1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * clients/klist/klist.c 8 * 9 * Copyright 1990 by the Massachusetts Institute of Technology. 10 * All Rights Reserved. 11 * 12 * Export of this software from the United States of America may 13 * require a specific license from the United States Government. 14 * It is the responsibility of any person or organization contemplating 15 * export to obtain such a license before exporting. 16 * 17 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 18 * distribute this software and its documentation for any purpose and 19 * without fee is hereby granted, provided that the above copyright 20 * notice appear in all copies and that both that copyright notice and 21 * this permission notice appear in supporting documentation, and that 22 * the name of M.I.T. not be used in advertising or publicity pertaining 23 * to distribution of the software without specific, written prior 24 * permission. Furthermore if you modify this software you must label 25 * your software as modified software and not distribute it in such a 26 * fashion that it might be confused with the original M.I.T. software. 27 * M.I.T. makes no representations about the suitability of 28 * this software for any purpose. It is provided "as is" without express 29 * or implied warranty. 30 * 31 * 32 * List out the contents of your credential cache or keytab. 33 */ 34 35 #include <k5-int.h> 36 #include "com_err.h" 37 #include <krb5.h> 38 #ifdef KRB5_KRB4_COMPAT 39 #include <kerberosIV/krb.h> 40 #endif /* KRB5_KRB4_COMPAT */ 41 42 #include <stdlib.h> 43 #include <string.h> 44 #include <stdio.h> 45 #include <time.h> 46 #include <libintl.h> 47 #include <locale.h> 48 #include <netinet/in.h> 49 #if defined(HAVE_ARPA_INET_H) 50 #include <arpa/inet.h> 51 #endif 52 #include <inet/ip.h> 53 #include <inet/ip6.h> 54 55 #ifndef _WIN32 56 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x)) 57 #else 58 #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) 59 #endif /* _WIN32 */ 60 61 #ifndef _WIN32 62 #include <sys/socket.h> 63 #include <netdb.h> 64 #endif 65 66 extern int optind; 67 68 int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0; 69 int show_etype = 0, show_addresses = 0, no_resolve = 0; 70 char *defname; 71 char *progname; 72 krb5_int32 now; 73 size_t timestamp_width; 74 75 krb5_context kcontext; 76 77 char * etype_string (krb5_enctype ); 78 void show_credential (krb5_creds *); 79 80 void do_ccache (char *); 81 void do_keytab (char *); 82 void printtime (time_t); 83 void one_addr (krb5_address *); 84 void fillit (FILE *, unsigned int, int); 85 void show_addr(krb5_address *a); 86 87 #ifdef KRB5_KRB4_COMPAT 88 void do_v4_ccache (char *); 89 #endif /* KRB5_KRB4_COMPAT */ 90 91 #define DEFAULT 0 92 #define CCACHE 1 93 #define KEYTAB 2 94 95 /* 96 * The reason we start out with got_k4 and got_k5 as zero (false) is 97 * so that we can easily add dynamic loading support for determining 98 * whether Kerberos 4 and Keberos 5 libraries are available 99 */ 100 101 static int got_k5 = 0; 102 static int got_k4 = 0; 103 104 static int default_k5 = 1; 105 #ifdef KRB5_KRB4_COMPAT 106 static int default_k4 = 1; 107 #else /* KRB5_KRB4_COMPAT */ 108 static int default_k4 = 0; 109 #endif /* KRB5_KRB4_COMPAT */ 110 111 static void usage() 112 { 113 #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available")) 114 115 fprintf(stderr, gettext("Usage: %s [-5] [-4] [-e]" 116 " [[-c] [-f] [-s] [-a [-n]]] " 117 "[-k [-t] [-K]] [name]\n"), progname); 118 fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5)); 119 fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4)); 120 fprintf(stderr, gettext("\t (Default is %s%s%s%s)\n"), 121 default_k5?"Kerberos 5":"", 122 (default_k5 && default_k4)?gettext(" and "):"", 123 default_k4?"Kerberos 4":"", 124 (!default_k5 && !default_k4)?gettext("neither"):""); 125 fprintf(stderr, gettext("\t-c specifies credentials cache\n")); 126 fprintf(stderr, gettext("\t-k specifies keytab\n")); 127 fprintf(stderr, gettext("\t (Default is credentials cache)\n")); 128 fprintf(stderr, gettext("\t-e shows the encryption type\n")); 129 fprintf(stderr, gettext("\toptions for credential caches:\n")); 130 fprintf(stderr, gettext("\t\t-f shows credentials flags\n")); 131 fprintf(stderr, gettext("\t\t-s sets exit status based on valid tgt existence\n")); 132 fprintf(stderr, gettext("\t\t-a displays the address list\n")); 133 fprintf(stderr, gettext("\t\t-n do not reverse-resolve\n")); 134 fprintf(stderr, gettext("\toptions for keytabs:\n")); 135 fprintf(stderr, gettext("\t\t-t shows keytab entry timestamps\n")); 136 fprintf(stderr, gettext("\t\t-K shows keytab entry DES keys\n")); 137 exit(1); 138 } 139 140 141 int 142 main(argc, argv) 143 int argc; 144 char **argv; 145 { 146 int c; 147 char *name; 148 int mode; 149 int use_k5 = 0, use_k4 = 0; 150 151 got_k5 = 1; 152 #ifdef KRB5_KRB4_COMPAT 153 got_k4 = 1; 154 #endif /* KRB5_KRB4_COMPAT */ 155 156 (void) setlocale(LC_ALL, ""); 157 158 #if !defined(TEXT_DOMAIN) 159 #define TEXT_DOMAIN "SYS_TEST" 160 #endif /* !TEXT_DOMAIN */ 161 162 (void) textdomain(TEXT_DOMAIN); 163 164 progname = GET_PROGNAME(argv[0]); 165 166 name = NULL; 167 mode = DEFAULT; 168 while ((c = getopt(argc, argv, "fetKsnack45")) != -1) { 169 switch (c) { 170 case 'f': 171 show_flags = 1; 172 break; 173 case 'e': 174 show_etype = 1; 175 break; 176 case 't': 177 show_time = 1; 178 break; 179 case 'K': 180 show_keys = 1; 181 break; 182 case 's': 183 status_only = 1; 184 break; 185 case 'n': 186 no_resolve = 1; 187 break; 188 case 'a': 189 show_addresses = 1; 190 break; 191 case 'c': 192 if (mode != DEFAULT) usage(); 193 mode = CCACHE; 194 break; 195 case 'k': 196 if (mode != DEFAULT) usage(); 197 mode = KEYTAB; 198 break; 199 case '4': 200 if (!got_k4) 201 { 202 #ifdef KRB5_KRB4_COMPAT 203 fprintf(stderr, "Kerberos 4 support could not be loaded\n"); 204 #else /* KRB5_KRB4_COMPAT */ 205 fprintf(stderr, gettext("This was not built with Kerberos 4 support\n")); 206 #endif /* KRB5_KRB4_COMPAT */ 207 exit(3); 208 } 209 use_k4 = 1; 210 break; 211 case '5': 212 if (!got_k5) 213 { 214 fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n")); 215 exit(3); 216 } 217 use_k5 = 1; 218 break; 219 default: 220 usage(); 221 break; 222 } 223 } 224 225 if (no_resolve && !show_addresses) { 226 usage(); 227 } 228 229 if (mode == DEFAULT || mode == CCACHE) { 230 if (show_time || show_keys) 231 usage(); 232 } else { 233 if (show_flags || status_only || show_addresses) 234 usage(); 235 } 236 237 if (argc - optind > 1) { 238 fprintf(stderr, 239 gettext("Extra arguments (starting with \"%s\").\n"), 240 argv[optind+1]); 241 usage(); 242 } 243 244 name = (optind == argc-1) ? argv[optind] : 0; 245 246 if (!use_k5 && !use_k4) 247 { 248 use_k5 = default_k5; 249 use_k4 = default_k4; 250 } 251 252 if (!use_k5) 253 got_k5 = 0; 254 if (!use_k4) 255 got_k4 = 0; 256 257 now = time(0); 258 { 259 char tmp[BUFSIZ]; 260 261 if (!krb5_timestamp_to_sfstring(now, tmp, 20, (char *) NULL) || 262 !krb5_timestamp_to_sfstring(now, tmp, sizeof(tmp), 263 (char *) NULL)) 264 timestamp_width = (int) strlen(tmp); 265 else 266 timestamp_width = 15; 267 } 268 269 if (got_k5) 270 { 271 krb5_error_code retval; 272 retval = krb5_init_context(&kcontext); 273 if (retval) { 274 com_err(progname, retval, gettext("while initializing krb5")); 275 exit(1); 276 } 277 278 if (mode == DEFAULT || mode == CCACHE) 279 do_ccache(name); 280 else 281 do_keytab(name); 282 } else { 283 #ifdef KRB5_KRB4_COMPAT 284 if (mode == DEFAULT || mode == CCACHE) 285 do_v4_ccache(name); 286 else { 287 /* We may want to add v4 srvtab support */ 288 fprintf(stderr, 289 "%s: srvtab option not supported for Kerberos 4\n", 290 progname); 291 exit(1); 292 } 293 #endif /* KRB4_KRB5_COMPAT */ 294 } 295 296 return 0; 297 } 298 299 void do_keytab(name) 300 char *name; 301 { 302 krb5_keytab kt; 303 krb5_keytab_entry entry; 304 krb5_kt_cursor cursor; 305 char buf[BUFSIZ]; /* hopefully large enough for any type */ 306 char *pname; 307 int code; 308 309 if (name == NULL) { 310 if ((code = krb5_kt_default(kcontext, &kt))) { 311 com_err(progname, code, 312 gettext("while getting default keytab")); 313 exit(1); 314 } 315 } else { 316 if ((code = krb5_kt_resolve(kcontext, name, &kt))) { 317 com_err(progname, code, 318 gettext("while resolving keytab %s"), 319 name); 320 exit(1); 321 } 322 } 323 324 if ((code = krb5_kt_get_name(kcontext, kt, buf, BUFSIZ))) { 325 com_err(progname, code, 326 gettext("while getting keytab name")); 327 exit(1); 328 } 329 330 printf(gettext("Keytab name: %s\n"), buf); 331 332 if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor))) { 333 com_err(progname, code, 334 gettext("while starting keytab scan")); 335 exit(1); 336 } 337 338 if (show_time) { 339 printf(gettext("KVNO Timestamp")); 340 fillit(stdout, timestamp_width - 341 sizeof (gettext("Timestamp")) + 2, (int)' '); 342 printf(gettext("Principal\n")); 343 printf("---- "); 344 fillit(stdout, timestamp_width, (int) '-'); 345 printf(" "); 346 fillit(stdout, 78 - timestamp_width - 347 sizeof (gettext("KVNO")), (int)'-'); 348 printf("\n"); 349 } else { 350 printf(gettext("KVNO Principal\n")); 351 printf("---- ------------------------------" 352 "--------------------------------------" 353 "------\n"); 354 } 355 356 while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0) { 357 if ((code = krb5_unparse_name(kcontext, entry.principal, &pname))) { 358 com_err(progname, code, 359 gettext("while unparsing principal name")); 360 exit(1); 361 } 362 printf("%4d ", entry.vno); 363 if (show_time) { 364 printtime(entry.timestamp); 365 printf(" "); 366 } 367 printf("%s", pname); 368 if (show_etype) 369 printf(" (%s) " , etype_string(entry.key.enctype)); 370 if (show_keys) { 371 printf(" (0x"); 372 { 373 int i; 374 for (i = 0; i < entry.key.length; i++) 375 printf("%02x", entry.key.contents[i]); 376 } 377 printf(")"); 378 } 379 printf("\n"); 380 krb5_free_unparsed_name(kcontext, pname); 381 } 382 if (code && code != KRB5_KT_END) { 383 com_err(progname, code, 384 gettext("while scanning keytab")); 385 exit(1); 386 } 387 if ((code = krb5_kt_end_seq_get(kcontext, kt, &cursor))) { 388 com_err(progname, code, 389 gettext("while ending keytab scan")); 390 exit(1); 391 } 392 exit(0); 393 } 394 void do_ccache(name) 395 char *name; 396 { 397 krb5_ccache cache = NULL; 398 krb5_cc_cursor cur; 399 krb5_creds creds; 400 krb5_principal princ; 401 krb5_flags flags; 402 krb5_error_code code; 403 int exit_status = 0; 404 405 if (status_only) 406 /* exit_status is set back to 0 if a valid tgt is found */ 407 exit_status = 1; 408 409 if (name == NULL) { 410 if ((code = krb5_cc_default(kcontext, &cache))) { 411 if (!status_only) 412 com_err(progname, code, 413 gettext("while getting default " 414 "ccache")); 415 exit(1); 416 } 417 } else { 418 if ((code = krb5_cc_resolve(kcontext, name, &cache))) { 419 if (!status_only) 420 com_err(progname, code, 421 gettext("while resolving ccache %s"), 422 name); 423 exit(1); 424 } 425 } 426 427 flags = 0; /* turns off OPENCLOSE mode */ 428 if ((code = krb5_cc_set_flags(kcontext, cache, flags))) { 429 if (code == KRB5_FCC_NOFILE) { 430 if (!status_only) { 431 com_err(progname, code, gettext("(ticket cache %s:%s)"), 432 krb5_cc_get_type(kcontext, cache), 433 krb5_cc_get_name(kcontext, cache)); 434 #ifdef KRB5_KRB4_COMPAT 435 if (name == NULL) 436 do_v4_ccache(0); 437 #endif /* KRB5_KRB4_COMPAT */ 438 } 439 } else { 440 if (!status_only) 441 com_err(progname, code, 442 gettext("while setting cache " 443 "flags(ticket cache %s:%s)"), 444 krb5_cc_get_type(kcontext, cache), 445 krb5_cc_get_name(kcontext, cache)); 446 } 447 exit(1); 448 } 449 if ((code = krb5_cc_get_principal(kcontext, cache, &princ))) { 450 if (!status_only) 451 com_err(progname, code, 452 gettext("while retrieving principal name")); 453 exit(1); 454 } 455 if ((code = krb5_unparse_name(kcontext, princ, &defname))) { 456 if (!status_only) 457 com_err(progname, code, 458 gettext("while unparsing principal name")); 459 exit(1); 460 } 461 if (!status_only) { 462 printf(gettext("Ticket cache: %s:%s\nDefault principal: " 463 "%s\n\n"), 464 krb5_cc_get_type(kcontext, cache), 465 krb5_cc_get_name(kcontext, cache), defname); 466 fputs(gettext("Valid starting"), stdout); 467 fillit(stdout, timestamp_width - 468 sizeof (gettext("Valid starting")) + 3, (int)' '); 469 fputs(gettext("Expires"), stdout); 470 fillit(stdout, timestamp_width - 471 sizeof (gettext("Expires")) + 3, (int)' '); 472 fputs(gettext("Service principal\n"), stdout); 473 } 474 if ((code = krb5_cc_start_seq_get(kcontext, cache, &cur))) { 475 if (!status_only) 476 com_err(progname, code, 477 gettext("while starting to retrieve tickets")); 478 exit(1); 479 } 480 while (!(code = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) { 481 if (status_only) { 482 if (exit_status && creds.server->length == 2 && 483 strcmp(creds.server->realm.data, 484 princ->realm.data) == 0 && 485 strcmp((char *)creds.server->data[0].data, 486 "krbtgt") == 0 && 487 strcmp((char *)creds.server->data[1].data, 488 princ->realm.data) == 0 && 489 creds.times.endtime > now) 490 exit_status = 0; 491 } else { 492 show_credential(&creds); 493 } 494 krb5_free_cred_contents(kcontext, &creds); 495 } 496 if (code == KRB5_CC_END) { 497 if ((code = krb5_cc_end_seq_get(kcontext, cache, &cur))) { 498 if (!status_only) 499 com_err(progname, code, 500 gettext("while finishing ticket " 501 "retrieval")); 502 exit(1); 503 } 504 flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */ 505 if ((code = krb5_cc_set_flags(kcontext, cache, flags))) { 506 if (!status_only) 507 com_err(progname, code, 508 gettext("while closing ccache")); 509 exit(1); 510 } 511 #ifdef KRB5_KRB4_COMPAT 512 if (name == NULL && !status_only) 513 do_v4_ccache(0); 514 #endif /* KRB5_KRB4_COMPAT */ 515 exit(exit_status); 516 } else { 517 if (!status_only) 518 com_err(progname, code, 519 gettext("while retrieving a ticket")); 520 exit(1); 521 } 522 } 523 524 char * 525 etype_string(enctype) 526 krb5_enctype enctype; 527 { 528 static char buf[256]; 529 krb5_error_code retval; 530 531 if ((retval = krb5_enctype_to_string(enctype, buf, sizeof(buf)))) { 532 /* XXX if there's an error != EINVAL, I should probably report it */ 533 snprintf(buf, sizeof(buf), gettext("unsupported encryption type %d"), enctype); 534 } 535 536 return buf; 537 } 538 539 static char * 540 flags_string(cred) 541 register krb5_creds *cred; 542 { 543 static char buf[32]; 544 int i = 0; 545 546 if (cred->ticket_flags & TKT_FLG_FORWARDABLE) 547 buf[i++] = 'F'; 548 if (cred->ticket_flags & TKT_FLG_FORWARDED) 549 buf[i++] = 'f'; 550 if (cred->ticket_flags & TKT_FLG_PROXIABLE) 551 buf[i++] = 'P'; 552 if (cred->ticket_flags & TKT_FLG_PROXY) 553 buf[i++] = 'p'; 554 if (cred->ticket_flags & TKT_FLG_MAY_POSTDATE) 555 buf[i++] = 'D'; 556 if (cred->ticket_flags & TKT_FLG_POSTDATED) 557 buf[i++] = 'd'; 558 if (cred->ticket_flags & TKT_FLG_INVALID) 559 buf[i++] = 'i'; 560 if (cred->ticket_flags & TKT_FLG_RENEWABLE) 561 buf[i++] = 'R'; 562 if (cred->ticket_flags & TKT_FLG_INITIAL) 563 buf[i++] = 'I'; 564 if (cred->ticket_flags & TKT_FLG_HW_AUTH) 565 buf[i++] = 'H'; 566 if (cred->ticket_flags & TKT_FLG_PRE_AUTH) 567 buf[i++] = 'A'; 568 if (cred->ticket_flags & TKT_FLG_TRANSIT_POLICY_CHECKED) 569 buf[i++] = 'T'; 570 if (cred->ticket_flags & TKT_FLG_OK_AS_DELEGATE) 571 buf[i++] = 'O'; /* D/d are taken. Use short strings? */ 572 if (cred->ticket_flags & TKT_FLG_ANONYMOUS) 573 buf[i++] = 'a'; 574 buf[i] = '\0'; 575 return(buf); 576 } 577 578 void 579 printtime(tv) 580 time_t tv; 581 { 582 char timestring[BUFSIZ]; 583 char fill; 584 585 fill = ' '; 586 if (!krb5_timestamp_to_sfstring((krb5_timestamp) tv, timestring, 587 timestamp_width+1, &fill)) { 588 printf(timestring); 589 } 590 } 591 592 void 593 show_credential(cred) 594 register krb5_creds * cred; 595 { 596 krb5_error_code retval; 597 krb5_ticket *tkt; 598 char *name, *sname, *flags; 599 int extra_field = 0; 600 601 retval = krb5_unparse_name(kcontext, cred->client, &name); 602 if (retval) { 603 com_err(progname, retval, 604 gettext("while unparsing client name")); 605 return; 606 } 607 retval = krb5_unparse_name(kcontext, cred->server, &sname); 608 if (retval) { 609 com_err(progname, retval, 610 gettext("while unparsing server name")); 611 krb5_free_unparsed_name(kcontext, name); 612 return; 613 } 614 if (!cred->times.starttime) 615 cred->times.starttime = cred->times.authtime; 616 617 printtime(cred->times.starttime); 618 putchar(' '); putchar(' '); 619 printtime(cred->times.endtime); 620 putchar(' '); putchar(' '); 621 622 printf("%s\n", sname); 623 624 if (strcmp(name, defname)) { 625 printf(gettext("\tfor client %s"), name); 626 extra_field++; 627 } 628 629 if (cred->times.renew_till) { 630 if (!extra_field) 631 fputs("\t",stdout); 632 else 633 fputs(", ",stdout); 634 fputs(gettext("renew until "), stdout); 635 printtime(cred->times.renew_till); 636 extra_field += 2; 637 } 638 639 if (extra_field > 3) { 640 fputs("\n", stdout); 641 extra_field = 0; 642 } 643 644 if (show_flags) { 645 flags = flags_string(cred); 646 if (flags && *flags) { 647 if (!extra_field) 648 fputs("\t",stdout); 649 else 650 fputs(", ",stdout); 651 printf(gettext("Flags: %s"), flags); 652 extra_field++; 653 } 654 } 655 656 if (extra_field > 2) { 657 fputs("\n", stdout); 658 extra_field = 0; 659 } 660 661 if (show_etype) { 662 retval = decode_krb5_ticket(&cred->ticket, &tkt); 663 if (retval) 664 goto err_tkt; 665 666 if (!extra_field) 667 fputs("\t",stdout); 668 else 669 fputs(", ",stdout); 670 printf(gettext("Etype(skey, tkt): %s, "), 671 etype_string(cred->keyblock.enctype)); 672 printf("%s ", 673 etype_string(tkt->enc_part.enctype)); 674 extra_field++; 675 676 err_tkt: 677 if (tkt != NULL) 678 krb5_free_ticket(kcontext, tkt); 679 } 680 681 /* if any additional info was printed, extra_field is non-zero */ 682 if (extra_field) 683 putchar('\n'); 684 685 686 if (show_addresses) { 687 if (!cred->addresses || !cred->addresses[0]) { 688 printf(gettext("\tAddresses: (none)\n")); 689 } else { 690 int i; 691 692 printf(gettext("\tAddresses: ")); 693 one_addr(cred->addresses[0]); 694 695 for (i=1; cred->addresses[i]; i++) { 696 printf(", "); 697 one_addr(cred->addresses[i]); 698 } 699 700 printf("\n"); 701 } 702 } 703 704 krb5_free_unparsed_name(kcontext, name); 705 krb5_free_unparsed_name(kcontext, sname); 706 } 707 708 #include "port-sockets.h" 709 #include "socket-utils.h" /* for ss2sin etc */ 710 #include <fake-addrinfo.h> 711 712 void one_addr(a) 713 krb5_address *a; 714 { 715 struct sockaddr_storage ss; 716 int err; 717 char namebuf[NI_MAXHOST]; 718 719 memset (&ss, 0, sizeof (ss)); 720 721 switch (a->addrtype) { 722 case ADDRTYPE_INET: 723 if (a->length != IPV4_ADDR_LEN) { 724 broken: 725 printf ("broken address (type %d length %d)", 726 a->addrtype, a->length); 727 return; 728 } 729 { 730 struct sockaddr_in *sinp = ss2sin (&ss); 731 sinp->sin_family = AF_INET; 732 #ifdef HAVE_SA_LEN 733 sinp->sin_len = sizeof (struct sockaddr_in); 734 #endif 735 memcpy (&sinp->sin_addr, a->contents, IPV4_ADDR_LEN); 736 } 737 break; 738 #ifdef KRB5_USE_INET6 739 case ADDRTYPE_INET6: 740 if (a->length != IPV6_ADDR_LEN) 741 goto broken; 742 { 743 struct sockaddr_in6 *sin6p = ss2sin6 (&ss); 744 sin6p->sin6_family = AF_INET6; 745 #ifdef HAVE_SA_LEN 746 sin6p->sin6_len = sizeof (struct sockaddr_in6); 747 #endif 748 memcpy (&sin6p->sin6_addr, a->contents, IPV6_ADDR_LEN); 749 } 750 break; 751 #endif 752 default: 753 printf(gettext("unknown addr type %d"), a->addrtype); 754 return; 755 } 756 757 namebuf[0] = 0; 758 err = getnameinfo (ss2sa (&ss), socklen (ss2sa (&ss)), 759 namebuf, sizeof (namebuf), 0, 0, 760 no_resolve ? NI_NUMERICHOST : 0U); 761 if (err) { 762 printf (gettext("unprintable address (type %d, error %d %s)"), a->addrtype, err, 763 gai_strerror (err)); 764 return; 765 } 766 printf ("%s", namebuf); 767 } 768 769 void 770 fillit(f, num, c) 771 FILE *f; 772 unsigned int num; 773 int c; 774 { 775 int i; 776 777 for (i=0; i<num; i++) 778 fputc(c, f); 779 } 780 781 #ifdef KRB5_KRB4_COMPAT 782 void 783 do_v4_ccache(name) 784 char * name; 785 { 786 char pname[ANAME_SZ]; 787 char pinst[INST_SZ]; 788 char prealm[REALM_SZ]; 789 char *file; 790 int k_errno; 791 CREDENTIALS c; 792 int header = 1; 793 794 if (!got_k4) 795 return; 796 797 file = name?name:tkt_string(); 798 799 if (status_only) { 800 fprintf(stderr, 801 "%s: exit status option not supported for Kerberos 4\n", 802 progname); 803 exit(1); 804 } 805 806 if (got_k5) 807 printf("\n\n"); 808 809 printf("Kerberos 4 ticket cache: %s\n", file); 810 811 /* 812 * Since krb_get_tf_realm will return a ticket_file error, 813 * we will call tf_init and tf_close first to filter out 814 * things like no ticket file. Otherwise, the error that 815 * the user would see would be 816 * klist: can't find realm of ticket file: No ticket file (tf_util) 817 * instead of 818 * klist: No ticket file (tf_util) 819 */ 820 821 /* Open ticket file */ 822 k_errno = tf_init(file, R_TKT_FIL); 823 if (k_errno) { 824 fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno)); 825 exit(1); 826 } 827 /* Close ticket file */ 828 (void) tf_close(); 829 830 /* 831 * We must find the realm of the ticket file here before calling 832 * tf_init because since the realm of the ticket file is not 833 * really stored in the principal section of the file, the 834 * routine we use must itself call tf_init and tf_close. 835 */ 836 if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) { 837 fprintf(stderr, "%s: can't find realm of ticket file: %s\n", 838 progname, krb_get_err_text (k_errno)); 839 exit(1); 840 } 841 842 /* Open ticket file */ 843 if ((k_errno = tf_init(file, R_TKT_FIL))) { 844 fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno)); 845 exit(1); 846 } 847 /* Get principal name and instance */ 848 if ((k_errno = tf_get_pname(pname)) || 849 (k_errno = tf_get_pinst(pinst))) { 850 fprintf(stderr, "%s: %s\n", progname, krb_get_err_text (k_errno)); 851 exit(1); 852 } 853 854 /* 855 * You may think that this is the obvious place to get the 856 * realm of the ticket file, but it can't be done here as the 857 * routine to do this must open the ticket file. This is why 858 * it was done before tf_init. 859 */ 860 861 printf("Principal: %s%s%s%s%s\n\n", pname, 862 (pinst[0] ? "." : ""), pinst, 863 (prealm[0] ? "@" : ""), prealm); 864 while ((k_errno = tf_get_cred(&c)) == KSUCCESS) { 865 if (header) { 866 printf("%-18s %-18s %s\n", 867 " Issued", " Expires", " Principal"); 868 header = 0; 869 } 870 printtime(c.issue_date); 871 fputs(" ", stdout); 872 printtime(krb_life_to_time(c.issue_date, c.lifetime)); 873 printf(" %s%s%s%s%s\n", 874 c.service, (c.instance[0] ? "." : ""), c.instance, 875 (c.realm[0] ? "@" : ""), c.realm); 876 } 877 if (header && k_errno == EOF) { 878 printf("No tickets in file.\n"); 879 } 880 } 881 #endif /* KRB4_KRB5_COMPAT */ 882