2 * clients/klist/klist.c
4 * Copyright 1990 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. M.I.T. makes no representations about the suitability of
20 * this software for any purpose. It is provided "as is" without express
21 * or implied warranty.
24 * List out the contents of your credential cache or keytab.
36 int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0;
43 krb5_context kcontext;
45 void show_credential KRB5_PROTOTYPE((char *,
49 void do_ccache KRB5_PROTOTYPE((char *));
50 void do_keytab KRB5_PROTOTYPE((char *));
51 void printtime KRB5_PROTOTYPE((time_t));
52 void fillit KRB5_PROTOTYPE((FILE *, int, int));
60 fprintf(stderr, "Usage: %s [[-c] [-f] [-e] [-s]] [-k [-t] [-K]] [name]\n",
62 fprintf(stderr, "\t-c specifies credentials cache, -k specifies keytab");
63 fprintf(stderr, ", -c is default\n");
64 fprintf(stderr, "\toptions for credential caches:\n");
65 fprintf(stderr, "\t\t-f shows credentials flags\n");
66 fprintf(stderr, "\t\t-e shows the encryption type\n");
67 fprintf(stderr, "\t\t-s sets exit status based on valid tgt existence\n");
68 fprintf(stderr, "\toptions for keytabs:\n");
69 fprintf(stderr, "\t\t-t shows keytab entry timestamps\n");
70 fprintf(stderr, "\t\t-K shows keytab entry DES keys\n");
84 krb5_init_context(&kcontext);
85 krb5_init_ets(kcontext);
87 progname = (strrchr(*argv, '/') ? strrchr(*argv, '/')+1 : argv[0]);
93 if ((*argv)[0] != '-') {
96 } else switch ((*argv)[1]) {
113 if (mode != DEFAULT) usage();
117 if (mode != DEFAULT) usage();
127 if (mode == DEFAULT || mode == CCACHE) {
128 if (show_time || show_keys)
131 if (show_flags || status_only)
135 if ((code = krb5_timeofday(kcontext, &now))) {
137 com_err(progname, code, "while getting time of day.");
143 if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) ||
144 !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), (char *) NULL))
145 timestamp_width = (int) strlen(tmp);
147 timestamp_width = 15;
150 if (mode == DEFAULT || mode == CCACHE)
160 krb5_keytab_entry entry;
161 krb5_kt_cursor cursor;
162 char buf[BUFSIZ]; /* hopefully large enough for any type */
167 if ((code = krb5_kt_default(kcontext, &kt))) {
168 com_err(progname, code, "while getting default keytab");
172 if ((code = krb5_kt_resolve(kcontext, name, &kt))) {
173 com_err(progname, code, "while resolving keytab %s",
179 if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) {
180 com_err(progname, code, "while getting keytab name");
184 printf("Keytab name: %s\n", buf);
186 if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) {
187 com_err(progname, code, "while starting keytab scan");
192 printf("KVNO Timestamp");
193 fillit(stdout, timestamp_width - sizeof("Timestamp") + 2, (int) ' ');
194 printf("Principal\n");
196 fillit(stdout, timestamp_width, (int) '-');
198 fillit(stdout, 78 - timestamp_width - sizeof("KVNO"), (int) '-');
201 printf("KVNO Principal\n");
202 printf("---- --------------------------------------------------------------------------\n");
205 while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) {
206 if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) {
207 com_err(progname, code, "while unparsing principal name");
210 printf("%4d ", entry.vno);
212 printtime(entry.timestamp);
220 for (i = 0; i < entry.key.length; i++)
221 printf("%02x", entry.key.contents[i]);
228 if (code && code != KRB5_KT_END) {
229 com_err(progname, code, "while scanning keytab");
232 if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) {
233 com_err(progname, code, "while ending keytab scan");
241 krb5_ccache cache = NULL;
244 krb5_principal princ;
246 krb5_error_code code;
250 /* exit_status is set back to 0 if a valid tgt is found */
254 if ((code = krb5_cc_default(kcontext, &cache))) {
256 com_err(progname, code, "while getting default ccache");
260 if ((code = krb5_cc_resolve(kcontext, name, &cache))) {
262 com_err(progname, code, "while resolving ccache %s",
268 flags = 0; /* turns off OPENCLOSE mode */
269 if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
270 if (code == ENOENT) {
272 com_err(progname, code, "(ticket cache %s)",
273 krb5_cc_get_name(kcontext, cache));
276 com_err(progname, code,
277 "while setting cache flags (ticket cache %s)",
278 krb5_cc_get_name(kcontext, cache));
282 if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) {
284 com_err(progname, code, "while retrieving principal name");
287 if ((code = krb5_unparse_name(kcontext, princ, &defname))) {
289 com_err(progname, code, "while unparsing principal name");
293 printf("Ticket cache: %s\nDefault principal: %s\n\n",
294 krb5_cc_get_name(kcontext, cache), defname);
295 fputs("Valid starting", stdout);
296 fillit(stdout, timestamp_width - sizeof("Valid starting") + 3,
298 fputs("Expires", stdout);
299 fillit(stdout, timestamp_width - sizeof("Expires") + 3,
301 fputs("Service principal\n", stdout);
303 if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) {
305 com_err(progname, code, "while starting to retrieve tickets");
308 while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) {
310 if (exit_status && creds.server->length == 2 &&
311 strcmp(creds.server->realm.data, princ->realm.data) == 0 &&
312 strcmp((char *)creds.server->data[0].data, "krbtgt") == 0 &&
313 strcmp((char *)creds.server->data[1].data,
314 princ->realm.data) == 0 &&
315 creds.times.endtime > now)
318 show_credential(progname, kcontext, &creds);
320 krb5_free_cred_contents(kcontext, &creds);
322 if (code == KRB5_CC_END) {
323 if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) {
325 com_err(progname, code, "while finishing ticket retrieval");
328 flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
329 if ((code = krb5_cc_set_flags(kcontext, cache, flags))) {
331 com_err(progname, code, "while closing ccache");
337 com_err(progname, code, "while retrieving a ticket");
343 etype_string(enctype)
344 krb5_enctype enctype;
349 case ENCTYPE_DES_CBC_CRC:
350 return "DES-CBC-CRC";
352 case ENCTYPE_DES_CBC_MD4:
353 return "DES-CBC-MD4";
355 case ENCTYPE_DES_CBC_MD5:
356 return "DES-CBC-MD5";
358 case ENCTYPE_DES3_CBC_MD5:
359 return "DES3-CBC-MD5";
362 sprintf(buf, "etype %d", enctype);
370 register krb5_creds *cred;
375 if (cred->ticket_flags & TKT_FLG_FORWARDABLE)
377 if (cred->ticket_flags & TKT_FLG_FORWARDED)
379 if (cred->ticket_flags & TKT_FLG_PROXIABLE)
381 if (cred->ticket_flags & TKT_FLG_PROXY)
383 if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE)
385 if (cred->ticket_flags & TKT_FLG_POSTDATED)
387 if (cred->ticket_flags & TKT_FLG_INVALID)
389 if (cred->ticket_flags & TKT_FLG_RENEWABLE)
391 if (cred->ticket_flags & TKT_FLG_INITIAL)
393 if (cred->ticket_flags & TKT_FLG_HW_AUTH)
395 if (cred->ticket_flags & TKT_FLG_PRE_AUTH)
405 char timestring[BUFSIZ];
409 if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv,
418 show_credential(progname, kcontext, cred)
420 krb5_context kcontext;
421 register krb5_creds * cred;
423 krb5_error_code retval;
425 char *name, *sname, *flags;
428 retval = krb5_unparse_name(kcontext, cred->client, &name);
430 com_err(progname, retval, "while unparsing client name");
433 retval = krb5_unparse_name(kcontext, cred->server, &sname);
435 com_err(progname, retval, "while unparsing server name");
439 if (!cred->times.starttime)
440 cred->times.starttime = cred->times.authtime;
442 printtime(cred->times.starttime);
443 putchar(' '); putchar(' ');
444 printtime(cred->times.endtime);
445 putchar(' '); putchar(' ');
447 printf("%s\n", sname);
449 if (strcmp(name, defname)) {
450 printf("\tfor client %s", name);
454 if (cred->times.renew_till) {
459 fputs("renew until ", stdout);
460 printtime(cred->times.renew_till);
464 if (extra_field > 3) {
470 flags = flags_string(cred);
471 if (flags && *flags) {
476 printf("Flags: %s", flags);
481 if (extra_field > 2) {
487 retval = decode_krb5_ticket(&cred->ticket, &tkt);
492 printf("Etype (skey, tkt): %s, %s ",
493 etype_string(cred->keyblock.enctype),
494 etype_string(tkt->enc_part.enctype));
495 krb5_free_ticket(kcontext, tkt);
499 /* if any additional info was printed, extra_field is non-zero */
514 for (i=0; i<num; i++)