Integrated patch from OpenVision which allows klist to list keytabs as
authorTheodore Tso <tytso@mit.edu>
Thu, 8 Jun 1995 21:47:51 +0000 (21:47 +0000)
committerTheodore Tso <tytso@mit.edu>
Thu, 8 Jun 1995 21:47:51 +0000 (21:47 +0000)
well as ccache's.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5984 dc483132-0cff-0310-8789-dd5450dbe970

src/clients/klist/ChangeLog
src/clients/klist/klist.c

index 924bbd32f21deb231b03f648f2928d8053d475dd..a5c82ea3b46930f70d91ed8ee1515cfe91a6cf6d 100644 (file)
@@ -1,3 +1,8 @@
+Thu Jun  8 17:46:51 1995    <tytso@rsx-11.mit.edu>
+
+       * klist.c: Integrated patch from OpenVision which allows klist to
+               list keytabs as well as ccache's.
+
 Thu May 11 07:31:42 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
 
        * klist.c (main): Update usage message to include -e and -f.
index ecd398d88024f2e7e30c37d19b559e5fbeae2fb8..4030ca94b0a39bb71abf474b98f193d43d1ee9a9 100644 (file)
  * or implied warranty.
  * 
  *
- * List out the contents of your credential cache.
+ * List out the contents of your credential cache or keytab.
  */
 
 #include "krb5.h"
 #include "com_err.h"
+#include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <time.h>
 
 extern int optind;
 extern char *optarg;
+int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
 int show_etype = 0;
-int show_flags = 0;
 char *defname;
-time_t now;
+char *progname;
+krb5_int32 now;
 
-void
-show_credential 
-       PROTOTYPE((char *,
-                  krb5_context,
-                  krb5_creds *));
+krb5_context kcontext;
+
+void show_credential PROTOTYPE((char *,
+                               krb5_context,
+                               krb5_creds *));
+       
+void do_ccache PROTOTYPE((char *));
+void do_keytab PROTOTYPE((char *));
+void printtime PROTOTYPE((time_t));
+       
+#define DEFAULT 0
+#define CCACHE 1
+#define KEYTAB 2
+
+void usage()
+{
+     fprintf(stderr, "Usage: %s [[-c] [-f] [-s]] [-k [-t] [-K]] [name]\n",
+            progname); 
+     fprintf(stderr, "\t-c specifies credentials cache, -k specifies keytab");
+     fprintf(stderr, ", -c is default\n");
+     fprintf(stderr, "\toptions for credential caches:\n");
+     fprintf(stderr, "\t\t-f shows credentials flags\n");
+     fprintf(stderr, "\t\t-s sets exit status based on valid tgt existence\n");
+     fprintf(stderr, "\toptions for keytabs:\n");
+     fprintf(stderr, "\t\t-t shows keytab entry timestamps\n");
+     fprintf(stderr, "\t\t-K shows keytab entry DES keys\n");
+     exit(1);
+}
 
 void
 main(argc, argv)
     int argc;
     char **argv;
 {
-    int c;
-    int errflg = 0;
     int code;
-    krb5_ccache cache = NULL;
-    krb5_cc_cursor cur;
-    krb5_creds creds;
-    char *cache_name;
-    krb5_principal princ;
-    krb5_flags flags;
-    krb5_context kcontext;
+    char *name;
+    int mode;
 
     krb5_init_context(&kcontext);
     krb5_init_ets(kcontext);
 
-    time(&now);
-    
-    if (strrchr(argv[0], '/'))
-       argv[0] = strrchr(argv[0], '/')+1;
+    progname = (strrchr(*argv, '/') ? strrchr(*argv, '/')+1 : argv[0]);
 
-    while ((c = getopt(argc, argv, "efc:")) != EOF) {
-       switch (c) {
+    argv++;
+    name = NULL;
+    mode = DEFAULT;
+    while (*argv) {
+       if ((*argv)[0] != '-') {
+           if (name) usage();
+           name = *argv;
+       } else switch ((*argv)[1]) {
        case 'e':
-            show_etype = 1;
-            break;
+           show_etype = 1;
+           break;
        case 'f':
-            show_flags = 1;
-            break;
+           show_flags = 1;
+           break;
+       case 't':
+           show_time = 1;
+           break;
+       case 'K':
+           show_keys = 1;
+           break;
+       case 's':
+           status_only = 1;
+           break;
        case 'c':
-           if (cache == NULL) {
-               cache_name = optarg;
-               
-               code = krb5_cc_resolve (kcontext, cache_name, &cache);
-               if (code != 0) {
-                   com_err(argv[0], code, "while resolving %s", cache_name);
-                   errflg++;
-               }
-           } else {
-               fprintf(stderr, "Only one -c option allowed\n");
-               errflg++;
-           }
+           if (mode != DEFAULT) usage();
+           mode = CCACHE;
+           break;
+       case 'k':
+           if (mode != DEFAULT) usage();
+           mode = KEYTAB;
            break;
-       case '?':
        default:
-           errflg++;
+           usage();
            break;
        }
+       argv++;
     }
 
-    if (optind != argc)
-       errflg++;
-    
-    if (errflg) {
-       fprintf(stderr, "Usage: %s [ -c cache ] [-e] [-f]\n", argv[0]);
-       exit(2);
+    if (mode == DEFAULT || mode == CCACHE) {
+        if (show_time || show_keys)
+             usage();
+    } else {
+        if (show_flags || status_only)
+             usage();
+    }
+
+    if ((code = krb5_timeofday(kcontext, &now))) {
+        if (!status_only)
+             com_err(progname, code, "while getting time of day.");
+        exit(1);
     }
-    if (cache == NULL) {
-       if (code = krb5_cc_default(kcontext, &cache)) {
-           com_err(argv[0], code, "while getting default ccache");
+
+    if (mode == DEFAULT || mode == CCACHE)
+        do_ccache(name);
+    else
+        do_keytab(name);
+}    
+
+void do_keytab(name)
+   char *name;
+{
+     krb5_keytab kt;
+     krb5_keytab_entry entry;
+     krb5_kt_cursor cursor;
+     char buf[BUFSIZ]; /* hopefully large enough for any type */
+     char *pname;
+     int code;
+     
+     if (name == NULL) {
+         if ((code = krb5_kt_default(kcontext, &kt))) {
+              com_err(progname, code, "while getting default keytab");
+              exit(1);
+         }
+     } else {
+         if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
+              com_err(progname, code, "while resolving keytab %s",
+                      name);
+              exit(1);
+         }
+     }
+
+     if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
+         com_err(progname, code, "while getting keytab name");
+         exit(1);
+     }
+
+     printf("Keytab name: %s\n", buf);
+     
+     if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
+         com_err(progname, code, "while starting keytab scan");
+         exit(1);
+     }
+
+     if (show_time) {
+         printf("KVNO Timestamp          Principal\n");
+         printf("---- ------------------ -------------------------------------------------------\n");
+     } else {
+         printf("KVNO Principal\n");
+         printf("---- --------------------------------------------------------------------------\n");
+     }
+     
+     while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
+         if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
+              com_err(progname, code, "while unparsing principal name");
+              exit(1);
+         }
+         printf("%4d ", entry.vno);
+         if (show_time) {
+              printtime(entry.timestamp);
+              printf(" ");
+         }
+         printf("%s", pname);
+         if (show_keys) {
+              printf(" (0x");
+              {
+                   int i;
+                   for (i = 0; i < entry.key.length; i++)
+                        printf("%02x", entry.key.contents[i]);
+              }
+              printf(")");
+         }
+         printf("\n");
+         free(pname);
+     }
+     if (code && code != KRB5_KT_END) {
+         com_err(progname, code, "while scanning keytab");
+         exit(1);
+     }
+     if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
+         com_err(progname, code, "while ending keytab scan");
+         exit(1);
+     }
+     exit(0);
+}
+void do_ccache(name)
+   char *name;
+{
+    krb5_ccache cache = NULL;
+    krb5_cc_cursor cur;
+    krb5_creds creds;
+    krb5_principal princ;
+    krb5_flags flags;
+    krb5_error_code code;
+    int        exit_status = 0;
+           
+    if (status_only)
+       /* exit_status is set back to 0 if a valid tgt is found */
+       exit_status = 1;
+
+    if (name == NULL) {
+       if ((code = krb5_cc_default(kcontext, &cache))) {
+           if (!status_only)
+               com_err(progname, code, "while getting default ccache");
+           exit(1);
+           }
+    } else {
+       if ((code = krb5_cc_resolve(kcontext, name, &cache))) {
+           if (!status_only)
+               com_err(progname, code, "while resolving ccache %s",
+                       name);
            exit(1);
        }
     }
-
     flags = 0;                         /* turns off OPENCLOSE mode */
-    if (code = krb5_cc_set_flags(kcontext, cache, flags)) {
+    if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
        if (code == ENOENT) {
-           com_err(argv[0], code, "(ticket cache %s)",
-                   krb5_cc_get_name(kcontext, cache));
-       } else
-           com_err(argv[0], code,
-                   "while setting cache flags (ticket cache %s)",
-                   krb5_cc_get_name(kcontext, cache));
+           if (!status_only)
+               com_err(progname, code, "(ticket cache %s)",
+                       krb5_cc_get_name(kcontext, cache));
+       } else {
+           if (!status_only)
+               com_err(progname, code,
+                       "while setting cache flags (ticket cache %s)",
+                       krb5_cc_get_name(kcontext, cache));
+       }
        exit(1);
     }
-    if (code = krb5_cc_get_principal(kcontext, cache, &princ)) {
-       com_err(argv[0], code, "while retrieving principal name");
+    if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
+       if (!status_only)
+           com_err(progname, code, "while retrieving principal name");
        exit(1);
     }
-    if (code = krb5_unparse_name(kcontext, princ, &defname)) {
-       com_err(argv[0], code, "while unparsing principal name");
+    if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
+       if (!status_only)
+           com_err(progname, code, "while unparsing principal name");
        exit(1);
     }
-    printf("Ticket cache: %s\nDefault principal: %s\n\n",
-           krb5_cc_get_name(kcontext, cache), defname);
-    if (code = krb5_cc_start_seq_get(kcontext, cache, &cur)) {
-       com_err(argv[0], code, "while starting to retrieve tickets");
+    if (!status_only) {
+       printf("Ticket cache: %s\nDefault principal: %s\n\n",
+              krb5_cc_get_name(kcontext, cache), defname);
+       fputs("  Valid starting       Expires          Service principal\n",
+             stdout);
+    }
+    if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
+       if (!status_only)
+           com_err(progname, code, "while starting to retrieve tickets");
        exit(1);
     }
-    fputs("  Valid starting       Expires          Service principal\n",
-         stdout);
     while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
-       show_credential(argv[0], kcontext, &creds);
+       if (status_only) {
+           if (exit_status && creds.server->length == 2 &&
+               strcmp(creds.server->realm.data, princ->realm.data) == 0 &&
+               strcmp((char *)creds.server->data[0].data, "krbtgt") == 0 &&
+               strcmp((char *)creds.server->data[1].data,
+                      princ->realm.data) == 0 && 
+               creds.times.endtime > now)
+               exit_status = 0;
+       } else {
+           show_credential(progname, kcontext, &creds);
+       }
        krb5_free_cred_contents(kcontext, &creds);
     }
     if (code == KRB5_CC_END) {
-       if (code = krb5_cc_end_seq_get(kcontext, cache, &cur)) {
-           com_err(argv[0], code, "while finishing ticket retrieval");
+       if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
+           if (!status_only)
+               com_err(progname, code, "while finishing ticket retrieval");
            exit(1);
        }
        flags = KRB5_TC_OPENCLOSE;      /* turns on OPENCLOSE mode */
-       if (code = krb5_cc_set_flags(kcontext, cache, flags)) {
-           com_err(argv[0], code, "while closing ccache");
+       if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
+           if (!status_only)
+               com_err(progname, code, "while closing ccache");
            exit(1);
        }
-       exit(0);
+       exit(exit_status);
     } else {
-       com_err(argv[0], code, "while retrieving a ticket");
+       if (!status_only)
+           com_err(progname, code, "while retrieving a ticket");
        exit(1);
     }  
 }
@@ -263,6 +421,7 @@ show_credential(progname, kcontext, cred)
                fputs(", ",stdout);
        fputs("renew until ", stdout);
         printtime(cred->times.renew_till);
+       first = 0;
     }
 
     if (show_etype) {
@@ -295,7 +454,9 @@ show_credential(progname, kcontext, cred)
         }
     }
 
-    putchar('\n');
+    /* if any additional info was printed, first is zero */
+    if (!first)
+       putchar('\n');
     free(name);
     free(sname);
 }