xref: /titanic_51/usr/src/cmd/krb5/klist/klist.c (revision a49a392f179e40c74ea8903bf2793b2aa49efdf1)
17c478bd9Sstevel@tonic-gate /*
2*a49a392fSps57422  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * clients/klist/klist.c
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * Copyright 1990 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate  * All Rights Reserved.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate  *
187c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
307c478bd9Sstevel@tonic-gate  * or implied warranty.
317c478bd9Sstevel@tonic-gate  *
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * List out the contents of your credential cache or keytab.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <k5-int.h>
377c478bd9Sstevel@tonic-gate #include "com_err.h"
387c478bd9Sstevel@tonic-gate #include <krb5.h>
397c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
407c478bd9Sstevel@tonic-gate #include <kerberosIV/krb.h>
417c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include <stdlib.h>
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <stdio.h>
467c478bd9Sstevel@tonic-gate #include <time.h>
477c478bd9Sstevel@tonic-gate #include <libintl.h>
487c478bd9Sstevel@tonic-gate #include <locale.h>
497c478bd9Sstevel@tonic-gate #include <netinet/in.h>
5056a424ccSmp153739 #if defined(HAVE_ARPA_INET_H)
517c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
5256a424ccSmp153739 #endif
537c478bd9Sstevel@tonic-gate #include <inet/ip.h>
547c478bd9Sstevel@tonic-gate #include <inet/ip6.h>
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #ifndef _WIN32
577c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
587c478bd9Sstevel@tonic-gate #else
597c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
607c478bd9Sstevel@tonic-gate #endif /* _WIN32 */
617c478bd9Sstevel@tonic-gate 
6256a424ccSmp153739 #ifndef _WIN32
637c478bd9Sstevel@tonic-gate #include <sys/socket.h>
647c478bd9Sstevel@tonic-gate #include <netdb.h>
6556a424ccSmp153739 #endif
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate extern int optind;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
707c478bd9Sstevel@tonic-gate int show_etype = 0, show_addresses = 0, no_resolve = 0;
717c478bd9Sstevel@tonic-gate char *defname;
727c478bd9Sstevel@tonic-gate char *progname;
737c478bd9Sstevel@tonic-gate krb5_int32 now;
747c478bd9Sstevel@tonic-gate size_t timestamp_width;
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate krb5_context kcontext;
777c478bd9Sstevel@tonic-gate 
78505d05c7Sgtb char * etype_string (krb5_enctype );
7956a424ccSmp153739 void show_credential (krb5_creds *);
807c478bd9Sstevel@tonic-gate 
81505d05c7Sgtb void do_ccache (char *);
82505d05c7Sgtb void do_keytab (char *);
83505d05c7Sgtb void printtime (time_t);
84505d05c7Sgtb void one_addr (krb5_address *);
8556a424ccSmp153739 void fillit (FILE *, unsigned int, int);
867c478bd9Sstevel@tonic-gate void show_addr(krb5_address *a);
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
89505d05c7Sgtb void do_v4_ccache (char *);
907c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate #define DEFAULT 0
937c478bd9Sstevel@tonic-gate #define CCACHE 1
947c478bd9Sstevel@tonic-gate #define KEYTAB 2
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * The reason we start out with got_k4 and got_k5 as zero (false) is
987c478bd9Sstevel@tonic-gate  * so that we can easily add dynamic loading support for determining
997c478bd9Sstevel@tonic-gate  * whether Kerberos 4 and Keberos 5 libraries are available
1007c478bd9Sstevel@tonic-gate  */
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate static int got_k5 = 0;
1037c478bd9Sstevel@tonic-gate static int got_k4 = 0;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate static int default_k5 = 1;
1067c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1077c478bd9Sstevel@tonic-gate static int default_k4 = 1;
1087c478bd9Sstevel@tonic-gate #else  /* KRB5_KRB4_COMPAT */
1097c478bd9Sstevel@tonic-gate static int default_k4 = 0;
1107c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
1117c478bd9Sstevel@tonic-gate 
11256a424ccSmp153739 static void usage()
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available"))
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("Usage: %s [-5] [-4] [-e]"
1177c478bd9Sstevel@tonic-gate                     " [[-c] [-f] [-s] [-a [-n]]] "
1187c478bd9Sstevel@tonic-gate 	            "[-k [-t] [-K]] [name]\n"), progname);
1197c478bd9Sstevel@tonic-gate     fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5));
1207c478bd9Sstevel@tonic-gate     fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4));
1217c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t   (Default is %s%s%s%s)\n"),
1227c478bd9Sstevel@tonic-gate 	    default_k5?"Kerberos 5":"",
1237c478bd9Sstevel@tonic-gate 	    (default_k5 && default_k4)?gettext(" and "):"",
1247c478bd9Sstevel@tonic-gate 	    default_k4?"Kerberos 4":"",
1257c478bd9Sstevel@tonic-gate 	    (!default_k5 && !default_k4)?gettext("neither"):"");
1267c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t-c specifies credentials cache\n"));
1277c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t-k specifies keytab\n"));
1287c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t   (Default is credentials cache)\n"));
1297c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t-e shows the encryption type\n"));
1307c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\toptions for credential caches:\n"));
1317c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-f shows credentials flags\n"));
1327c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-s sets exit status based on valid tgt existence\n"));
1337c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-a displays the address list\n"));
1347c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-n do not reverse-resolve\n"));
1357c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\toptions for keytabs:\n"));
1367c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-t shows keytab entry timestamps\n"));
1377c478bd9Sstevel@tonic-gate     fprintf(stderr, gettext("\t\t-K shows keytab entry DES keys\n"));
1387c478bd9Sstevel@tonic-gate     exit(1);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate int
14356a424ccSmp153739 main(argc, argv)
14456a424ccSmp153739     int argc;
14556a424ccSmp153739     char **argv;
1467c478bd9Sstevel@tonic-gate {
1477c478bd9Sstevel@tonic-gate     int c;
1487c478bd9Sstevel@tonic-gate     char *name;
1497c478bd9Sstevel@tonic-gate     int mode;
1507c478bd9Sstevel@tonic-gate     int use_k5 = 0, use_k4 = 0;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate     got_k5 = 1;
1537c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1547c478bd9Sstevel@tonic-gate     got_k4 = 1;
1557c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate     (void) setlocale(LC_ALL, "");
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
1607c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
1617c478bd9Sstevel@tonic-gate #endif /* !TEXT_DOMAIN */
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate     progname = GET_PROGNAME(argv[0]);
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate     name = NULL;
1687c478bd9Sstevel@tonic-gate     mode = DEFAULT;
1697c478bd9Sstevel@tonic-gate     while ((c = getopt(argc, argv, "fetKsnack45")) != -1) {
1707c478bd9Sstevel@tonic-gate 	switch (c) {
1717c478bd9Sstevel@tonic-gate 	case 'f':
1727c478bd9Sstevel@tonic-gate 	    show_flags = 1;
1737c478bd9Sstevel@tonic-gate 	    break;
1747c478bd9Sstevel@tonic-gate 	case 'e':
1757c478bd9Sstevel@tonic-gate 	    show_etype = 1;
1767c478bd9Sstevel@tonic-gate 	    break;
1777c478bd9Sstevel@tonic-gate 	case 't':
1787c478bd9Sstevel@tonic-gate 	    show_time = 1;
1797c478bd9Sstevel@tonic-gate 	    break;
1807c478bd9Sstevel@tonic-gate 	case 'K':
1817c478bd9Sstevel@tonic-gate 	    show_keys = 1;
1827c478bd9Sstevel@tonic-gate 	    break;
1837c478bd9Sstevel@tonic-gate 	case 's':
1847c478bd9Sstevel@tonic-gate 	    status_only = 1;
1857c478bd9Sstevel@tonic-gate 	    break;
1867c478bd9Sstevel@tonic-gate 	case 'n':
1877c478bd9Sstevel@tonic-gate 	    no_resolve = 1;
1887c478bd9Sstevel@tonic-gate 	    break;
1897c478bd9Sstevel@tonic-gate 	case 'a':
1907c478bd9Sstevel@tonic-gate 	    show_addresses = 1;
1917c478bd9Sstevel@tonic-gate 	    break;
1927c478bd9Sstevel@tonic-gate 	case 'c':
1937c478bd9Sstevel@tonic-gate 	    if (mode != DEFAULT) usage();
1947c478bd9Sstevel@tonic-gate 	    mode = CCACHE;
1957c478bd9Sstevel@tonic-gate 	    break;
1967c478bd9Sstevel@tonic-gate 	case 'k':
1977c478bd9Sstevel@tonic-gate 	    if (mode != DEFAULT) usage();
1987c478bd9Sstevel@tonic-gate 	    mode = KEYTAB;
1997c478bd9Sstevel@tonic-gate 	    break;
2007c478bd9Sstevel@tonic-gate 	case '4':
2017c478bd9Sstevel@tonic-gate 	    if (!got_k4)
2027c478bd9Sstevel@tonic-gate 	    {
2037c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
2047c478bd9Sstevel@tonic-gate 		fprintf(stderr, "Kerberos 4 support could not be loaded\n");
2057c478bd9Sstevel@tonic-gate #else  /* KRB5_KRB4_COMPAT */
2067c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("This was not built with Kerberos 4 support\n"));
2077c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
2087c478bd9Sstevel@tonic-gate 		exit(3);
2097c478bd9Sstevel@tonic-gate 	    }
2107c478bd9Sstevel@tonic-gate 	    use_k4 = 1;
2117c478bd9Sstevel@tonic-gate 	    break;
2127c478bd9Sstevel@tonic-gate 	case '5':
2137c478bd9Sstevel@tonic-gate 	    if (!got_k5)
2147c478bd9Sstevel@tonic-gate 	    {
2157c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n"));
2167c478bd9Sstevel@tonic-gate 		exit(3);
2177c478bd9Sstevel@tonic-gate 	    }
2187c478bd9Sstevel@tonic-gate 	    use_k5 = 1;
2197c478bd9Sstevel@tonic-gate 	    break;
2207c478bd9Sstevel@tonic-gate 	default:
2217c478bd9Sstevel@tonic-gate 	    usage();
2227c478bd9Sstevel@tonic-gate 	    break;
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate     }
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate     if (no_resolve && !show_addresses) {
2277c478bd9Sstevel@tonic-gate 	usage();
2287c478bd9Sstevel@tonic-gate     }
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate     if (mode == DEFAULT || mode == CCACHE) {
2317c478bd9Sstevel@tonic-gate 	if (show_time || show_keys)
2327c478bd9Sstevel@tonic-gate 	    usage();
2337c478bd9Sstevel@tonic-gate     } else {
2347c478bd9Sstevel@tonic-gate 	if (show_flags || status_only || show_addresses)
2357c478bd9Sstevel@tonic-gate 	    usage();
2367c478bd9Sstevel@tonic-gate     }
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate     if (argc - optind > 1) {
2397c478bd9Sstevel@tonic-gate 		fprintf(stderr,
2407c478bd9Sstevel@tonic-gate 			gettext("Extra arguments (starting with \"%s\").\n"),
2417c478bd9Sstevel@tonic-gate 		argv[optind+1]);
2427c478bd9Sstevel@tonic-gate 	usage();
2437c478bd9Sstevel@tonic-gate     }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate     name = (optind == argc-1) ? argv[optind] : 0;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate     if (!use_k5 && !use_k4)
2487c478bd9Sstevel@tonic-gate     {
2497c478bd9Sstevel@tonic-gate 	use_k5 = default_k5;
2507c478bd9Sstevel@tonic-gate 	use_k4 = default_k4;
2517c478bd9Sstevel@tonic-gate     }
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate     if (!use_k5)
2547c478bd9Sstevel@tonic-gate 	got_k5 = 0;
2557c478bd9Sstevel@tonic-gate     if (!use_k4)
2567c478bd9Sstevel@tonic-gate 	got_k4 = 0;
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate     now = time(0);
2597c478bd9Sstevel@tonic-gate     {
2607c478bd9Sstevel@tonic-gate 	char tmp[BUFSIZ];
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
2637c478bd9Sstevel@tonic-gate 	    !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp),
2647c478bd9Sstevel@tonic-gate 					(char *) NULL))
26556a424ccSmp153739 	    timestamp_width = (int) strlen(tmp);
2667c478bd9Sstevel@tonic-gate 	else
2677c478bd9Sstevel@tonic-gate 	    timestamp_width = 15;
2687c478bd9Sstevel@tonic-gate     }
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate     if (got_k5)
2717c478bd9Sstevel@tonic-gate     {
2727c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
2737c478bd9Sstevel@tonic-gate 	retval = krb5_init_context(&kcontext);
2747c478bd9Sstevel@tonic-gate 	if (retval) {
2757c478bd9Sstevel@tonic-gate 	    com_err(progname, retval, gettext("while initializing krb5"));
2767c478bd9Sstevel@tonic-gate 	    exit(1);
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate 	if (mode == DEFAULT || mode == CCACHE)
2807c478bd9Sstevel@tonic-gate 	    do_ccache(name);
2817c478bd9Sstevel@tonic-gate 	else
2827c478bd9Sstevel@tonic-gate 	    do_keytab(name);
2837c478bd9Sstevel@tonic-gate     } else {
2847c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
2857c478bd9Sstevel@tonic-gate 	if (mode == DEFAULT || mode == CCACHE)
2867c478bd9Sstevel@tonic-gate 	    do_v4_ccache(name);
2877c478bd9Sstevel@tonic-gate 	else {
2887c478bd9Sstevel@tonic-gate 	    /* We may want to add v4 srvtab support */
2897c478bd9Sstevel@tonic-gate 	    fprintf(stderr,
2907c478bd9Sstevel@tonic-gate 		    "%s: srvtab option not supported for Kerberos 4\n",
2917c478bd9Sstevel@tonic-gate 		    progname);
2927c478bd9Sstevel@tonic-gate 	    exit(1);
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate #endif /* KRB4_KRB5_COMPAT */
2957c478bd9Sstevel@tonic-gate     }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate     return 0;
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate void do_keytab(name)
3017c478bd9Sstevel@tonic-gate    char *name;
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate      krb5_keytab kt;
3047c478bd9Sstevel@tonic-gate      krb5_keytab_entry entry;
3057c478bd9Sstevel@tonic-gate      krb5_kt_cursor cursor;
3067c478bd9Sstevel@tonic-gate      char buf[BUFSIZ]; /* hopefully large enough for any type */
3077c478bd9Sstevel@tonic-gate      char *pname;
3087c478bd9Sstevel@tonic-gate      int code;
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate      if (name == NULL) {
3117c478bd9Sstevel@tonic-gate 	  if ((code = krb5_kt_default(kcontext, &kt))) {
3127c478bd9Sstevel@tonic-gate 			com_err(progname, code,
3137c478bd9Sstevel@tonic-gate 				gettext("while getting default keytab"));
3147c478bd9Sstevel@tonic-gate 	       exit(1);
3157c478bd9Sstevel@tonic-gate 	  }
3167c478bd9Sstevel@tonic-gate      } else {
3177c478bd9Sstevel@tonic-gate 	  if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
3187c478bd9Sstevel@tonic-gate 			com_err(progname, code,
3197c478bd9Sstevel@tonic-gate 				gettext("while resolving keytab %s"),
3207c478bd9Sstevel@tonic-gate 		       name);
3217c478bd9Sstevel@tonic-gate 	       exit(1);
3227c478bd9Sstevel@tonic-gate 	  }
3237c478bd9Sstevel@tonic-gate      }
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate      if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
3267c478bd9Sstevel@tonic-gate 	  com_err(progname, code,
3277c478bd9Sstevel@tonic-gate 			gettext("while getting keytab name"));
3287c478bd9Sstevel@tonic-gate 	  exit(1);
3297c478bd9Sstevel@tonic-gate      }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate      printf(gettext("Keytab name: %s\n"), buf);
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate      if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
3347c478bd9Sstevel@tonic-gate 	  com_err(progname, code,
3357c478bd9Sstevel@tonic-gate 			gettext("while starting keytab scan"));
3367c478bd9Sstevel@tonic-gate 	  exit(1);
3377c478bd9Sstevel@tonic-gate      }
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate      if (show_time) {
3407c478bd9Sstevel@tonic-gate 	  printf(gettext("KVNO Timestamp"));
3417c478bd9Sstevel@tonic-gate 	  fillit(stdout, timestamp_width -
3427c478bd9Sstevel@tonic-gate 	    sizeof (gettext("Timestamp")) + 2, (int)' ');
3437c478bd9Sstevel@tonic-gate 	  printf(gettext("Principal\n"));
3447c478bd9Sstevel@tonic-gate 	  printf("---- ");
3457c478bd9Sstevel@tonic-gate 	  fillit(stdout, timestamp_width, (int) '-');
3467c478bd9Sstevel@tonic-gate 	  printf(" ");
3477c478bd9Sstevel@tonic-gate 	  fillit(stdout, 78 - timestamp_width -
3487c478bd9Sstevel@tonic-gate 		    sizeof (gettext("KVNO")), (int)'-');
3497c478bd9Sstevel@tonic-gate 	  printf("\n");
3507c478bd9Sstevel@tonic-gate      } else {
3517c478bd9Sstevel@tonic-gate 	  printf(gettext("KVNO Principal\n"));
3527c478bd9Sstevel@tonic-gate 	  printf("---- ------------------------------"
3537c478bd9Sstevel@tonic-gate 			    "--------------------------------------"
3547c478bd9Sstevel@tonic-gate 			    "------\n");
3557c478bd9Sstevel@tonic-gate      }
3567c478bd9Sstevel@tonic-gate 
35756a424ccSmp153739      while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
35856a424ccSmp153739 	  if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
3597c478bd9Sstevel@tonic-gate 	       com_err(progname, code,
3607c478bd9Sstevel@tonic-gate 				gettext("while unparsing principal name"));
3617c478bd9Sstevel@tonic-gate 	       exit(1);
3627c478bd9Sstevel@tonic-gate 	  }
3637c478bd9Sstevel@tonic-gate 	  printf("%4d ", entry.vno);
3647c478bd9Sstevel@tonic-gate 	  if (show_time) {
3657c478bd9Sstevel@tonic-gate 	       printtime(entry.timestamp);
3667c478bd9Sstevel@tonic-gate 	       printf(" ");
3677c478bd9Sstevel@tonic-gate 	  }
3687c478bd9Sstevel@tonic-gate 	  printf("%s", pname);
3697c478bd9Sstevel@tonic-gate 	  if (show_etype)
3707c478bd9Sstevel@tonic-gate 	      printf(" (%s) " , etype_string(entry.key.enctype));
3717c478bd9Sstevel@tonic-gate 	  if (show_keys) {
3727c478bd9Sstevel@tonic-gate 	       printf(" (0x");
3737c478bd9Sstevel@tonic-gate 	       {
3747c478bd9Sstevel@tonic-gate 		    int i;
3757c478bd9Sstevel@tonic-gate 		    for (i = 0; i < entry.key.length; i++)
3767c478bd9Sstevel@tonic-gate 			 printf("%02x", entry.key.contents[i]);
3777c478bd9Sstevel@tonic-gate 	       }
3787c478bd9Sstevel@tonic-gate 	       printf(")");
3797c478bd9Sstevel@tonic-gate 	  }
3807c478bd9Sstevel@tonic-gate 	  printf("\n");
3817c478bd9Sstevel@tonic-gate 	  krb5_free_unparsed_name(kcontext, pname);
3827c478bd9Sstevel@tonic-gate      }
3837c478bd9Sstevel@tonic-gate      if (code && code != KRB5_KT_END) {
3847c478bd9Sstevel@tonic-gate 		com_err(progname, code,
3857c478bd9Sstevel@tonic-gate 			gettext("while scanning keytab"));
3867c478bd9Sstevel@tonic-gate 	  exit(1);
3877c478bd9Sstevel@tonic-gate      }
3887c478bd9Sstevel@tonic-gate      if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
3897c478bd9Sstevel@tonic-gate 		com_err(progname, code,
3907c478bd9Sstevel@tonic-gate 			gettext("while ending keytab scan"));
3917c478bd9Sstevel@tonic-gate 	  exit(1);
3927c478bd9Sstevel@tonic-gate      }
3937c478bd9Sstevel@tonic-gate      exit(0);
3947c478bd9Sstevel@tonic-gate }
3957c478bd9Sstevel@tonic-gate void do_ccache(name)
3967c478bd9Sstevel@tonic-gate    char *name;
3977c478bd9Sstevel@tonic-gate {
3987c478bd9Sstevel@tonic-gate     krb5_ccache cache = NULL;
3997c478bd9Sstevel@tonic-gate     krb5_cc_cursor cur;
4007c478bd9Sstevel@tonic-gate     krb5_creds creds;
4017c478bd9Sstevel@tonic-gate     krb5_principal princ;
4027c478bd9Sstevel@tonic-gate     krb5_flags flags;
4037c478bd9Sstevel@tonic-gate     krb5_error_code code;
4047c478bd9Sstevel@tonic-gate     int	exit_status = 0;
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate     if (status_only)
4077c478bd9Sstevel@tonic-gate 	/* exit_status is set back to 0 if a valid tgt is found */
4087c478bd9Sstevel@tonic-gate 	exit_status = 1;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate     if (name == NULL) {
4117c478bd9Sstevel@tonic-gate 	if ((code = krb5_cc_default(kcontext, &cache))) {
4127c478bd9Sstevel@tonic-gate 	    if (!status_only)
4137c478bd9Sstevel@tonic-gate 				com_err(progname, code,
4147c478bd9Sstevel@tonic-gate 					gettext("while getting default "
4157c478bd9Sstevel@tonic-gate 						"ccache"));
4167c478bd9Sstevel@tonic-gate 	    exit(1);
4177c478bd9Sstevel@tonic-gate 	    }
4187c478bd9Sstevel@tonic-gate     } else {
4197c478bd9Sstevel@tonic-gate 	if ((code = krb5_cc_resolve(kcontext, name, &cache))) {
4207c478bd9Sstevel@tonic-gate 	    if (!status_only)
4217c478bd9Sstevel@tonic-gate 				com_err(progname, code,
4227c478bd9Sstevel@tonic-gate 					gettext("while resolving ccache %s"),
4237c478bd9Sstevel@tonic-gate 			name);
4247c478bd9Sstevel@tonic-gate 	    exit(1);
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate     }
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate     flags = 0;				/* turns off OPENCLOSE mode */
4297c478bd9Sstevel@tonic-gate     if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
4307c478bd9Sstevel@tonic-gate 	if (code == KRB5_FCC_NOFILE) {
4317c478bd9Sstevel@tonic-gate 	    if (!status_only) {
4327c478bd9Sstevel@tonic-gate 		com_err(progname, code, gettext("(ticket cache %s:%s)"),
4337c478bd9Sstevel@tonic-gate 			krb5_cc_get_type(kcontext, cache),
4347c478bd9Sstevel@tonic-gate 			krb5_cc_get_name(kcontext, cache));
4357c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4367c478bd9Sstevel@tonic-gate 		if (name == NULL)
4377c478bd9Sstevel@tonic-gate 		    do_v4_ccache(0);
4387c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
4397c478bd9Sstevel@tonic-gate 	    }
4407c478bd9Sstevel@tonic-gate 	} else {
4417c478bd9Sstevel@tonic-gate 	    if (!status_only)
4427c478bd9Sstevel@tonic-gate 		com_err(progname, code,
4437c478bd9Sstevel@tonic-gate 			gettext("while setting cache "
4447c478bd9Sstevel@tonic-gate 				"flags(ticket cache %s:%s)"),
4457c478bd9Sstevel@tonic-gate 			krb5_cc_get_type(kcontext, cache),
4467c478bd9Sstevel@tonic-gate 			krb5_cc_get_name(kcontext, cache));
4477c478bd9Sstevel@tonic-gate 	}
4487c478bd9Sstevel@tonic-gate 	exit(1);
4497c478bd9Sstevel@tonic-gate     }
4507c478bd9Sstevel@tonic-gate     if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
4517c478bd9Sstevel@tonic-gate 	if (!status_only)
4527c478bd9Sstevel@tonic-gate 			com_err(progname, code,
4537c478bd9Sstevel@tonic-gate 				gettext("while retrieving principal name"));
4547c478bd9Sstevel@tonic-gate 	exit(1);
4557c478bd9Sstevel@tonic-gate     }
4567c478bd9Sstevel@tonic-gate     if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
4577c478bd9Sstevel@tonic-gate 	if (!status_only)
4587c478bd9Sstevel@tonic-gate 			com_err(progname, code,
4597c478bd9Sstevel@tonic-gate 				gettext("while unparsing principal name"));
4607c478bd9Sstevel@tonic-gate 	exit(1);
4617c478bd9Sstevel@tonic-gate     }
4627c478bd9Sstevel@tonic-gate     if (!status_only) {
4637c478bd9Sstevel@tonic-gate 		printf(gettext("Ticket cache: %s:%s\nDefault principal: "
4647c478bd9Sstevel@tonic-gate 			    "%s\n\n"),
4657c478bd9Sstevel@tonic-gate 	       krb5_cc_get_type(kcontext, cache),
4667c478bd9Sstevel@tonic-gate 	       krb5_cc_get_name(kcontext, cache), defname);
4677c478bd9Sstevel@tonic-gate 		fputs(gettext("Valid starting"), stdout);
4687c478bd9Sstevel@tonic-gate 		fillit(stdout, timestamp_width -
4697c478bd9Sstevel@tonic-gate 		    sizeof (gettext("Valid starting")) + 3, (int)' ');
4707c478bd9Sstevel@tonic-gate 		fputs(gettext("Expires"), stdout);
4717c478bd9Sstevel@tonic-gate 		fillit(stdout, timestamp_width -
4727c478bd9Sstevel@tonic-gate 		    sizeof (gettext("Expires")) + 3, (int)' ');
4737c478bd9Sstevel@tonic-gate 		fputs(gettext("Service principal\n"), stdout);
4747c478bd9Sstevel@tonic-gate     }
4757c478bd9Sstevel@tonic-gate     if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
4767c478bd9Sstevel@tonic-gate 	if (!status_only)
4777c478bd9Sstevel@tonic-gate 			com_err(progname, code,
4787c478bd9Sstevel@tonic-gate 				gettext("while starting to retrieve tickets"));
4797c478bd9Sstevel@tonic-gate 	exit(1);
4807c478bd9Sstevel@tonic-gate     }
4817c478bd9Sstevel@tonic-gate     while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
4827c478bd9Sstevel@tonic-gate 	if (status_only) {
4837c478bd9Sstevel@tonic-gate 	    if (exit_status && creds.server->length == 2 &&
4847c478bd9Sstevel@tonic-gate 			    strcmp(creds.server->realm.data,
4857c478bd9Sstevel@tonic-gate 				princ->realm.data) == 0 &&
4867c478bd9Sstevel@tonic-gate 			    strcmp((char *)creds.server->data[0].data,
4877c478bd9Sstevel@tonic-gate 				"krbtgt") == 0 &&
4887c478bd9Sstevel@tonic-gate 		strcmp((char *)creds.server->data[1].data,
4897c478bd9Sstevel@tonic-gate 		       princ->realm.data) == 0 &&
4907c478bd9Sstevel@tonic-gate 		creds.times.endtime > now)
4917c478bd9Sstevel@tonic-gate 		exit_status = 0;
4927c478bd9Sstevel@tonic-gate 	} else {
49356a424ccSmp153739 	    show_credential(&creds);
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 	krb5_free_cred_contents(kcontext, &creds);
4967c478bd9Sstevel@tonic-gate     }
4977c478bd9Sstevel@tonic-gate     if (code == KRB5_CC_END) {
4987c478bd9Sstevel@tonic-gate 	if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
4997c478bd9Sstevel@tonic-gate 	    if (!status_only)
5007c478bd9Sstevel@tonic-gate 				com_err(progname, code,
5017c478bd9Sstevel@tonic-gate 					gettext("while finishing ticket "
5027c478bd9Sstevel@tonic-gate 						"retrieval"));
5037c478bd9Sstevel@tonic-gate 	    exit(1);
5047c478bd9Sstevel@tonic-gate 	}
5057c478bd9Sstevel@tonic-gate 	flags = KRB5_TC_OPENCLOSE;	/* turns on OPENCLOSE mode */
5067c478bd9Sstevel@tonic-gate 	if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
5077c478bd9Sstevel@tonic-gate 	    if (!status_only)
5087c478bd9Sstevel@tonic-gate 				com_err(progname, code,
5097c478bd9Sstevel@tonic-gate 					gettext("while closing ccache"));
5107c478bd9Sstevel@tonic-gate 	    exit(1);
5117c478bd9Sstevel@tonic-gate 	}
5127c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
5137c478bd9Sstevel@tonic-gate 	if (name == NULL && !status_only)
5147c478bd9Sstevel@tonic-gate 	    do_v4_ccache(0);
5157c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
5167c478bd9Sstevel@tonic-gate 	exit(exit_status);
5177c478bd9Sstevel@tonic-gate     } else {
5187c478bd9Sstevel@tonic-gate 	if (!status_only)
5197c478bd9Sstevel@tonic-gate 			com_err(progname, code,
5207c478bd9Sstevel@tonic-gate 				gettext("while retrieving a ticket"));
5217c478bd9Sstevel@tonic-gate 	exit(1);
5227c478bd9Sstevel@tonic-gate     }
5237c478bd9Sstevel@tonic-gate }
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate char *
5267c478bd9Sstevel@tonic-gate etype_string(enctype)
5277c478bd9Sstevel@tonic-gate     krb5_enctype enctype;
5287c478bd9Sstevel@tonic-gate {
529*a49a392fSps57422     static char buf[256];
5307c478bd9Sstevel@tonic-gate     krb5_error_code retval;
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate     if ((retval = krb5_enctype_to_string(enctype, buf, sizeof(buf)))) {
5337c478bd9Sstevel@tonic-gate 	/* XXX if there's an error != EINVAL, I should probably report it */
534*a49a392fSps57422 	snprintf(buf, sizeof(buf), gettext("unsupported encryption type %d"), enctype);
5357c478bd9Sstevel@tonic-gate     }
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate     return buf;
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
54056a424ccSmp153739 static char *
5417c478bd9Sstevel@tonic-gate flags_string(cred)
5427c478bd9Sstevel@tonic-gate     register krb5_creds *cred;
5437c478bd9Sstevel@tonic-gate {
5447c478bd9Sstevel@tonic-gate     static char buf[32];
5457c478bd9Sstevel@tonic-gate     int i = 0;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
5487c478bd9Sstevel@tonic-gate 	buf[i++] = 'F';
5497c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_FORWARDED)
5507c478bd9Sstevel@tonic-gate 	buf[i++] = 'f';
5517c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_PROXIABLE)
5527c478bd9Sstevel@tonic-gate 	buf[i++] = 'P';
5537c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_PROXY)
5547c478bd9Sstevel@tonic-gate 	buf[i++] = 'p';
5557c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
5567c478bd9Sstevel@tonic-gate 	buf[i++] = 'D';
5577c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_POSTDATED)
5587c478bd9Sstevel@tonic-gate 	buf[i++] = 'd';
5597c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_INVALID)
5607c478bd9Sstevel@tonic-gate 	buf[i++] = 'i';
5617c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_RENEWABLE)
5627c478bd9Sstevel@tonic-gate 	buf[i++] = 'R';
5637c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_INITIAL)
5647c478bd9Sstevel@tonic-gate 	buf[i++] = 'I';
5657c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_HW_AUTH)
5667c478bd9Sstevel@tonic-gate 	buf[i++] = 'H';
5677c478bd9Sstevel@tonic-gate     if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
5687c478bd9Sstevel@tonic-gate 	buf[i++] = 'A';
56956a424ccSmp153739     if (cred->ticket_flags & TKT_FLG_TRANSIT_POLICY_CHECKED)
57056a424ccSmp153739 	buf[i++] = 'T';
57156a424ccSmp153739     if (cred->ticket_flags & TKT_FLG_OK_AS_DELEGATE)
57256a424ccSmp153739 	buf[i++] = 'O';		/* D/d are taken.  Use short strings?  */
57356a424ccSmp153739     if (cred->ticket_flags & TKT_FLG_ANONYMOUS)
57456a424ccSmp153739 	buf[i++] = 'a';
5757c478bd9Sstevel@tonic-gate     buf[i] = '\0';
5767c478bd9Sstevel@tonic-gate     return(buf);
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate void
5807c478bd9Sstevel@tonic-gate printtime(tv)
5817c478bd9Sstevel@tonic-gate     time_t tv;
5827c478bd9Sstevel@tonic-gate {
5837c478bd9Sstevel@tonic-gate     char timestring[BUFSIZ];
5847c478bd9Sstevel@tonic-gate     char fill;
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate     fill = ' ';
5877c478bd9Sstevel@tonic-gate 	if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv, timestring,
5887c478bd9Sstevel@tonic-gate 					timestamp_width+1, &fill)) {
5897c478bd9Sstevel@tonic-gate 	printf(timestring);
5907c478bd9Sstevel@tonic-gate     }
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate void
59456a424ccSmp153739 show_credential(cred)
5957c478bd9Sstevel@tonic-gate     register krb5_creds * cred;
5967c478bd9Sstevel@tonic-gate {
5977c478bd9Sstevel@tonic-gate     krb5_error_code retval;
5987c478bd9Sstevel@tonic-gate     krb5_ticket *tkt;
5997c478bd9Sstevel@tonic-gate     char *name, *sname, *flags;
6007c478bd9Sstevel@tonic-gate     int	extra_field = 0;
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate     retval = krb5_unparse_name(kcontext, cred->client, &name);
6037c478bd9Sstevel@tonic-gate     if (retval) {
6047c478bd9Sstevel@tonic-gate 		com_err(progname, retval,
6057c478bd9Sstevel@tonic-gate 			gettext("while unparsing client name"));
6067c478bd9Sstevel@tonic-gate 	return;
6077c478bd9Sstevel@tonic-gate     }
6087c478bd9Sstevel@tonic-gate     retval = krb5_unparse_name(kcontext, cred->server, &sname);
6097c478bd9Sstevel@tonic-gate     if (retval) {
6107c478bd9Sstevel@tonic-gate 		com_err(progname, retval,
6117c478bd9Sstevel@tonic-gate 			gettext("while unparsing server name"));
6127c478bd9Sstevel@tonic-gate 		krb5_free_unparsed_name(kcontext, name);
6137c478bd9Sstevel@tonic-gate 	return;
6147c478bd9Sstevel@tonic-gate     }
6157c478bd9Sstevel@tonic-gate     if (!cred->times.starttime)
6167c478bd9Sstevel@tonic-gate 	cred->times.starttime = cred->times.authtime;
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate     printtime(cred->times.starttime);
6197c478bd9Sstevel@tonic-gate     putchar(' '); putchar(' ');
6207c478bd9Sstevel@tonic-gate     printtime(cred->times.endtime);
6217c478bd9Sstevel@tonic-gate     putchar(' '); putchar(' ');
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate     printf("%s\n", sname);
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate     if (strcmp(name, defname)) {
6267c478bd9Sstevel@tonic-gate 		printf(gettext("\tfor client %s"), name);
6277c478bd9Sstevel@tonic-gate 	    extra_field++;
6287c478bd9Sstevel@tonic-gate     }
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate     if (cred->times.renew_till) {
6317c478bd9Sstevel@tonic-gate 	if (!extra_field)
6327c478bd9Sstevel@tonic-gate 		fputs("\t",stdout);
6337c478bd9Sstevel@tonic-gate 	else
6347c478bd9Sstevel@tonic-gate 		fputs(", ",stdout);
6357c478bd9Sstevel@tonic-gate 		fputs(gettext("renew until "), stdout);
6367c478bd9Sstevel@tonic-gate 	printtime(cred->times.renew_till);
6377c478bd9Sstevel@tonic-gate 	extra_field += 2;
6387c478bd9Sstevel@tonic-gate     }
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate     if (extra_field > 3) {
6417c478bd9Sstevel@tonic-gate 	fputs("\n", stdout);
6427c478bd9Sstevel@tonic-gate 	extra_field = 0;
6437c478bd9Sstevel@tonic-gate     }
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate     if (show_flags) {
6467c478bd9Sstevel@tonic-gate 	flags = flags_string(cred);
6477c478bd9Sstevel@tonic-gate 	if (flags && *flags) {
6487c478bd9Sstevel@tonic-gate 	    if (!extra_field)
6497c478bd9Sstevel@tonic-gate 		fputs("\t",stdout);
6507c478bd9Sstevel@tonic-gate 	    else
6517c478bd9Sstevel@tonic-gate 		fputs(", ",stdout);
6527c478bd9Sstevel@tonic-gate 			printf(gettext("Flags: %s"), flags);
6537c478bd9Sstevel@tonic-gate 	    extra_field++;
6547c478bd9Sstevel@tonic-gate 	}
6557c478bd9Sstevel@tonic-gate     }
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate     if (extra_field > 2) {
6587c478bd9Sstevel@tonic-gate 	fputs("\n", stdout);
6597c478bd9Sstevel@tonic-gate 	extra_field = 0;
6607c478bd9Sstevel@tonic-gate     }
6617c478bd9Sstevel@tonic-gate 
6627c478bd9Sstevel@tonic-gate     if (show_etype) {
6637c478bd9Sstevel@tonic-gate 	retval = decode_krb5_ticket(&cred->ticket, &tkt);
66456a424ccSmp153739 	if (retval)
66556a424ccSmp153739 	    goto err_tkt;
66656a424ccSmp153739 
6677c478bd9Sstevel@tonic-gate 	if (!extra_field)
6687c478bd9Sstevel@tonic-gate 	    fputs("\t",stdout);
6697c478bd9Sstevel@tonic-gate 	else
6707c478bd9Sstevel@tonic-gate 	    fputs(", ",stdout);
6717c478bd9Sstevel@tonic-gate 	printf(gettext("Etype(skey, tkt): %s, "),
6727c478bd9Sstevel@tonic-gate 	       etype_string(cred->keyblock.enctype));
6737c478bd9Sstevel@tonic-gate 	printf("%s ",
6747c478bd9Sstevel@tonic-gate 	       etype_string(tkt->enc_part.enctype));
6757c478bd9Sstevel@tonic-gate 	extra_field++;
67656a424ccSmp153739 
67756a424ccSmp153739     err_tkt:
67856a424ccSmp153739 	if (tkt != NULL)
67956a424ccSmp153739 	    krb5_free_ticket(kcontext, tkt);
6807c478bd9Sstevel@tonic-gate     }
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate     /* if any additional info was printed, extra_field is non-zero */
6837c478bd9Sstevel@tonic-gate     if (extra_field)
6847c478bd9Sstevel@tonic-gate 	putchar('\n');
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate     if (show_addresses) {
6887c478bd9Sstevel@tonic-gate 	if (!cred->addresses || !cred->addresses[0]) {
6897c478bd9Sstevel@tonic-gate 	    printf(gettext("\tAddresses: (none)\n"));
6907c478bd9Sstevel@tonic-gate 	} else {
6917c478bd9Sstevel@tonic-gate 	    int i;
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	    printf(gettext("\tAddresses: "));
6947c478bd9Sstevel@tonic-gate 	    one_addr(cred->addresses[0]);
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 	    for (i=1; cred->addresses[i]; i++) {
6977c478bd9Sstevel@tonic-gate 		printf(", ");
6987c478bd9Sstevel@tonic-gate 		one_addr(cred->addresses[i]);
6997c478bd9Sstevel@tonic-gate 	    }
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 	    printf("\n");
7027c478bd9Sstevel@tonic-gate 	}
7037c478bd9Sstevel@tonic-gate     }
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate     krb5_free_unparsed_name(kcontext, name);
7067c478bd9Sstevel@tonic-gate     krb5_free_unparsed_name(kcontext, sname);
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate #include "port-sockets.h"
7107c478bd9Sstevel@tonic-gate #include "socket-utils.h" /* for ss2sin etc */
7117c478bd9Sstevel@tonic-gate #include <fake-addrinfo.h>
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate void one_addr(a)
7147c478bd9Sstevel@tonic-gate     krb5_address *a;
7157c478bd9Sstevel@tonic-gate {
7167c478bd9Sstevel@tonic-gate     struct sockaddr_storage ss;
7177c478bd9Sstevel@tonic-gate     int err;
7187c478bd9Sstevel@tonic-gate     char namebuf[NI_MAXHOST];
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate     memset (&ss, 0, sizeof (ss));
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate     switch (a->addrtype) {
7237c478bd9Sstevel@tonic-gate     case ADDRTYPE_INET:
7247c478bd9Sstevel@tonic-gate 	if (a->length != IPV4_ADDR_LEN) {
7257c478bd9Sstevel@tonic-gate 	broken:
7267c478bd9Sstevel@tonic-gate 	    printf ("broken address (type %d length %d)",
7277c478bd9Sstevel@tonic-gate 		    a->addrtype, a->length);
7287c478bd9Sstevel@tonic-gate 	    return;
7297c478bd9Sstevel@tonic-gate 	}
7307c478bd9Sstevel@tonic-gate 	{
7317c478bd9Sstevel@tonic-gate 	    struct sockaddr_in *sinp = ss2sin (&ss);
7327c478bd9Sstevel@tonic-gate 	    sinp->sin_family = AF_INET;
7337c478bd9Sstevel@tonic-gate #ifdef HAVE_SA_LEN
7347c478bd9Sstevel@tonic-gate 	    sinp->sin_len = sizeof (struct sockaddr_in);
7357c478bd9Sstevel@tonic-gate #endif
7367c478bd9Sstevel@tonic-gate 	    memcpy (&sinp->sin_addr, a->contents, IPV4_ADDR_LEN);
7377c478bd9Sstevel@tonic-gate 	}
7387c478bd9Sstevel@tonic-gate 	break;
7397c478bd9Sstevel@tonic-gate #ifdef KRB5_USE_INET6
7407c478bd9Sstevel@tonic-gate     case ADDRTYPE_INET6:
7417c478bd9Sstevel@tonic-gate 	if (a->length != IPV6_ADDR_LEN)
7427c478bd9Sstevel@tonic-gate 	    goto broken;
7437c478bd9Sstevel@tonic-gate 	{
7447c478bd9Sstevel@tonic-gate 	    struct sockaddr_in6 *sin6p = ss2sin6 (&ss);
7457c478bd9Sstevel@tonic-gate 	    sin6p->sin6_family = AF_INET6;
7467c478bd9Sstevel@tonic-gate #ifdef HAVE_SA_LEN
7477c478bd9Sstevel@tonic-gate 	    sin6p->sin6_len = sizeof (struct sockaddr_in6);
7487c478bd9Sstevel@tonic-gate #endif
7497c478bd9Sstevel@tonic-gate 	    memcpy (&sin6p->sin6_addr, a->contents, IPV6_ADDR_LEN);
7507c478bd9Sstevel@tonic-gate 	}
7517c478bd9Sstevel@tonic-gate 	break;
7527c478bd9Sstevel@tonic-gate #endif
7537c478bd9Sstevel@tonic-gate     default:
7547c478bd9Sstevel@tonic-gate 	printf(gettext("unknown addr type %d"), a->addrtype);
7557c478bd9Sstevel@tonic-gate 	return;
7567c478bd9Sstevel@tonic-gate     }
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate     namebuf[0] = 0;
7597c478bd9Sstevel@tonic-gate     err = getnameinfo (ss2sa (&ss), socklen (ss2sa (&ss)),
7607c478bd9Sstevel@tonic-gate 		       namebuf, sizeof (namebuf), 0, 0,
7617c478bd9Sstevel@tonic-gate 		       no_resolve ? NI_NUMERICHOST : 0U);
7627c478bd9Sstevel@tonic-gate     if (err) {
7637c478bd9Sstevel@tonic-gate 	printf (gettext("unprintable address (type %d, error %d %s)"), a->addrtype, err,
7647c478bd9Sstevel@tonic-gate 		gai_strerror (err));
7657c478bd9Sstevel@tonic-gate 	return;
7667c478bd9Sstevel@tonic-gate     }
7677c478bd9Sstevel@tonic-gate     printf ("%s", namebuf);
7687c478bd9Sstevel@tonic-gate }
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate void
7717c478bd9Sstevel@tonic-gate fillit(f, num, c)
7727c478bd9Sstevel@tonic-gate     FILE		*f;
77356a424ccSmp153739     unsigned int	num;
7747c478bd9Sstevel@tonic-gate     int			c;
7757c478bd9Sstevel@tonic-gate {
7767c478bd9Sstevel@tonic-gate     int i;
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate     for (i=0; i<num; i++)
7797c478bd9Sstevel@tonic-gate 	fputc(c, f);
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
7837c478bd9Sstevel@tonic-gate void
7847c478bd9Sstevel@tonic-gate do_v4_ccache(name)
7857c478bd9Sstevel@tonic-gate     char * name;
7867c478bd9Sstevel@tonic-gate {
7877c478bd9Sstevel@tonic-gate     char    pname[ANAME_SZ];
7887c478bd9Sstevel@tonic-gate     char    pinst[INST_SZ];
7897c478bd9Sstevel@tonic-gate     char    prealm[REALM_SZ];
7907c478bd9Sstevel@tonic-gate     char    *file;
7917c478bd9Sstevel@tonic-gate     int     k_errno;
7927c478bd9Sstevel@tonic-gate     CREDENTIALS c;
7937c478bd9Sstevel@tonic-gate     int     header = 1;
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate     if (!got_k4)
7967c478bd9Sstevel@tonic-gate 	return;
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate     file = name?name:tkt_string();
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate     if (status_only) {
8017c478bd9Sstevel@tonic-gate 	fprintf(stderr,
8027c478bd9Sstevel@tonic-gate 		"%s: exit status option not supported for Kerberos 4\n",
8037c478bd9Sstevel@tonic-gate 		progname);
8047c478bd9Sstevel@tonic-gate 	exit(1);
8057c478bd9Sstevel@tonic-gate     }
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate     if (got_k5)
8087c478bd9Sstevel@tonic-gate 	printf("\n\n");
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate     printf("Kerberos 4 ticket cache: %s\n", file);
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate     /*
8137c478bd9Sstevel@tonic-gate      * Since krb_get_tf_realm will return a ticket_file error,
8147c478bd9Sstevel@tonic-gate      * we will call tf_init and tf_close first to filter out
8157c478bd9Sstevel@tonic-gate      * things like no ticket file.  Otherwise, the error that
8167c478bd9Sstevel@tonic-gate      * the user would see would be
8177c478bd9Sstevel@tonic-gate      * klist: can't find realm of ticket file: No ticket file (tf_util)
8187c478bd9Sstevel@tonic-gate      * instead of
8197c478bd9Sstevel@tonic-gate      * klist: No ticket file (tf_util)
8207c478bd9Sstevel@tonic-gate      */
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate     /* Open ticket file */
82356a424ccSmp153739     k_errno = tf_init(file, R_TKT_FIL);
82456a424ccSmp153739     if (k_errno) {
8257c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno));
8267c478bd9Sstevel@tonic-gate 	exit(1);
8277c478bd9Sstevel@tonic-gate     }
8287c478bd9Sstevel@tonic-gate     /* Close ticket file */
8297c478bd9Sstevel@tonic-gate     (void) tf_close();
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate     /*
8327c478bd9Sstevel@tonic-gate      * We must find the realm of the ticket file here before calling
8337c478bd9Sstevel@tonic-gate      * tf_init because since the realm of the ticket file is not
8347c478bd9Sstevel@tonic-gate      * really stored in the principal section of the file, the
8357c478bd9Sstevel@tonic-gate      * routine we use must itself call tf_init and tf_close.
8367c478bd9Sstevel@tonic-gate      */
8377c478bd9Sstevel@tonic-gate     if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) {
8387c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: can't find realm of ticket file: %s\n",
8397c478bd9Sstevel@tonic-gate 		progname, krb_get_err_text (k_errno));
8407c478bd9Sstevel@tonic-gate 	exit(1);
8417c478bd9Sstevel@tonic-gate     }
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate     /* Open ticket file */
84456a424ccSmp153739     if ((k_errno = tf_init(file, R_TKT_FIL))) {
8457c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno));
8467c478bd9Sstevel@tonic-gate 	exit(1);
8477c478bd9Sstevel@tonic-gate     }
8487c478bd9Sstevel@tonic-gate     /* Get principal name and instance */
8497c478bd9Sstevel@tonic-gate     if ((k_errno = tf_get_pname(pname)) ||
8507c478bd9Sstevel@tonic-gate 	(k_errno = tf_get_pinst(pinst))) {
8517c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno));
8527c478bd9Sstevel@tonic-gate 	exit(1);
8537c478bd9Sstevel@tonic-gate     }
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate     /*
8567c478bd9Sstevel@tonic-gate      * You may think that this is the obvious place to get the
8577c478bd9Sstevel@tonic-gate      * realm of the ticket file, but it can't be done here as the
8587c478bd9Sstevel@tonic-gate      * routine to do this must open the ticket file.  This is why
8597c478bd9Sstevel@tonic-gate      * it was done before tf_init.
8607c478bd9Sstevel@tonic-gate      */
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate     printf("Principal: %s%s%s%s%s\n\n", pname,
8637c478bd9Sstevel@tonic-gate 	   (pinst[0] ? "." : ""), pinst,
8647c478bd9Sstevel@tonic-gate 	   (prealm[0] ? "@" : ""), prealm);
8657c478bd9Sstevel@tonic-gate     while ((k_errno = tf_get_cred(&c)) == KSUCCESS) {
8667c478bd9Sstevel@tonic-gate 	if (header) {
8677c478bd9Sstevel@tonic-gate 	    printf("%-18s  %-18s  %s\n",
8687c478bd9Sstevel@tonic-gate 		   "  Issued", "  Expires", "  Principal");
8697c478bd9Sstevel@tonic-gate 	    header = 0;
8707c478bd9Sstevel@tonic-gate 	}
8717c478bd9Sstevel@tonic-gate 	printtime(c.issue_date);
8727c478bd9Sstevel@tonic-gate 	fputs("  ", stdout);
87356a424ccSmp153739 	printtime(krb_life_to_time(c.issue_date, c.lifetime));
8747c478bd9Sstevel@tonic-gate 	printf("  %s%s%s%s%s\n",
8757c478bd9Sstevel@tonic-gate 	       c.service, (c.instance[0] ? "." : ""), c.instance,
8767c478bd9Sstevel@tonic-gate 	       (c.realm[0] ? "@" : ""), c.realm);
8777c478bd9Sstevel@tonic-gate     }
8787c478bd9Sstevel@tonic-gate     if (header && k_errno == EOF) {
8797c478bd9Sstevel@tonic-gate 	printf("No tickets in file.\n");
8807c478bd9Sstevel@tonic-gate     }
8817c478bd9Sstevel@tonic-gate }
8827c478bd9Sstevel@tonic-gate #endif /* KRB4_KRB5_COMPAT */
883