]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add kinit/klist -i options to use client keytab
authorGreg Hudson <ghudson@mit.edu>
Mon, 16 Jul 2012 14:13:29 +0000 (10:13 -0400)
committerGreg Hudson <ghudson@mit.edu>
Mon, 16 Jul 2012 14:24:17 +0000 (10:24 -0400)
In combination with -k, -i will cause kinit or klist to use the
default client keytab instead of the default acceptor keytab.  This
gives an easy way to figure out what default client keytab name is in
use and to get credentials using it.

ticket: 7216 (new)

doc/rst_source/krb_users/user_commands/kinit.rst
doc/rst_source/krb_users/user_commands/klist.rst
src/clients/kinit/kinit.c
src/clients/klist/klist.c
src/tests/t_keytab.py

index 6143c95e47c7242d04a421d7de4d66ee634f1dd5..783bd7769928ff71e56b96b05af75e3e98bb7104 100644 (file)
@@ -118,14 +118,15 @@ OPTIONS
     expired ticket cannot be renewed, even if the ticket is still
     within its renewable life.
 
-**-k** [**-t** *keytab_file*]
+**-k** [**-i** | **-t** *keytab_file*]
     requests a ticket, obtained from a key in the local host's keytab.
     The location of the keytab may be specified with the **-t**
-    *keytab_file* option; otherwise the default keytab will be used.
-    By default, a host ticket for the local host is requested, but any
-    principal may be specified.  On a KDC, the special keytab location
-    ``KDB:`` can be used to indicate that kinit should open the KDC
-    database and look up the key directly.  This permits an
+    *keytab_file* option, or with the **-i** option to specify the use
+    of the default client keytab; otherwise the default keytab will be
+    used.  By default, a host ticket for the local host is requested,
+    but any principal may be specified.  On a KDC, the special keytab
+    location ``KDB:`` can be used to indicate that kinit should open
+    the KDC database and look up the key directly.  This permits an
     administrator to obtain tickets as any principal that supports
     authentication based on the key.
 
index 5a9a076f4065f6d52984e46b5653b38653ef98f1..0b867a867caedb6f24deb5bd90998b406ba52b1b 100644 (file)
@@ -77,6 +77,11 @@ OPTIONS
 **-k**
     List keys held in a keytab file.
 
+**-i**
+    In combination with **-k**, defaults to using the default client
+    keytab instead of the default acceptor keytab, if no name is
+    given.
+
 **-t**
     Display the time entry timestamps for each keytab entry in the
     keytab file.
index 256f165fe931bce24f738e64c55cd8f3324a6053..a315173b6089d0edebcd528cdd4b9f501f55d881 100644 (file)
@@ -120,6 +120,7 @@ struct k_opts
     char *armor_ccache;
 
     action_type action;
+    int use_client_keytab;
 
     int num_pa_opts;
     krb5_gic_opt_pa_data *pa_opts;
@@ -197,7 +198,7 @@ usage()
             "[-E" USAGE_LONG_ENTERPRISE "] "
             USAGE_BREAK
             "[-v] [-R] "
-            "[-k [-t keytab_file]] "
+            "[-k [-i|-t keytab_file]] "
             "[-c cachename] "
             USAGE_BREAK
             "[-S service_name] [-T ticket_armor_cache]"
@@ -223,6 +224,7 @@ usage()
     fprintf(stderr, _("\t-C canonicalize\n"));
     fprintf(stderr, _("\t-E client is enterprise principal name\n"));
     fprintf(stderr, _("\t-k use keytab\n"));
+    fprintf(stderr, _("\t-i use default client keytab (with -k)\n"));
     fprintf(stderr, _("\t-t filename of keytab to use\n"));
     fprintf(stderr, _("\t-c Kerberos 5 cache name\n"));
     fprintf(stderr, _("\t-S service\n"));
@@ -284,7 +286,7 @@ parse_options(argc, argv, opts)
     int errflg = 0;
     int i;
 
-    while ((i = GETOPT(argc, argv, "r:fpFPn54aAVl:s:c:kt:T:RS:vX:CE"))
+    while ((i = GETOPT(argc, argv, "r:fpFPn54aAVl:s:c:kit:T:RS:vX:CE"))
            != -1) {
         switch (i) {
         case 'V':
@@ -349,6 +351,9 @@ parse_options(argc, argv, opts)
         case 'k':
             opts->action = INIT_KT;
             break;
+        case 'i':
+            opts->use_client_keytab = 1;
+            break;
         case 't':
             if (opts->keytab_name)
             {
@@ -700,6 +705,12 @@ k5_kinit(opts, k5)
         }
         if (opts->verbose)
             fprintf(stderr, _("Using keytab: %s\n"), opts->keytab_name);
+    } else if (opts->action == INIT_KT && opts->use_client_keytab) {
+        code = krb5_kt_client_default(k5->ctx, &keytab);
+        if (code != 0) {
+            com_err(progname, code, _("resolving default client keytab"));
+            goto cleanup;
+        }
     }
 
     for (i = 0; i < opts->num_pa_opts; i++) {
index fefd895d18d8569258d6ba20b68d0252353505f2..3f633fd9063eb582b3fa45674a8c3e20fe1af971 100644 (file)
@@ -58,7 +58,7 @@ extern int optind;
 
 int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
 int show_etype = 0, show_addresses = 0, no_resolve = 0, print_version = 0;
-int show_adtype = 0, show_all = 0, list_all = 0;
+int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
 char *defname;
 char *progname;
 krb5_int32 now;
@@ -92,6 +92,7 @@ static void usage()
     fprintf(stderr, _("\t-c specifies credentials cache\n"));
     fprintf(stderr, _("\t-k specifies keytab\n"));
     fprintf(stderr, _("\t   (Default is credentials cache)\n"));
+    fprintf(stderr, _("\t-i uses default client keytab if no name given\n"));
     fprintf(stderr, _("\t-l lists credential caches in collection\n"));
     fprintf(stderr, _("\t-A shows content of all credential caches\n"));
     fprintf(stderr, _("\t-e shows the encryption type\n"));
@@ -125,7 +126,7 @@ main(argc, argv)
     name = NULL;
     mode = DEFAULT;
     /* V=version so v can be used for verbose later if desired.  */
-    while ((c = getopt(argc, argv, "dfetKsnack45lAV")) != -1) {
+    while ((c = getopt(argc, argv, "dfetKsnacki45lAV")) != -1) {
         switch (c) {
         case 'd':
             show_adtype = 1;
@@ -159,6 +160,9 @@ main(argc, argv)
             if (mode != DEFAULT) usage();
             mode = KEYTAB;
             break;
+        case 'i':
+            use_client_keytab = 1;
+            break;
         case '4':
             fprintf(stderr, _("Kerberos 4 is no longer supported\n"));
             exit(3);
@@ -255,7 +259,12 @@ void do_keytab(name)
     char *pname;
     int code;
 
-    if (name == NULL) {
+    if (name == NULL && use_client_keytab) {
+        if ((code = krb5_kt_client_default(kcontext, &kt))) {
+            com_err(progname, code, _("while getting default client keytab"));
+            exit(1);
+        }
+    } else if (name == NULL) {
         if ((code = krb5_kt_default(kcontext, &kt))) {
             com_err(progname, code, _("while getting default keytab"));
             exit(1);
index ef303f197571a8678c7950f767f05370deab2038..8d73636c8d038172ee5e7dfe0b79b51a68a01e4e 100644 (file)
@@ -18,6 +18,14 @@ output = realm.kinit(realm.user_princ, flags=['-k'], expected_code=1)
 if 'no suitable keys' not in output:
     fail('Expected error not seen in kinit output')
 
+# Test kinit and klist with client keytab defaults.
+realm.extract_keytab(realm.user_princ, realm.client_keytab);
+realm.kinit(realm.user_princ, flags=['-k', '-i'])
+realm.klist(realm.user_princ)
+out = realm.run_as_client([klist, '-k', '-i'])
+if realm.client_keytab not in out or realm.user_princ not in out:
+    fail('Expected output not seen from klist -k -i')
+
 # Test handling of kvno values beyond 255.
 princ = 'foo/bar@%s' % realm.realm
 realm.addprinc(princ)