krb5 commit: Add kinit/klist -i options to use client keytab

Greg Hudson ghudson at MIT.EDU
Mon Jul 16 10:24:44 EDT 2012


https://github.com/krb5/krb5/commit/194e0433f07e244aab59edcb22ea0c6e359f9f0d
commit 194e0433f07e244aab59edcb22ea0c6e359f9f0d
Author: Greg Hudson <ghudson at mit.edu>
Date:   Mon Jul 16 10:13:29 2012 -0400

    Add kinit/klist -i options to use client keytab
    
    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 |   13 +++++++------
 doc/rst_source/krb_users/user_commands/klist.rst |    5 +++++
 src/clients/kinit/kinit.c                        |   15 +++++++++++++--
 src/clients/klist/klist.c                        |   15 ++++++++++++---
 src/tests/t_keytab.py                            |    8 ++++++++
 5 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/doc/rst_source/krb_users/user_commands/kinit.rst b/doc/rst_source/krb_users/user_commands/kinit.rst
index 6143c95..783bd77 100644
--- a/doc/rst_source/krb_users/user_commands/kinit.rst
+++ b/doc/rst_source/krb_users/user_commands/kinit.rst
@@ -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.
 
diff --git a/doc/rst_source/krb_users/user_commands/klist.rst b/doc/rst_source/krb_users/user_commands/klist.rst
index 5a9a076..0b867a8 100644
--- a/doc/rst_source/krb_users/user_commands/klist.rst
+++ b/doc/rst_source/krb_users/user_commands/klist.rst
@@ -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.
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
index 256f165..a315173 100644
--- a/src/clients/kinit/kinit.c
+++ b/src/clients/kinit/kinit.c
@@ -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++) {
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index fefd895..3f633fd 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -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);
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py
index ef303f1..8d73636 100644
--- a/src/tests/t_keytab.py
+++ b/src/tests/t_keytab.py
@@ -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)


More information about the cvs-krb5 mailing list