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