]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
convert to cygnus kinit
authorMarc Horowitz <marc@mit.edu>
Sat, 22 Aug 1998 02:28:16 +0000 (02:28 +0000)
committerMarc Horowitz <marc@mit.edu>
Sat, 22 Aug 1998 02:28:16 +0000 (02:28 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/branches/marc-3des@10864 dc483132-0cff-0310-8789-dd5450dbe970

src/clients/kinit/kinit.c

index 6f7b840c98981c3e5cd572c288f5f875e015975e..ce1cdb52c28d5c2a176c82369a039eb3fdffab54 100644 (file)
  * Initialize a credentials cache.
  */
 
-#include "k5-int.h"
+#include <krb5.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef GETOPT_LONG
+#include "getopt.h"
+#else
+#include <unistd.h>
+#endif
 #include "com_err.h"
-#include "adm_proto.h"
 
-#include <stdio.h>
 #ifdef HAVE_PWD_H
 #include <pwd.h>
-#endif
 
-#define KRB5_DEFAULT_OPTIONS 0
-#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
-
-extern int optind;
-extern char *optarg;
+void get_name_from_passwd_file(program_name, kcontext, me)
+    char * program_name;
+    krb5_context kcontext;
+    krb5_principal * me;
+{
+    struct passwd *pw;
+    krb5_error_code code;
+    if (pw = getpwuid((int) getuid())) {
+       if ((code = krb5_parse_name(kcontext, pw->pw_name, me))) {
+           com_err (program_name, code, "when parsing name %s", pw->pw_name);
+           exit(1);
+       }
+    } else {
+       fprintf(stderr, "Unable to identify user from password file\n");
+       exit(1);
+    }
+}
+#else /* HAVE_PWD_H */
+void get_name_from_passwd_file(kcontext, me)
+    krb5_context kcontext;
+    krb5_principal * me;
+{
+    fprintf(stderr, "Unable to identify user\n");
+    exit(1);
+}
+#endif /* HAVE_PWD_H */
 
-krb5_data tgtname = {
-    0,
-    KRB5_TGS_NAME_SIZE,
-    KRB5_TGS_NAME
+#ifdef GETOPT_LONG
+/* if struct[2] == NULL, then long_getopt acts as if the short flag
+   struct[3] was specified.  If struct[2] != NULL, then struct[3] is
+   stored in *(struct[2]), the array index which was specified is
+   stored in *index, and long_getopt() returns 0. */
+
+struct option long_options[] = {
+    { "noforwardable", 0, NULL, 'f'+0200 },
+    { "noproxiable", 0, NULL, 'p'+0200 },
+    { "addresses", 0, NULL, 'A'+0200},
+    { "forwardable", 0, NULL, 'f' },
+    { "proxiable", 0, NULL, 'p' },
+    { "noaddresses", 0, NULL, 'A'},
+    { "version", 0, NULL, 0x01 },
+    { NULL, 0, NULL, 0 }
 };
-
-/* Internal prototypes */
-static krb5_error_code krb5_validate_tgt
-        KRB5_PROTOTYPE((krb5_context, krb5_ccache,
-                        krb5_principal, krb5_data *));
-static krb5_error_code krb5_renew_tgt
-        KRB5_PROTOTYPE((krb5_context, krb5_ccache,
-                        krb5_principal, krb5_data *));
-static krb5_error_code krb5_tgt_gen
-        KRB5_PROTOTYPE((krb5_context, krb5_ccache,
-                        krb5_principal, krb5_data *, int opt));
-
-/*
- * Try no preauthentication first; then try the encrypted timestamp
- */
-krb5_preauthtype * preauth = NULL;
-krb5_preauthtype preauth_list[2] = { 0, -1 };
+#endif
 
 int
 main(argc, argv)
@@ -68,114 +89,145 @@ main(argc, argv)
     char **argv;
 {
     krb5_context kcontext;
+    krb5_principal me = NULL;
+    krb5_deltat start_time = 0;
+    krb5_address **addresses = NULL;
+    krb5_get_init_creds_opt opts;
+    char *service_name = NULL;
+    krb5_keytab keytab = NULL;
+    char *cache_name;
     krb5_ccache ccache = NULL;
-    char *cache_name = NULL;           /* -f option */
-    char *keytab_name = NULL;          /* -t option */
-    char *service_name = NULL;         /* -s option */
-    krb5_deltat lifetime = KRB5_DEFAULT_LIFE;  /* -l option */
-    krb5_timestamp starttime = 0;
-    krb5_deltat rlife = 0;
-    int options = KRB5_DEFAULT_OPTIONS;
-    int option;
-    int errflg = 0;
-    krb5_error_code code;
-    krb5_principal me;
-    krb5_principal server;
+    enum { INIT_PW, INIT_KT, RENEW, VALIDATE} action;
+    int errflg = 0, idx, i;
     krb5_creds my_creds;
-    krb5_timestamp now;
-    krb5_address *null_addr = (krb5_address *)0;
-    krb5_address **addrs = (krb5_address **)0;
-    int use_keytab = 0;                        /* -k option */
-    krb5_keytab keytab = NULL;
-    struct passwd *pw = 0;
-    int pwsize;
-    char password[255], *client_name, prompt[1024];
+    krb5_error_code code;
 
-    code = krb5_init_context(&kcontext);
-    if (code) {
-           com_err(argv[0], code, "while initializing krb5");
-           exit(1);
-    }
+    /* Ensure we can be driven from a pipe */
+    if(!isatty(fileno(stdin)))
+        setvbuf(stdin, 0, _IONBF, 0);
+    if(!isatty(fileno(stdout)))
+        setvbuf(stdout, 0, _IONBF, 0);
+    if(!isatty(fileno(stderr)))
+        setvbuf(stderr, 0, _IONBF, 0);
 
-    if ((code = krb5_timeofday(kcontext, &now))) {
-       com_err(argv[0], code, "while getting time of day");
-       exit(1);
-    }
+    krb5_init_context(&kcontext);
+    krb5_init_ets(kcontext);
+
+    krb5_get_init_creds_opt_init(&opts);
+
+    action = INIT_PW;
 
     if (strrchr(argv[0], '/'))
        argv[0] = strrchr(argv[0], '/')+1;
 
-    while ((option = getopt(argc, argv, "r:Rfpl:s:c:kt:vS:")) != -1) {
-       switch (option) {
-       case 'r':
-           options |= KDC_OPT_RENEWABLE;
-           code = krb5_string_to_deltat(optarg, &rlife);
-           if (code != 0 || rlife == 0) {
-               fprintf(stderr, "Bad lifetime value %s\n", optarg);
-               errflg++;
+    while (
+#ifdef GETOPT_LONG
+          (i = getopt_long(argc, argv, "r:fpAl:s:c:kt:RS:v",
+                           long_options, &idx)) != EOF
+#else
+          (i = getopt(argc, argv, "r:fpAl:s:c:kt:RS:v")) != EOF
+#endif
+          ) {
+       switch (i) {
+#ifdef GETOPT_LONG
+       case 1: /* Print the version */
+           printf("%s\n", krb5_version);
+           exit(0);
+#endif
+        case 'l':
+           {
+               krb5_deltat lifetime;
+               code = krb5_string_to_deltat(optarg, &lifetime);
+               if (code != 0 || lifetime == 0) {
+                   fprintf(stderr, "Bad lifetime value %s\n", optarg);
+                   errflg++;
+               }
+               krb5_get_init_creds_opt_set_tkt_life(&opts, lifetime);
            }
            break;
-       case 'R':
-           /* renew the ticket */
-           options |= KDC_OPT_RENEW;
+       case 'r':
+           {
+               krb5_deltat rlife;
+
+               code = krb5_string_to_deltat(optarg, &rlife);
+               if (code != 0 || rlife == 0) {
+                   fprintf(stderr, "Bad lifetime value %s\n", optarg);
+                   errflg++;
+               }
+               krb5_get_init_creds_opt_set_renew_life(&opts, rlife);
+           }
            break;
-       case 'v':
-           /* validate the ticket */
-           options |= KDC_OPT_VALIDATE;
+       case 'f':
+           krb5_get_init_creds_opt_set_forwardable(&opts, 1);
            break;
-        case 'S':
-           service_name = optarg;
+#ifdef GETOPT_LONG
+       case 'f'+0200:
+           krb5_get_init_creds_opt_set_forwardable(&opts, 0);
            break;
+#endif
        case 'p':
-           options |= KDC_OPT_PROXIABLE;
+           krb5_get_init_creds_opt_set_proxiable(&opts, 1);
            break;
-       case 'f':
-           options |= KDC_OPT_FORWARDABLE;
+#ifdef GETOPT_LONG
+       case 'p'+0200:
+           krb5_get_init_creds_opt_set_proxiable(&opts, 0);
            break;
-#ifndef NO_KEYTAB
-       case 'k':
-           use_keytab = 1;
+#endif
+       case 'A':
+           krb5_get_init_creds_opt_set_address_list(&opts, NULL);
            break;
-       case 't':
-           if (keytab == NULL) {
-                keytab_name = optarg;
+#ifdef GETOPT_LONG
+       case 'A'+0200:
+           krb5_os_localaddr(kcontext, &addresses);
+           krb5_get_init_creds_opt_set_address_list(&opts, addresses);
+           break;
+#endif
+               case 's':
+           code = krb5_string_to_deltat(optarg, &start_time);
+           if (code != 0 || start_time == 0) {
+               krb5_timestamp abs_starttime;
+               krb5_timestamp now;
+
+               code = krb5_string_to_timestamp(optarg, &abs_starttime);
+               if (code != 0 || abs_starttime == 0) {
+                   fprintf(stderr, "Bad start time value %s\n", optarg);
+                   errflg++;
+               } else {
+                   if ((code = krb5_timeofday(kcontext, &now))) {
+                       com_err(argv[0], code,
+                               "while getting time of day");
+                       exit(1);
+                   }
 
-                code = krb5_kt_resolve(kcontext, keytab_name, &keytab);
+                   start_time = abs_starttime - now;
+               }
+           }
+           break;
+        case 'S':
+           service_name = optarg;
+           break;
+        case 'k':
+           action = INIT_KT;
+           break;
+        case 't':
+           if (keytab == NULL) {
+                code = krb5_kt_resolve(kcontext, optarg, &keytab);
                 if (code != 0) {
-                     com_err(argv[0], code, "resolving keytab %s",
-                             keytab_name);
-                errflg++;
+                     com_err(argv[0], code, "resolving keytab %s", optarg);
+                     errflg++;
                 }
            } else {
                 fprintf(stderr, "Only one -t option allowed.\n");
                 errflg++;
            }
            break;
-#endif
-       case 'l':
-           code = krb5_string_to_deltat(optarg, &lifetime);
-           if (code != 0 || lifetime == 0) {
-               fprintf(stderr, "Bad lifetime value %s\n", optarg);
-               errflg++;
-           }
+       case 'R':
+           action = RENEW;
            break;
-       case 's':
-           code = krb5_string_to_timestamp(optarg, &starttime);
-           if (code != 0 || starttime == 0) {
-             krb5_deltat ktmp;
-             code = krb5_string_to_deltat(optarg, &ktmp);
-             if (code == 0 && ktmp != 0) {
-               starttime = now + ktmp;
-               options |= KDC_OPT_POSTDATED;
-             } else {
-               fprintf(stderr, "Bad postdate start time value %s\n", optarg);
-               errflg++;
-             }
-           } else {
-             options |= KDC_OPT_POSTDATED;
-           }
+       case 'v':
+           action = VALIDATE;
            break;
-       case 'c':
+               case 'c':
            if (ccache == NULL) {
                cache_name = optarg;
                
@@ -190,7 +242,6 @@ main(argc, argv)
                errflg++;
            }
            break;
-       case '?':
        default:
            errflg++;
            break;
@@ -204,7 +255,11 @@ main(argc, argv)
     }
 
     if (errflg) {
-       fprintf(stderr, "Usage: %s [-r time] [-R] [-s time] [-v] [-puf] [-l lifetime] [-c cachename] [-k] [-t keytab] [-S target_service] [principal]\n", argv[0]);
+#ifdef GETOPT_LONG
+       fprintf(stderr, "Usage: %s [--version] [-l lifetime] [-r renewable_life] [-f | --forwardable | --noforwardable] [-p | --proxiable | --noproxiable] [-A | --noaddresses | --addresses] [-s start_time] [-S target_service] [-k [-t keytab_file]] [-R] [-v] [-c cachename] [principal]\n", argv[0]);
+#else
+       fprintf(stderr, "Usage: %s [-l lifetime] [-r renewable_life] [-f] [-p] [-A] [-s start_time] [-S target_service] [-k [-t keytab_file]] [-R] [-v] [-c cachename] [principal]\n", argv[0]);
+#endif
        exit(2);
     }
 
@@ -215,147 +270,51 @@ main(argc, argv)
         }
     }
 
-    if (optind != argc-1) {       /* No principal name specified */
-#ifndef NO_KEYTAB
-        if (use_keytab) {
-             /* Use the default host/service name */
-             code = krb5_sname_to_principal(kcontext, NULL, NULL,
-                                            KRB5_NT_SRV_HST, &me);
-             if (code) {
-                  com_err(argv[0], code,
-                          "when creating default server principal name");
-                  exit(1);
-             }
-        } else
-#endif
-        {
-             /* Get default principal from cache if one exists */
-             code = krb5_cc_get_principal(kcontext, ccache, &me);
-             if (code) {
-#ifdef HAVE_PWD_H
-                  /* Else search passwd file for client */
-                  pw = getpwuid((int) getuid());
-                  if (pw) {
-                       if ((code = krb5_parse_name(kcontext,pw->pw_name,
-                                                   &me))) {
-                            com_err (argv[0], code, "when parsing name %s",
-                                     pw->pw_name);
-                            exit(1);
-                       }
-                  } else {
-                       fprintf(stderr, 
-                       "Unable to identify user from password file\n");
-                       exit(1);
-                  }
-#else /* HAVE_PWD_H */
-                  fprintf(stderr, "Unable to identify user\n");
-                  exit(1);
-#endif /* HAVE_PWD_H */
-             }
-        }
-    } /* Use specified name */  
-    else if ((code = krb5_parse_name (kcontext, argv[optind], &me))) {
-        com_err (argv[0], code, "when parsing name %s",argv[optind]);
-        exit(1);
-    }
-    
-    if ((code = krb5_unparse_name(kcontext, me, &client_name))) {
-       com_err (argv[0], code, "when unparsing name");
-       exit(1);
-    }
-
-    memset((char *)&my_creds, 0, sizeof(my_creds));
-    
-    my_creds.client = me;
-
-    if (service_name == NULL) {
-        if((code = krb5_build_principal_ext(kcontext, &server,
-                                            krb5_princ_realm(kcontext, me)->length,
-                                            krb5_princ_realm(kcontext, me)->data,
-                                            tgtname.length, tgtname.data,
-                                            krb5_princ_realm(kcontext, me)->length,
-                                            krb5_princ_realm(kcontext, me)->data,
-                                            0))) {
-             com_err(argv[0], code, "while building server name");
-             exit(1);
-        }
-    } else {
-        if ((code = krb5_parse_name(kcontext, service_name, &server))) {
-             com_err(argv[0], code, "while parsing service name %s",
-                     service_name);
-             exit(1);
-        }
-    }
-       
-    my_creds.server = server;
-
-    if (options & KDC_OPT_POSTDATED) {
-      my_creds.times.starttime = starttime;
-      my_creds.times.endtime = starttime + lifetime;
+    if (optind == argc-1) {
+       /* Use specified name */
+       if ((code = krb5_parse_name (kcontext, argv[optind], &me))) {
+           com_err (argv[0], code, "when parsing name %s",argv[optind]);
+           exit(1);
+       }
     } else {
-      my_creds.times.starttime = 0;    /* start timer when request
-                                          gets to KDC */
-      my_creds.times.endtime = now + lifetime;
-    }
-    if (options & KDC_OPT_RENEWABLE) {
-       my_creds.times.renew_till = now + rlife;
-    } else
-       my_creds.times.renew_till = 0;
-
-    if (options & KDC_OPT_VALIDATE) {
-        /* don't use get_in_tkt, just use mk_req... */
-        krb5_data outbuf;
-
-        code = krb5_validate_tgt(kcontext, ccache, server, &outbuf);
-       if (code) {
-         com_err (argv[0], code, "validating tgt");
-         exit(1);
+       /* No principal name specified */
+       if (action == INIT_KT) {
+           /* Use the default host/service name */
+           if (code = krb5_sname_to_principal(kcontext, NULL, NULL,
+                                              KRB5_NT_SRV_HST, &me)) {
+               com_err(argv[0], code,
+                       "when creating default server principal name");
+               exit(1);
+           }
+       } else {
+           /* Get default principal from cache if one exists */
+           if (code = krb5_cc_get_principal(kcontext, ccache, &me))
+               get_name_from_passwd_file(argv[0], kcontext, &me);
        }
-       /* should be done... */
-       exit(0);
     }
-
-    if (options & KDC_OPT_RENEW) {
-        /* don't use get_in_tkt, just use mk_req... */
-        krb5_data outbuf;
-
-        code = krb5_renew_tgt(kcontext, ccache, server, &outbuf);
-       if (code) {
-         com_err (argv[0], code, "renewing tgt");
-         exit(1);
-       }
-       /* should be done... */
-       exit(0);
+    
+    switch (action) {
+    case INIT_PW:
+       code = krb5_get_init_creds_password(kcontext, &my_creds, me, NULL,
+                                           krb5_prompter_posix, NULL,
+                                           start_time, service_name,
+                                           &opts);
+       break;
+    case INIT_KT:
+       code = krb5_get_init_creds_keytab(kcontext, &my_creds, me, keytab,
+                                           start_time, service_name,
+                                           &opts);
+       break;
+    case VALIDATE:
+       code = krb5_get_validated_creds(kcontext, &my_creds, me, ccache,
+                                       service_name);
+       break;
+    case RENEW:
+       code = krb5_get_renewed_creds(kcontext, &my_creds, me, ccache,
+                                     service_name);
+       break;
     }
-#ifndef NO_KEYTAB
-    if (!use_keytab)
-#endif
-    {
-        (void) sprintf(prompt, "Password for %.*s: ",
-                       sizeof(prompt)-32, (char *) client_name);
-
-        pwsize = sizeof(password);
 
-        code = krb5_read_password(kcontext, prompt, 0, password, &pwsize);
-        if (code || pwsize == 0) {
-             fprintf(stderr, "Error while reading password for '%s'\n",
-                     client_name);
-             memset(password, 0, sizeof(password));
-             exit(1);
-        }
-
-        code = krb5_get_in_tkt_with_password(kcontext, options, addrs,
-                                             NULL, preauth, password, 0,
-                                             &my_creds, 0);
-        memset(password, 0, sizeof(password));
-#ifndef NO_KEYTAB
-    } else {
-        code = krb5_get_in_tkt_with_keytab(kcontext, options, addrs,
-                                           NULL, preauth, keytab, 0,
-                                           &my_creds, 0);
-#endif
-    }
-    
     if (code) {
        if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
            fprintf (stderr, "%s: Password incorrect\n", argv[0]);
@@ -364,86 +323,27 @@ main(argc, argv)
        exit(1);
     }
 
-    code = krb5_cc_initialize (kcontext, ccache, me);
-    if (code != 0) {
+    if (code = krb5_cc_initialize(kcontext, ccache, me)) {
        com_err (argv[0], code, "when initializing cache %s",
                 cache_name?cache_name:"");
        exit(1);
     }
 
-    code = krb5_cc_store_cred(kcontext, ccache, &my_creds);
-    if (code) {
+    if (code = krb5_cc_store_cred(kcontext, ccache, &my_creds)) {
        com_err (argv[0], code, "while storing credentials");
        exit(1);
     }
 
-    /* my_creds is pointing at server */
-    krb5_free_principal(kcontext, server);
+    if (me)
+       krb5_free_principal(kcontext, me);
+    if (keytab)
+       krb5_kt_close(kcontext, keytab);
+    if (ccache)
+       krb5_cc_close(kcontext, ccache);
+    if (addresses)
+       krb5_free_addresses(kcontext, addresses);
 
     krb5_free_context(kcontext);
-
+    
     exit(0);
 }
-
-#define VALIDATE 0
-#define RENEW 1
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code krb5_validate_tgt(context, ccache, server, outbuf)
-     krb5_context context;
-     krb5_ccache ccache;
-     krb5_principal      server; /* tgtname */
-     krb5_data *outbuf;
-{
-       return krb5_tgt_gen(context, ccache, server, outbuf, VALIDATE);
-}
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code krb5_renew_tgt(context, ccache, server, outbuf)
-     krb5_context context;
-     krb5_ccache ccache;
-     krb5_principal      server; /* tgtname */
-     krb5_data *outbuf;
-{
-       return krb5_tgt_gen(context, ccache, server, outbuf, RENEW);
-}
-
-
-/* stripped down version of krb5_mk_req */
-static krb5_error_code krb5_tgt_gen(context, ccache, server, outbuf, opt)
-     krb5_context context;
-     krb5_ccache ccache;
-     krb5_principal      server; /* tgtname */
-     krb5_data *outbuf;
-     int opt;
-{
-    krb5_error_code      retval;
-    krb5_creds                 * credsp;
-    krb5_creds                   creds;
-
-    /* obtain ticket & session key */
-    memset((char *)&creds, 0, sizeof(creds));
-    if ((retval = krb5_copy_principal(context, server, &creds.server)))
-       goto cleanup;
-
-    if ((retval = krb5_cc_get_principal(context, ccache, &creds.client)))
-       goto cleanup_creds;
-
-    if(opt == VALIDATE) {
-           if ((retval = krb5_get_credentials_validate(context, 0,
-                                                       ccache, &creds, &credsp)))
-                   goto cleanup_creds;
-    } else {
-           if ((retval = krb5_get_credentials_renew(context, 0,
-                                                       ccache, &creds, &credsp)))
-                   goto cleanup_creds;
-    }
-
-    /* we don't actually need to do the mk_req, just get the creds. */
-cleanup_creds:
-    krb5_free_cred_contents(context, &creds);
-
-cleanup:
-
-    return retval;
-}