[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: kerberos support in ssh/lsh
nisse@lysator.liu.se (Niels Möller) writes:
> I'm quite new to this list and to kerberos, and I would need some
> advice.
[...]
> 2. fork() off an extra process, which duplicates most of the work done
> by kinit.
I ended up with the short program below, based losely on Heimdal's
implementation of su. Am I on the right track? What are the chances
that it will work also with MIT kerberos, not just heimdal?
/Niels
: /* lsh-krb-checkpw.c
: * [ copyright notice skipped ] */
:
: #include "lsh_types.h"
:
: #include <assert.h>
: #include <stdlib.h>
: #include <stdio.h>
:
: #include <krb5.h>
:
: static void usage(void) NORETURN;
: static void die(char *msg) NORETURN;
:
: /* NOTE: It is essential that this program never ever exits successfully unless
: * the the user was accepted by kerberos. */
: static void
: usage(void)
: {
: printf("Usage: lsh-krb-checkpw user < password\n");
: exit(EXIT_FAILURE);
: }
:
: static void
: die(char *msg)
: {
: fprintf(stderr, "lsh-krb-checkpw: %s\n", msg);
: exit(EXIT_FAILURE);
: }
:
: #define PW_MAX_SIZE 40
:
: static char *
: read_pw(FILE *f)
: {
: /* An extra byte for the terminating NUL. */
: char *buf = malloc(PW_MAX_SIZE+1);
: size_t length;
:
: if (!buf)
: return NULL;
:
: length = fread(buf, 1, PW_MAX_SIZE, f);
:
: if (!length || !feof(f))
: {
: free(buf);
: return NULL;
: }
:
: assert(length <= PW_MAX_SIZE);
: buf[length] = '\0';
:
: return buf;
: }
:
: int
: main(int argc, char **argv)
: {
: krb5_context context;
: krb5_ccache ccache;
: krb5_principal p;
: char *name;
: char *pw;
:
: if (argc != 2)
: usage();
:
: name = argv[1];
: pw = read_pw(stdin);
:
: if (!pw)
: die("No proper password provided.");
:
: if (!strcmp(name, "root"))
: /* In this case, heimdal's su.c creates a principal for the
: * current uid, but I don't quite understand why. */
: die("Won't log in root.");
:
: if (krb5_init_context (&context))
: die("krb5_init_context failed.");
:
: if (krb5_make_principal(context, &p, NULL, name, NULL))
: die("krb5_init_context failed.");
:
: if (!krb5_kuserok(context, p, name))
: die("krb5_kuserok doesn't know the user.");
:
: if (krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache))
: die("krb5_cc_gen_new failed.");
:
: if (krb5_verify_user_lrealm(context, p, ccache, pw, TRUE, NULL))
: die("krb5_verify_user_lrealm failed.");
:
: /* Authentication successful. */
:
: /* TODO: Keep the credential cache in some way. Perhaps write it to
: * disk, and, write the file name used to stdout. */
:
: return EXIT_SUCCESS;
: }