1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1991, 1999, 2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <ctype.h> 30 #include <sys/types.h> 31 #include <sys/errno.h> 32 #include <setjmp.h> 33 #include <string.h> 34 35 #include <netinet/in.h> 36 #include <rpc/types.h> 37 #include <rpc/rpc.h> 38 #include <rpc/xdr.h> 39 #include <rpc/auth.h> 40 #include <rpc/clnt.h> 41 #include <rpc/rpc_msg.h> 42 #include <rpcsvc/nis.h> 43 #include <rpcsvc/nis_callback.h> 44 45 #include "snoop.h" 46 #include "nis_clnt.h" 47 48 extern char *dlc_header; 49 extern jmp_buf xdr_err; 50 51 /* 52 * Number of spaces for each level of indentation. Since this value is 53 * assumed in most of the strings below, defining it is pretty quixotic. 54 */ 55 #define INDENT_SPACES 4 56 57 /* 58 * ==== Old (pre Sep '91) format for public keys in NIS+ directories, now 59 * removed from the header files. Should be removed from snoop once 60 * we're sure we won't see old-style packets 61 */ 62 #ifndef SZ_PKEY 63 #define SZ_PKEY 64 64 #endif /* SZ_PKEY */ 65 66 /* 67 * ==== New (Aug '91) NIS+ remote procedure, which hasn't made into our 68 * header files yet. When it does, nuke this stuff. 69 */ 70 #ifndef NIS_UPDKEYS 71 #define NIS_UPDKEYS 24 72 #endif /* NIS_UPDKEYS */ 73 74 /* 75 * ==== Constants for public keys. We should use NIS_MAXKEYLEN and the 76 * key-type constants from the NIS+ header files, but at present (Aug '91) 77 * we're ahead of the header files. 78 */ 79 #define KEYLEN_FIRST 0 80 #define KEYLEN_LIMIT 1024 81 #define KEYTYPE_FIRST 0 82 #define KEYTYPE_LIMIT 3 83 84 85 static char *procnames_short[] = { 86 "Null", /* 0 */ 87 "Lookup", /* 1 */ 88 "Add", /* 2 */ 89 "Modify", /* 3 */ 90 "Remove", /* 4 */ 91 "IBlist", /* 5 */ 92 "IBadd", /* 6 */ 93 "IBmodify", /* 7 */ 94 "IBremove", /* 8 */ 95 "IBfirst", /* 9 */ 96 "IBnext", /* 10 */ 97 "** Unused 11", /* 11 */ 98 "FindDir", /* 12 */ 99 "** Unused 13", /* 13 */ 100 "Status", /* 14 */ 101 "DumpLog", /* 15 */ 102 "Dump", /* 16 */ 103 "Callback", /* 17 */ 104 "CheckpointTime", /* 18 */ 105 "Checkpoint", /* 19 */ 106 "Ping", /* 20 */ 107 "ServerState", /* 21 */ 108 "MakeDir", /* 22 */ 109 "RemoveDir", /* 23 */ 110 "UpdateKeys", /* 24 */ 111 }; 112 113 static char *procnames_long[] = { 114 "Null procedure", /* 0 */ 115 "Lookup", /* 1 */ 116 "Add", /* 2 */ 117 "Modify", /* 3 */ 118 "Remove", /* 4 */ 119 "List IBase", /* 5 */ 120 "Add to IBase", /* 6 */ 121 "Modify IBase", /* 7 */ 122 "Remove from IBase", /* 8 */ 123 "IBase First Entry", /* 9 */ 124 "IBase Next Entry", /* 10 */ 125 "** 11 (Unused) **", /* 11 */ 126 "Find Directory", /* 12 */ 127 "** 13 (Unused) **", /* 13 */ 128 "Get/Reset Statistics", /* 14 */ 129 "Dump Directory Log", /* 15 */ 130 "Dump Directory Contents", /* 16 */ 131 "Check Callback Thread", /* 17 */ 132 "Get Checkpoint Time", /* 18 */ 133 "Establish Checkpoint", /* 19 */ 134 "Ping Replicas", /* 20 */ 135 "Change Server State", /* 21 */ 136 "Make Directory", /* 22 */ 137 "Remove Directory", /* 23 */ 138 "Update Public Keys", /* 24 */ 139 }; 140 141 #define MAXPROC 24 142 143 static void detail_bool(void); 144 static void detail_callback(void); 145 static void detail_cback_data(void); 146 static void detail_cookie(void); 147 static void detail_cp_result(void); 148 static void detail_cptime(void); 149 static void detail_dump_args(void); 150 static void detail_ib_request(void); 151 static void detail_fd_args(void); 152 static void detail_fd_result(void); 153 static void detail_log_entry(void); 154 static void detail_log_result(void); 155 static void detail_nis_attrs(int); 156 static void detail_nis_error(void); 157 static void detail_nis_name(void); 158 static void detail_nis_result(void); 159 static void detail_nis_taglist(void); 160 static void detail_ns_request(void); 161 static void detail_ping_args(void); 162 static int is_printable(char *, unsigned int); 163 static void sum_bool(char *); 164 static void sum_callback(char *); 165 static void sum_cback_data(char *); 166 static void sum_cp_result(char *); 167 static void sum_cptime(char *); 168 static void sum_dump_args(char *); 169 static void sum_ib_request(char *); 170 static void sum_fd_args(char *); 171 static void sum_fd_result(char *); 172 static void sum_log_result(char *); 173 static void sum_nis_error(char *); 174 static void sum_nis_name(char *); 175 static void sum_nis_result(char *); 176 static void sum_nis_taglist(char *); 177 static void sum_ns_request(char *); 178 static void sum_ping_args(char *); 179 180 void 181 interpret_nisplus(flags, type, xid, vers, proc, data, len) 182 int flags, type, xid, vers, proc; 183 char *data; 184 int len; 185 { 186 char *line; 187 188 if (proc < 0 || proc > MAXPROC) 189 return; 190 191 if (flags & F_SUM) { 192 if (setjmp(xdr_err)) { 193 return; 194 } 195 196 line = get_sum_line(); 197 198 if (type == CALL) { 199 (void) sprintf(line, 200 "NIS+ C %s", 201 procnames_short[proc]); 202 line += strlen(line); 203 204 switch (proc) { 205 case NIS_LOOKUP: 206 case NIS_ADD: 207 case NIS_MODIFY: 208 case NIS_REMOVE: 209 sum_ns_request(line); 210 break; 211 case NIS_IBLIST: 212 case NIS_IBADD: 213 case NIS_IBMODIFY: 214 case NIS_IBREMOVE: 215 case NIS_IBFIRST: 216 case NIS_IBNEXT: 217 sum_ib_request(line); 218 break; 219 case NIS_FINDDIRECTORY: 220 sum_fd_args(line); 221 break; 222 case NIS_STATUS: 223 case NIS_SERVSTATE: 224 sum_nis_taglist(line); 225 break; 226 case NIS_DUMPLOG: 227 case NIS_DUMP: 228 sum_dump_args(line); 229 break; 230 case NIS_CALLBACK: 231 sum_callback(line); 232 break; 233 case NIS_PING: 234 sum_ping_args(line); 235 break; 236 case NIS_CPTIME: 237 case NIS_CHECKPOINT: 238 case NIS_MKDIR: 239 case NIS_RMDIR: 240 case NIS_UPDKEYS: 241 sum_nis_name(line); 242 break; 243 default: 244 /* === mutter about bogus procnums? */ 245 break; 246 } 247 248 check_retransmit(line, xid); 249 } else { 250 (void) sprintf(line, "NIS+ R %s ", 251 procnames_short[proc]); 252 line += strlen(line); 253 switch (proc) { 254 case NIS_LOOKUP: 255 case NIS_ADD: 256 case NIS_MODIFY: 257 case NIS_REMOVE: 258 case NIS_IBLIST: 259 case NIS_IBADD: 260 case NIS_IBMODIFY: 261 case NIS_IBREMOVE: 262 case NIS_IBFIRST: 263 case NIS_IBNEXT: 264 sum_nis_result(line); 265 break; 266 case NIS_FINDDIRECTORY: 267 sum_fd_result(line); 268 break; 269 case NIS_STATUS: 270 case NIS_SERVSTATE: 271 sum_nis_taglist(line); 272 break; 273 case NIS_DUMPLOG: 274 case NIS_DUMP: 275 sum_log_result(line); 276 break; 277 case NIS_CALLBACK: 278 sum_bool(line); 279 break; 280 case NIS_CPTIME: 281 sum_cptime(line); 282 break; 283 case NIS_CHECKPOINT: 284 sum_cp_result(line); 285 break; 286 case NIS_PING: 287 break; 288 case NIS_MKDIR: 289 case NIS_RMDIR: 290 case NIS_UPDKEYS: 291 sum_nis_error(line); 292 break; 293 default: 294 /* === mutter about bogus procnums? */ 295 break; 296 } 297 } 298 } 299 300 if (flags & F_DTAIL) { 301 show_header("NIS+: ", "NIS+ Name Service", len); 302 show_space(); 303 if (setjmp(xdr_err)) { 304 return; 305 } 306 (void) sprintf(get_line(0, 0), 307 "Proc = %d (%s)", 308 proc, procnames_long[proc]); 309 310 if (type == CALL) { 311 switch (proc) { 312 case NIS_LOOKUP: 313 case NIS_ADD: 314 case NIS_MODIFY: 315 case NIS_REMOVE: 316 detail_ns_request(); 317 break; 318 case NIS_IBLIST: 319 case NIS_IBADD: 320 case NIS_IBMODIFY: 321 case NIS_IBREMOVE: 322 case NIS_IBFIRST: 323 case NIS_IBNEXT: 324 detail_ib_request(); 325 break; 326 case NIS_FINDDIRECTORY: 327 detail_fd_args(); 328 break; 329 case NIS_STATUS: 330 case NIS_SERVSTATE: 331 detail_nis_taglist(); 332 break; 333 case NIS_DUMPLOG: 334 case NIS_DUMP: 335 detail_dump_args(); 336 break; 337 case NIS_CALLBACK: 338 detail_callback(); 339 break; 340 case NIS_PING: 341 detail_ping_args(); 342 break; 343 case NIS_CPTIME: 344 case NIS_CHECKPOINT: 345 case NIS_MKDIR: 346 case NIS_RMDIR: 347 case NIS_UPDKEYS: 348 detail_nis_name(); 349 break; 350 default: 351 /* === mutter about bogus procnums? */ 352 break; 353 } 354 } else { 355 switch (proc) { 356 case NIS_LOOKUP: 357 case NIS_ADD: 358 case NIS_MODIFY: 359 case NIS_REMOVE: 360 case NIS_IBLIST: 361 case NIS_IBADD: 362 case NIS_IBMODIFY: 363 case NIS_IBREMOVE: 364 case NIS_IBFIRST: 365 case NIS_IBNEXT: 366 detail_nis_result(); 367 break; 368 case NIS_FINDDIRECTORY: 369 detail_fd_result(); 370 break; 371 case NIS_STATUS: 372 case NIS_SERVSTATE: 373 detail_nis_taglist(); 374 break; 375 case NIS_DUMPLOG: 376 case NIS_DUMP: 377 detail_log_result(); 378 break; 379 case NIS_CALLBACK: 380 detail_bool(); 381 break; 382 case NIS_CPTIME: 383 detail_cptime(); 384 break; 385 case NIS_CHECKPOINT: 386 detail_cp_result(); 387 break; 388 case NIS_PING: 389 break; 390 case NIS_MKDIR: 391 case NIS_RMDIR: 392 case NIS_UPDKEYS: 393 detail_nis_error(); 394 break; 395 default: 396 /* === mutter about bogus procnums? */ 397 break; 398 } 399 } 400 401 show_trailer(); 402 } 403 } 404 405 static char *cbnames_short[] = { 406 "Null", /* 0 */ 407 "Receive", /* 1 */ 408 "Finish", /* 2 */ 409 "Error", /* 3 */ 410 }; 411 412 static char *cbnames_long[] = { 413 "Null procedure", /* 0 */ 414 "Receive Callback Data", /* 1 */ 415 "Finish Callback", /* 2 */ 416 "Callback Error", /* 3 */ 417 }; 418 419 void 420 interpret_nisp_cb(flags, type, xid, vers, proc, data, len) 421 int flags, type, xid, vers, proc; 422 char *data; 423 int len; 424 { 425 char *line; 426 427 if (flags & F_SUM) { 428 if (setjmp(xdr_err)) { 429 return; 430 } 431 432 line = get_sum_line(); 433 434 if (type == CALL) { 435 (void) sprintf(line, 436 "NIS+ Callback C %s", 437 cbnames_short[proc]); 438 line += strlen(line); 439 440 switch (proc) { 441 case CBPROC_RECEIVE: 442 sum_cback_data(line); 443 break; 444 case CBPROC_FINISH: 445 /* void: nothing to do */ 446 break; 447 case CBPROC_ERROR: 448 sum_nis_error(line); 449 break; 450 default: 451 /* === mutter about bogus procnums? */ 452 break; 453 } 454 455 check_retransmit(line, xid); 456 } else { 457 (void) sprintf(line, "NIS+ Callback R %s ", 458 cbnames_short[proc]); 459 line += strlen(line); 460 switch (proc) { 461 case CBPROC_RECEIVE: 462 sum_bool(line); 463 break; 464 case CBPROC_FINISH: 465 case CBPROC_ERROR: 466 /* void: nothing to do */ 467 break; 468 default: 469 /* === mutter about bogus procnums? */ 470 break; 471 } 472 } 473 } 474 475 if (flags & F_DTAIL) { 476 show_header("NIS+ CB: ", "NIS+ Name Service Callback", len); 477 show_space(); 478 if (setjmp(xdr_err)) { 479 return; 480 } 481 (void) sprintf(get_line(0, 0), 482 "Proc = %d (%s)", 483 proc, cbnames_long[proc]); 484 485 if (type == CALL) { 486 switch (proc) { 487 case CBPROC_RECEIVE: 488 detail_cback_data(); 489 break; 490 case CBPROC_FINISH: 491 /* void: nothing to do */ 492 break; 493 case CBPROC_ERROR: 494 detail_nis_error(); 495 break; 496 default: 497 /* === mutter about bogus procnums? */ 498 break; 499 } 500 } else { 501 switch (proc) { 502 case CBPROC_RECEIVE: 503 detail_bool(); 504 break; 505 case CBPROC_FINISH: 506 case CBPROC_ERROR: 507 /* void: nothing to do */ 508 break; 509 default: 510 /* === mutter about bogus procnums? */ 511 break; 512 } 513 } 514 515 show_trailer(); 516 } 517 } 518 519 /* 520 * stringof_XXX() routines -- return printable representations of various 521 * numeric values. Would be nice if we could get this from the NIS+ 522 * library instead of reinventing them. 523 * N.B. Mucho use of pointer-to-static result types (ugh); don't expect the 524 * return value to stay good for long. 525 */ 526 527 #ifndef RIGHTS_FORMAT 528 #define RIGHTS_FORMAT 1 529 #endif /* RIGHTS_FORMAT */ 530 531 static struct { 532 int shift; 533 char *name; 534 } rightsclasses[] = { 535 #if RIGHTS_FORMAT == 1 536 24, "", 537 16, "", 538 8, "", 539 0, "", 540 #elif RIGHTS_FORMAT == 2 541 16, "o:", 542 8, "g:", 543 0, "w:", 544 24, "u:", 545 #else /* RIGHTS_FORMAT == 3 */ 546 16, "owner:", 547 8, "group:", 548 0, "world:", 549 24, "unauth:", 550 #endif /* RIGHTS_FORMAT */ 551 }; 552 553 char * 554 stringof_rights(rights) 555 unsigned rights; 556 { 557 static char rightsbuf[100]; 558 char *p; 559 int i; 560 561 sprintf(rightsbuf, "%08x (", rights); 562 p = rightsbuf + strlen(rightsbuf); 563 564 for (i = 0; i < 4; i++) { 565 int shift = rightsclasses[i].shift; 566 strcpy(p, rightsclasses[i].name); 567 p += strlen(p); 568 *p++ = (rights >> shift) & NIS_READ_ACC ? 'r' : '-'; 569 *p++ = (rights >> shift) & NIS_MODIFY_ACC ? 'm' : '-'; 570 *p++ = (rights >> shift) & NIS_CREATE_ACC ? 'c' : '-'; 571 *p++ = (rights >> shift) & NIS_DESTROY_ACC ? 'd' : '-'; 572 *p++ = ' '; 573 rights &= ~((NIS_READ_ACC | NIS_MODIFY_ACC | 574 NIS_CREATE_ACC | NIS_DESTROY_ACC) << shift); 575 } 576 if (rights == 0) { 577 p[-1] = ')'; /* Nuke that last space */ 578 p[ 0] = 0; 579 } else { 580 sprintf(p, "+ Unknown bits: %08x **)", rights); 581 } 582 return (rightsbuf); 583 } 584 585 char * 586 stringof_ib_flags(flags) 587 unsigned flags; 588 { 589 static char flagsbuf[120]; 590 591 if (flags == 0) { 592 sprintf(flagsbuf, "%08x", flags); 593 return (flagsbuf); 594 } 595 sprintf(flagsbuf, 596 "%08x (%s%s%s%s", 597 flags, 598 flags & MOD_SAMEOBJ ? "MOD_SAMEOBJ, " : "", 599 flags & REM_MULTIPLE ? "REM_MULTIPLE, " : "", 600 flags & ADD_OVERWRITE ? "ADD_OVERWRITE, " : "", 601 flags & RETURN_RESULT ? "RETURN_RESULT, " : ""); 602 flags &= ~(MOD_SAMEOBJ | REM_MULTIPLE | ADD_OVERWRITE | RETURN_RESULT); 603 if (flags != 0) { 604 sprintf(flagsbuf + strlen(flagsbuf), 605 "** Unknown bits %08x **, ", flags); 606 } 607 /* Replace the trailing ", " with ")" */ 608 sprintf(flagsbuf + strlen(flagsbuf) - 2, ")"); 609 return (flagsbuf); 610 } 611 612 char * 613 stringof_colflags(flags) 614 unsigned flags; 615 { 616 static char flagsbuf[120]; 617 618 if (flags == 0) { 619 sprintf(flagsbuf, "%08x", flags); 620 return (flagsbuf); 621 } 622 sprintf(flagsbuf, 623 "%08x (%s%s%s%s%s", 624 flags, 625 flags & TA_CASE ? "Case-insensitive, " : "", 626 flags & TA_SEARCHABLE ? "Searchable, " : "", 627 flags & TA_XDR ? "XDR Encoded, " : "", 628 flags & TA_CRYPT ? "Encrypted, " : "", 629 flags & TA_BINARY ? "Binary, " : ""); 630 flags &= ~(TA_CASE | TA_SEARCHABLE | TA_XDR | TA_CRYPT | TA_BINARY); 631 if (flags != 0) { 632 sprintf(flagsbuf + strlen(flagsbuf), 633 "** Unknown bits %08x **, ", flags); 634 } 635 /* Replace the trailing ", " with ")" */ 636 sprintf(flagsbuf + strlen(flagsbuf) - 2, ")"); 637 return (flagsbuf); 638 } 639 640 char * 641 stringof_entryflags(flags) 642 unsigned flags; 643 { 644 static char flagsbuf[100]; 645 646 if (flags == 0) { 647 sprintf(flagsbuf, "%08x", flags); 648 return (flagsbuf); 649 } 650 sprintf(flagsbuf, 651 "%08x (%s%s%s%s", 652 flags, 653 flags & EN_MODIFIED ? "Modified, " : "", 654 flags & EN_XDR ? "XDR Encoded, " : "", 655 flags & EN_CRYPT ? "Encrypted, " : "", 656 flags & EN_BINARY ? "Binary, " : ""); 657 flags &= ~(EN_MODIFIED | EN_XDR | EN_CRYPT | EN_BINARY); 658 if (flags != 0) { 659 sprintf(flagsbuf + strlen(flagsbuf), 660 "** Unknown bits %08x **, ", flags); 661 } 662 /* Replace the trailing ", " with ")" */ 663 sprintf(flagsbuf + strlen(flagsbuf) - 2, ")"); 664 return (flagsbuf); 665 } 666 667 char * 668 stringof_groupflags(flags) 669 unsigned flags; 670 { 671 static char flagsbuf[80]; 672 673 if (flags == 0) { 674 sprintf(flagsbuf, "%08x", flags); 675 return (flagsbuf); 676 } 677 sprintf(flagsbuf, 678 "%08x (%s%s%s", 679 flags, 680 flags & NEGMEM_GROUPS ? "Negative, " : "", 681 flags & RECURS_GROUPS ? "Recursive, " : "", 682 flags & IMPMEM_GROUPS ? "Implicit, " : ""); 683 flags &= ~(NEGMEM_GROUPS | RECURS_GROUPS | IMPMEM_GROUPS); 684 if (flags != 0) { 685 sprintf(flagsbuf + strlen(flagsbuf), 686 "** Unknown bits %08x **, ", flags); 687 } 688 /* Replace the trailing ", " with ")" */ 689 sprintf(flagsbuf + strlen(flagsbuf) - 2, ")"); 690 return (flagsbuf); 691 } 692 693 char * 694 stringof_tag(ttype) 695 int ttype; 696 { 697 switch (ttype) { 698 case TAG_DEBUG: return ("DEBUG"); 699 case TAG_STATS: return ("STATS"); 700 case TAG_GCACHE: return ("GCACHE"); 701 case TAG_DCACHE: return ("DCACHE"); 702 case TAG_OCACHE: return ("OCACHE"); 703 case TAG_SECURE: return ("SECURE"); 704 705 #ifdef undef 706 /* 707 * Old tags, removed September '91 (some of the tag-numbers have been 708 * reassigned, just to make things completely confusing). 709 */ 710 case TAG_LOOKUPS: return ("LOOKUPS"; 711 case TAG_S_LOOKUPS: return ("S_LOOKUPS"; 712 case TAG_U_LOOKUPS: return ("U_LOOKUPS"; 713 #endif /* undef */ 714 case TAG_OPSTATS: return ("OPSTATS"); 715 case TAG_THREADS: return ("THREADS"); 716 case TAG_UPDATES: return ("UPDATES"); 717 case TAG_VISIBLE: return ("VISIBLE"); 718 case TAG_S_DCACHE: return ("S_DCACHE"); 719 case TAG_S_OCACHE: return ("S_OCACHE"); 720 case TAG_S_GCACHE: return ("S_GCACHE"); 721 case TAG_S_STORAGE: return ("S_STORAGE"); 722 723 default: return ("*Unknown*"); 724 } 725 } 726 727 char * 728 stringof_otype(otype) 729 int otype; 730 { 731 static char buf[30]; 732 733 switch (otype) { 734 case NIS_BOGUS_OBJ: return ("BOGUS (uninitialized?)"); 735 case NIS_NO_OBJ: return ("NULL"); 736 case NIS_DIRECTORY_OBJ: return ("DIRECTORY"); 737 case NIS_GROUP_OBJ: return ("GROUP"); 738 case NIS_TABLE_OBJ: return ("TABLE"); 739 case NIS_ENTRY_OBJ: return ("ENTRY"); 740 case NIS_LINK_OBJ: return ("LINK"); 741 case NIS_PRIVATE_OBJ: return ("PRIVATE"); 742 default: sprintf(buf, "** Unknown (%d) **", otype); 743 return (buf); 744 } 745 } 746 747 char * 748 stringof_entry_t(et) 749 int et; 750 { 751 static char buf[30]; 752 753 switch (et) { 754 case LOG_NOP: return ("LOG_NOP"); /* === lowercase? */ 755 case ADD_NAME: return ("ADD_NAME"); 756 case REM_NAME: return ("REM_NAME"); 757 case MOD_NAME_OLD: return ("MOD_NAME_OLD"); 758 case MOD_NAME_NEW: return ("MOD_NAME_NEW"); 759 case ADD_IBASE: return ("ADD_IBASE"); 760 case REM_IBASE: return ("REM_IBASE"); 761 case MOD_IBASE: return ("MOD_IBASE"); 762 case UPD_STAMP: return ("UPD_STAMP"); 763 default: sprintf(buf, "** Unknown (%d) **", et); 764 return (buf); 765 } 766 } 767 768 char * 769 stringof_ktype(ktype) 770 unsigned ktype; 771 { 772 static char buf[40]; 773 char *p; 774 775 sprintf(buf, "%d ", ktype); 776 p = buf + strlen(buf); 777 switch (ktype) { 778 case 0: strcpy(p, "(None)"); break; 779 case 1: strcpy(p, "(Diffie-Hellman)"); break; 780 case 2: strcpy(p, "(RSA)"); break; 781 case 4: strcpy(p, "(Diffie-Hellman Ext)"); break; 782 default: strcpy(p, "(** Unknown **)"); break; 783 } 784 return (buf); 785 } 786 787 static void 788 sumxdr_nis_name(line) 789 char *line; 790 { 791 char buff[NIS_MAXNAMELEN + 1]; 792 793 (void) sprintf(line, " \"%s\"", getxdr_string(buff, NIS_MAXNAMELEN)); 794 /* ==== ? could/should truncate long names a la showxdr_string() ? */ 795 } 796 797 static unsigned 798 sumxdr_nis_error(line) 799 char *line; 800 { 801 unsigned err = getxdr_u_long(); 802 sprintf(line, "[%s]", nis_sperrno(err)); 803 return (err); 804 } 805 806 static void 807 sum_ns_request(line) 808 char *line; 809 { 810 sumxdr_nis_name(line); 811 /* Leave the optional object for detailed listings */ 812 } 813 814 int nchars_attrval = 32; 815 816 static void 817 sum_ib_request(line) 818 char *line; 819 { 820 unsigned long nattrs; 821 unsigned long len; 822 int pos; 823 char *val; 824 char buff[NIS_MAXATTRNAME + 1]; 825 826 sumxdr_nis_name(line); 827 line += strlen(line); 828 nattrs = getxdr_u_long(); 829 switch (nattrs) { 830 case 0: 831 /* === Could print "No attrs " */ 832 break; 833 case 1: 834 sprintf(line, " [%s = ", getxdr_string(buff, NIS_MAXATTRNAME)); 835 line += strlen(line); 836 pos = getxdr_pos(); 837 val = getxdr_bytes((uint_t *)&len); 838 if (is_printable(val, len)) { 839 if (len - 1 > nchars_attrval) { 840 sprintf(line, "(%d-character value)", len); 841 } else { 842 sprintf(line, "\"%s\"", val); 843 } 844 } else { 845 if ((len - 1) * 2 > nchars_attrval) { 846 sprintf(line, "(%d-byte value)", len); 847 } else { 848 /* 849 * Too lazy to print hex ourselves; instead, 850 * back up and use snoop's hex-printer 851 */ 852 setxdr_pos(pos); 853 len = getxdr_u_long(); /* Yes, we did know it */ 854 strcpy(line, getxdr_hex(len)); 855 } 856 } 857 line += strlen(line); 858 *line++ = ']'; 859 *line = 0; 860 break; 861 default: 862 sprintf(line, " (Num attrs = %lu)", nattrs); 863 /* === Note that we haven't skipped the attrs */ 864 break; 865 } 866 /* === Don't bother with flags, obj, cbhost, bufsize, cookie */ 867 } 868 869 static void 870 sum_fd_args(line) 871 char *line; 872 { 873 sumxdr_nis_name(line); 874 #ifdef LESS_TERSE 875 strcat(line, " for"); 876 sumxdr_nis_name(line + strlen(line)); 877 #endif /* LESS_TERSE */ 878 } 879 880 #define MAXTAGLEN 1024 /* num chars of tag to display */ 881 882 static void 883 sum_nis_taglist(line) 884 char *line; 885 { 886 char buff[MAXTAGLEN + 1]; 887 unsigned ntags; 888 unsigned ttype; 889 890 ntags = getxdr_u_long(); 891 if (ntags == 0) { 892 strcpy(line, " [But no tags !?]"); 893 return; 894 } 895 ttype = getxdr_u_long(); 896 sprintf(line, 897 " %s=\"%s\"", stringof_tag(ttype), 898 getxdr_string(buff, MAXTAGLEN)); 899 if (ntags > 1) { 900 sprintf(line + strlen(line), " [and %lu more tags]", ntags - 1); 901 } 902 } 903 904 static void 905 sum_dump_args(line) 906 char *line; 907 { 908 sumxdr_nis_name(line); 909 strcat(line, " from "); 910 strcat(line, getxdr_time()); 911 } 912 913 /*ARGSUSED*/ 914 static void 915 sum_callback(line) /* i.e. the netobj argument to NIS_CALLBACK */ 916 char *line; 917 { 918 /* netobjs are pretty opaque, so don't try to summarize */ 919 } 920 921 static void 922 sum_ping_args(line) 923 char *line; 924 { 925 sumxdr_nis_name(line); 926 strcat(line, " at "); 927 strcat(line, getxdr_time()); 928 } 929 930 static void 931 sum_nis_name(line) 932 char *line; 933 { 934 sumxdr_nis_name(line); 935 } 936 937 static void 938 sum_cback_data(line) 939 char *line; 940 { 941 (void) sprintf(line, " (%lu entries)", getxdr_u_long()); 942 } 943 944 static void 945 sum_nis_result(line) 946 char *line; 947 { 948 unsigned nobjs; 949 950 (void) sumxdr_nis_error(line); 951 nobjs = getxdr_u_long(); 952 if (nobjs != 0) { 953 sprintf(line + strlen(line), 954 " and %lu object%s", nobjs, (nobjs == 1) ? "" : "s"); 955 } 956 } 957 958 static void 959 sum_fd_result(line) 960 char *line; 961 { 962 (void) sumxdr_nis_error(line); 963 #ifdef LESS_TERSE 964 strcat(line, " from"); 965 sumxdr_nis_name(line + strlen(line)); 966 #endif /* LESS_TERSE */ 967 } 968 969 static void 970 sum_log_result(line) 971 char *line; 972 { 973 uint_t dummy; 974 unsigned nents; 975 976 (void) sumxdr_nis_error(line); 977 (void) getxdr_bytes(&dummy); /* Skip netobj lr_cookie */ 978 nents = getxdr_u_long(); 979 sprintf(line + strlen(line), 980 " and %lu log entr%s", nents, (nents == 1) ? "y" : "ies"); 981 } 982 983 static void 984 sum_bool(line) 985 char *line; 986 { 987 (void) sprintf(line, getxdr_u_long() ? "true" : "false"); 988 } 989 990 static void 991 sum_cptime(line) 992 char *line; 993 { 994 (void) sprintf(line, " %s", getxdr_time()); 995 } 996 997 static void 998 sum_cp_result(line) 999 char *line; 1000 { 1001 (void) sumxdr_nis_error(line); 1002 } 1003 1004 static void 1005 sum_nis_error(line) 1006 char *line; 1007 { 1008 (void) sumxdr_nis_error(line); 1009 } 1010 1011 #define SHOW_NIS_NAME(format) (void) showxdr_string(NIS_MAXNAMELEN, format) 1012 #define SHOW_NAME() SHOW_NIS_NAME("Name = %s") 1013 1014 /* 1015 * showxdr_longhex() -- ersatz wrapper around showxdr_hex() to ensure we 1016 * don't display too much on one line. Multi-line results will 1017 * === probably look pretty awful, but we may at least prevent core-dumps 1018 */ 1019 int nwords_longhex = 8; 1020 1021 static void 1022 showxdr_longhex(len, fmt) 1023 int len; 1024 char *fmt; 1025 { 1026 int nbytes_longhex = 4 * nwords_longhex; 1027 1028 while (len > nbytes_longhex) { 1029 showxdr_hex(nbytes_longhex, fmt); 1030 len -= nbytes_longhex; 1031 } 1032 showxdr_hex(len, fmt); 1033 } 1034 1035 static void 1036 detail_nis_error() 1037 { 1038 enum nis_error status; 1039 int pos; 1040 1041 pos = getxdr_pos(); 1042 status = (enum nis_error) getxdr_u_long(); 1043 sprintf(get_line(pos, getxdr_pos()), 1044 "Status = %lu (%s)", status, nis_sperrno(status)); 1045 } 1046 1047 void 1048 detail_nis_oid() 1049 { 1050 showxdr_time(" Object created at %s"); 1051 showxdr_time(" last modified at %s"); 1052 } 1053 1054 static void 1055 detail_nis_server(outdent) 1056 int outdent; /* Crock to get indentation right. Normally zero; */ 1057 /* set to four instead to remove leading spaces */ 1058 { 1059 unsigned nep; 1060 unsigned ktype; 1061 int pos1; 1062 1063 SHOW_NIS_NAME(outdent + " Hostname = %s"); 1064 nep = getxdr_u_long(); 1065 while (nep-- > 0) { /* list of endpoints */ 1066 (void) showxdr_string(1024, 1067 outdent + " Uaddr = %s"); 1068 (void) showxdr_string(1024, 1069 outdent + " Family = %s"); 1070 (void) showxdr_string(1024, 1071 outdent + " Protocol = %s"); 1072 } 1073 /* 1074 * The format of the public-key information has changed (Aug '91). 1075 * Ye olde style was a u_char[64] (which XDR's pretty inefficiently, 1076 * but that's another matter). The new format has a key-type 1077 * enumeration followed by an opaque<NIS_MAXKEYLEN>. For now 1078 * (hence probably for all time) we'll hard-code the values of the 1079 * enumeration and of NIS_MAXKEYLEN here rather than getting them 1080 * from a header file. Tsk. Also for now, we'll try to guess 1081 * whether we're looking at the new format or the old. 1082 */ 1083 pos1 = getxdr_pos(); 1084 ktype = getxdr_u_long(); 1085 if (ktype < KEYTYPE_LIMIT || ktype == NIS_PK_DHEXT) { 1086 int pos2; 1087 unsigned klen; 1088 1089 pos2 = getxdr_pos(); 1090 klen = getxdr_u_long(); 1091 if (klen < KEYLEN_LIMIT) { 1092 /* 1093 * Smells like new-style key; let's hope so. If we're 1094 * wrong, it may cause XDR underflow. Ugh. ==== 1095 */ 1096 sprintf(get_line(pos1, pos2), 1097 outdent + " Key type = %s", 1098 stringof_ktype(ktype)); 1099 sprintf(get_line(pos2, getxdr_pos()), 1100 outdent + " Key length = %lu", klen); 1101 if (klen != 0) { 1102 if (ktype == NIS_PK_DHEXT) { 1103 int marker; 1104 int key_count; 1105 marker = getxdr_pos(); 1106 key_count = 1; 1107 while (getxdr_pos() < marker + klen) { 1108 ulong_t a_u_long; 1109 ushort_t keylen; 1110 ushort_t algtype; 1111 size_t binlen; 1112 size_t binpadlen; 1113 1114 a_u_long = getxdr_u_long(); 1115 keylen = a_u_long >> 16; 1116 algtype = a_u_long & 1117 ((ushort_t)0xffff); 1118 binlen = (keylen + 7) / 8; 1119 binpadlen = ((binlen + 3) / 4) 1120 * 4; 1121 sprintf(get_line(0, 0), 1122 " Key %d length = %hu bits", 1123 key_count, keylen); 1124 sprintf(get_line(0, 0), 1125 " Algorithm type = %hu", 1126 algtype); 1127 if (keylen != 0) 1128 showxdr_hex(binpadlen, 1129 " Key value = %s"); 1130 key_count++; 1131 } 1132 setxdr_pos(marker + klen); 1133 } else { 1134 showxdr_hex(klen, outdent + 1135 " Key value = %s"); 1136 } 1137 } 1138 return; 1139 } 1140 } 1141 /* 1142 * It didn't smell new, so assume it's the old u_char[64], which 1143 * XDR's as 64 32-bit words (ouch). 1144 */ 1145 setxdr_pos(4*SZ_PKEY + pos1); 1146 sprintf(get_line(pos1, getxdr_pos()), 1147 outdent + " [Public Key not displayed]"); 1148 } 1149 1150 void 1151 detail_directory_obj() 1152 { 1153 unsigned nstyp; 1154 unsigned nserv, nar; 1155 int pos; 1156 char *line; 1157 1158 SHOW_NIS_NAME(" Name = %s"); 1159 pos = getxdr_pos(); 1160 nstyp = getxdr_u_long(); 1161 line = get_line(pos, getxdr_pos()); 1162 (void) sprintf(line, " NStype = %lu", nstyp); 1163 line += strlen(line); 1164 1165 switch (nstyp) { 1166 case NIS: 1167 sprintf(line, " (NIS+)"); 1168 break; 1169 case SUNYP: 1170 sprintf(line, " (NIS/YP)"); 1171 break; 1172 case DNS: 1173 sprintf(line, " (DNS)"); 1174 break; 1175 default: 1176 break; 1177 } 1178 1179 nserv = showxdr_u_long(" Servers = %lu"); 1180 while (nserv-- > 0) { /* array of servers */ 1181 detail_nis_server(0); 1182 } 1183 (void) showxdr_u_long(" Time to live = %lu (seconds)"); 1184 /* === show time in more useful form too? */ 1185 nar = showxdr_u_long(" Access Rights = %lu"); 1186 while (nar-- > 0) { /* list of ar masks */ 1187 unsigned ar, otype; 1188 pos = getxdr_pos(); 1189 ar = getxdr_u_long(); 1190 otype = getxdr_u_long(); 1191 sprintf(get_line(pos, getxdr_pos()), " %s for %s", 1192 stringof_rights(ar), stringof_otype(otype)); 1193 } 1194 } 1195 1196 void 1197 detail_group_obj() 1198 { 1199 unsigned val; 1200 int pos; 1201 1202 pos = getxdr_pos(); 1203 val = getxdr_u_long(); 1204 sprintf(get_line(pos, getxdr_pos()), 1205 " Flags = %s", stringof_groupflags(val)); 1206 val = showxdr_u_long(" Number of Members = %lu"); 1207 while (val-- > 0) { 1208 SHOW_NIS_NAME(" %s"); 1209 } 1210 } 1211 1212 void 1213 detail_table_obj() 1214 { 1215 unsigned ncols; 1216 unsigned col; 1217 (void) showxdr_string(1024, " Table Type = %s"); 1218 (void) showxdr_long (" Max Columns = %d"); 1219 (void) showxdr_char (" Separator = '%c'"); /* ==== improve */ 1220 ncols = showxdr_u_long(" Num Columns = %lu"); 1221 for (col = 1; col <= ncols; col++) { 1222 int pos1, pos2; 1223 unsigned val; 1224 char format[23]; 1225 /* === Print all three on one line? */ 1226 sprintf(format, "%6d: ColName = \"%%s\"", col); 1227 (void) showxdr_string(NIS_MAXATTRNAME, format); 1228 pos1 = getxdr_pos(); 1229 val = getxdr_u_long(); 1230 pos2 = getxdr_pos(); 1231 sprintf(get_line(pos1, pos2), 1232 " Flags = %s", stringof_colflags(val)); 1233 val = getxdr_u_long(); 1234 sprintf(get_line(pos2, getxdr_pos()), 1235 " Rights = %s", stringof_rights(val)); 1236 } 1237 (void) showxdr_string(NIS_MAXPATH, " Search Path = \"%s\""); 1238 } 1239 1240 void 1241 detail_entry_obj() 1242 { 1243 unsigned col, ncols; 1244 char *entyp; 1245 int is_nis_object = 0; 1246 1247 entyp = showxdr_string(1024, " Entry Type = \"%s\""); 1248 is_nis_object = (entyp != 0 && strcmp(entyp, "NIS object") == 0); 1249 /* Don't rely on entyp[] remaining valid */ 1250 ncols = showxdr_u_long(" Num Columns = %lu"); 1251 for (col = 1; col <= ncols; col++) { 1252 int pos1, pos2, len; 1253 unsigned flags; 1254 /* === Print both on one line? */ 1255 pos1 = getxdr_pos(); 1256 flags = getxdr_u_long(); 1257 pos2 = getxdr_pos(); 1258 if (ncols == 1) { 1259 sprintf(get_line(pos1, pos2), 1260 " Flags = %s", 1261 stringof_entryflags(flags)); 1262 } else { 1263 sprintf(get_line(pos1, pos2), 1264 "%6d: Flags = %s", 1265 col, stringof_entryflags(flags)); 1266 } 1267 if (flags & (EN_BINARY | EN_CRYPT | EN_XDR)) { 1268 len = getxdr_u_long(); 1269 if (is_nis_object && 1270 len == sizeof (unsigned long) && 1271 (flags & EN_CRYPT) == 0) { 1272 /* Special case for type = "NIS object" */ 1273 unsigned otype = getxdr_u_long(); 1274 sprintf(get_line(pos2, getxdr_pos()), 1275 " Value = %08x (ObjType = %s)", 1276 otype, stringof_otype(otype)); 1277 } else { 1278 showxdr_longhex(len, 1279 " Value = Binary %s"); 1280 } 1281 } else { 1282 showxdr_string(NIS_MAXATTRVAL, 1283 " Value = ASCII \"%s\""); 1284 } 1285 } 1286 } 1287 1288 void 1289 detail_link_obj() 1290 { 1291 int pos; 1292 int val; 1293 1294 pos = getxdr_pos(); 1295 val = getxdr_long(); 1296 sprintf(get_line(pos, getxdr_pos()), 1297 " Real Type= %08x (%s)", val, stringof_otype(val)); 1298 detail_nis_attrs(0); 1299 SHOW_NIS_NAME(" Real Name= %s"); 1300 } 1301 1302 void 1303 detail_private_obj() 1304 { 1305 /* ==== Need something fancier than this to be really useful */ 1306 showxdr_longhex(getxdr_u_long(), " Data = Binary %s"); 1307 } 1308 1309 void 1310 detail_nis_object() 1311 { 1312 unsigned rights, otype; 1313 int pos; 1314 1315 detail_nis_oid(); 1316 SHOW_NIS_NAME(" Name = %s"); 1317 SHOW_NIS_NAME(" Owner = %s"); 1318 SHOW_NIS_NAME(" Group = %s"); 1319 SHOW_NIS_NAME(" Domain = %s"); 1320 pos = getxdr_pos(); 1321 rights = getxdr_u_long(); 1322 sprintf(get_line(pos, getxdr_pos()), " Rights = %s", 1323 stringof_rights(rights)); 1324 (void) showxdr_u_long(" Lifetime = %8lu (seconds)"); 1325 1326 /* ?? show_space(); */ 1327 pos = getxdr_pos(); 1328 otype = getxdr_u_long(); 1329 (void) sprintf(get_line(pos, getxdr_pos()), 1330 " ObjType = %08x (%s)", 1331 otype, stringof_otype(otype)); 1332 switch (otype) { 1333 case NIS_DIRECTORY_OBJ: 1334 detail_directory_obj(); 1335 break; 1336 case NIS_GROUP_OBJ: 1337 detail_group_obj(); 1338 break; 1339 case NIS_TABLE_OBJ: 1340 detail_table_obj(); 1341 break; 1342 case NIS_ENTRY_OBJ: 1343 detail_entry_obj(); 1344 break; 1345 case NIS_LINK_OBJ: 1346 detail_link_obj(); 1347 break; 1348 case NIS_PRIVATE_OBJ: 1349 detail_private_obj(); 1350 break; 1351 default: 1352 /* ==== Can't do anything clever, right? */ 1353 break; 1354 } 1355 } 1356 1357 static void 1358 detail_ns_request() 1359 { 1360 unsigned nobjs; 1361 1362 SHOW_NAME(); 1363 nobjs = getxdr_u_long(); 1364 /* nobjs should be 0 or 1 only; === should check it ? */ 1365 if (nobjs != 0) { 1366 sprintf(get_line(0, 0), "Object included:"); 1367 } 1368 while (nobjs-- > 0) { 1369 detail_nis_object(); 1370 } 1371 } 1372 1373 static void 1374 detail_ib_request() 1375 { 1376 unsigned len; 1377 unsigned flags; 1378 int pos; 1379 1380 SHOW_NAME(); 1381 detail_nis_attrs(INDENT_SPACES); 1382 pos = getxdr_pos(); 1383 flags = getxdr_u_long(); 1384 sprintf(get_line(pos, getxdr_pos()), 1385 "Flags = %s", stringof_ib_flags(flags)); 1386 pos = getxdr_pos(); 1387 len = getxdr_u_long(); 1388 if (len == 0) { 1389 sprintf(get_line(pos, getxdr_pos()), "No included object"); 1390 } else { 1391 /* len should be 0 or 1 only; === should check it ? */ 1392 sprintf(get_line(pos, getxdr_pos()), "Included object:"); 1393 while (len-- > 0) { 1394 detail_nis_object(); 1395 } 1396 } 1397 pos = getxdr_pos(); 1398 len = getxdr_u_long(); 1399 if (len == 0) { 1400 sprintf(get_line(pos, getxdr_pos()), "No callback"); 1401 } else { 1402 /* len should be 0 or 1 only; === should check it ? */ 1403 sprintf(get_line(pos, getxdr_pos()), "Callback info:"); 1404 while (len-- > 0) { 1405 detail_nis_server(INDENT_SPACES); 1406 } 1407 } 1408 (void) showxdr_u_long("Bufsize = %lu"); 1409 detail_cookie(); 1410 } 1411 1412 static void 1413 detail_fd_args() 1414 { 1415 SHOW_NAME(); 1416 SHOW_NIS_NAME("Requester = %s"); 1417 } 1418 1419 static void 1420 detail_nis_taglist() 1421 { 1422 unsigned ntags; 1423 unsigned tagn; 1424 1425 ntags = showxdr_u_long("Number of tags = %lu"); 1426 for (tagn = 1; tagn < ntags; tagn++) { 1427 unsigned ttype; 1428 int pos; 1429 1430 if (ntags != 1) { 1431 sprintf(get_line(0, 0), " Tag %d:", tagn); 1432 } 1433 pos = getxdr_pos(); 1434 ttype = getxdr_u_long(); 1435 sprintf(get_line(pos, getxdr_pos()), 1436 " Tag name = %08x (%s)", 1437 ttype, stringof_tag(ttype)); 1438 showxdr_string(1024, " Tag value = \"%s\""); 1439 /* ^ ==== nis.x says it's a string rather than an opaque, */ 1440 /* but is it really? */ 1441 } 1442 } 1443 1444 static void 1445 detail_dump_args() 1446 { 1447 unsigned nserv; 1448 int pos; 1449 1450 SHOW_NAME(); 1451 showxdr_time("Time = %s"); 1452 1453 pos = getxdr_pos(); 1454 nserv = getxdr_u_long(); 1455 if (nserv == 1) { 1456 sprintf(get_line(pos, getxdr_pos()), "Callback:"); 1457 } else if (nserv > 1) { 1458 sprintf(get_line(pos, getxdr_pos()), 1459 "Num callbacks = %lu (!?):", nserv); 1460 } 1461 while (nserv-- > 0) { 1462 detail_nis_server(INDENT_SPACES); 1463 } 1464 } 1465 1466 static void 1467 detail_callback() /* i.e. the netobj argument to NIS_CALLBACK */ 1468 { 1469 detail_cookie(); 1470 } 1471 1472 static void 1473 detail_cookie() 1474 { 1475 unsigned len; 1476 int pos; 1477 1478 pos = getxdr_pos(); 1479 len = getxdr_u_long(); 1480 if (len == 0) { 1481 sprintf(get_line(pos, getxdr_pos()), "Cookie = NULL"); 1482 } else { 1483 showxdr_longhex(len, "Cookie = %s"); 1484 } 1485 } 1486 1487 static void 1488 detail_ping_args() 1489 { 1490 SHOW_NAME(); 1491 showxdr_time("Time = %s"); 1492 } 1493 1494 static void 1495 detail_nis_name() 1496 { 1497 SHOW_NAME(); 1498 } 1499 1500 static void 1501 detail_cback_data() 1502 { 1503 unsigned nobjs, no; 1504 nobjs = showxdr_u_long("Number of entries = %lu"); 1505 for (no = 1; no <= nobjs; no++) { 1506 if (getxdr_long() == 0) { 1507 sprintf(get_line(0, 0), " Entry %d is NULL (!?)", no); 1508 } else { 1509 if (nobjs != 1) { 1510 1511 sprintf(get_line(0, 0), " Entry %d:", no); 1512 } 1513 detail_nis_object(); 1514 } 1515 } 1516 } 1517 1518 static void 1519 detail_nis_result() 1520 { 1521 int pos; 1522 unsigned no, nobjs; 1523 1524 detail_nis_error(); 1525 pos = getxdr_pos(); 1526 nobjs = getxdr_u_long(); 1527 sprintf(get_line(pos, getxdr_pos()), "Number of objects = %lu", nobjs); 1528 for (no = 1; no <= nobjs; no++) { 1529 if (nobjs != 1) { 1530 sprintf(get_line(0, 0), " Object %d:", no); 1531 } 1532 detail_nis_object(); 1533 } 1534 detail_cookie(); 1535 showxdr_u_long("Server ticks = %8lu"); 1536 showxdr_u_long("Database ticks = %8lu"); 1537 showxdr_u_long("Cache ticks = %8lu"); /* These should always be */ 1538 showxdr_u_long("Client ticks = %8lu"); /* zero on the wire, yes? */ 1539 } 1540 1541 static void 1542 detail_fd_result() 1543 { 1544 int pos; 1545 unsigned len; 1546 int dir_pos; 1547 unsigned dir_len; 1548 int dir_end; 1549 1550 detail_nis_error(); 1551 SHOW_NAME(); 1552 /* nis.x doesn't say so, but the opaque contains a directory_obj */ 1553 dir_len = getxdr_u_long(); /* Byte-count at start of opaque */ 1554 if (dir_len == 0) { 1555 sprintf(get_line(0, 0), "Directory object = NULL"); 1556 } else { 1557 sprintf(get_line(0, 0), "Directory object:"); 1558 dir_pos = getxdr_pos(); 1559 dir_end = ((dir_len + 3) & ~3) + dir_pos; 1560 /* ^^^^^^^^^^ Did XDR do this already? */ 1561 detail_directory_obj(); 1562 pos = getxdr_pos(); 1563 if (pos != dir_end) { 1564 sprintf(get_line(pos, dir_end), 1565 "(Skipping %d unused bytes at end of directory object)", 1566 dir_end - pos); 1567 setxdr_pos(dir_end); 1568 } 1569 } 1570 len = getxdr_u_long(); 1571 if (len == 0) { 1572 sprintf(get_line(pos, getxdr_pos()), 1573 "Signature = NULL"); 1574 } else { 1575 if (len > 8) { 1576 sprintf(get_line(pos, getxdr_pos()), 1577 "Signature length is %lu, expected <= 8 bytes", 1578 len); 1579 } 1580 showxdr_longhex(len, "Signature = %s"); 1581 } 1582 } 1583 1584 /* 1585 * is_printable() -- looks for a string of (len-1) printable characters 1586 * followed by a NUL. Characters are deemed printable iff ctype's 1587 * isprint() macro says so, thus tab (^I) is regarded as unprintable. 1588 * === Is this test more stringent than we want, esp wrt placement of NUL? 1589 */ 1590 static int 1591 is_printable(str, len) 1592 char *str; 1593 unsigned len; 1594 { 1595 while (len > 1) { 1596 if (!isprint(*str)) { 1597 return (0); 1598 } 1599 str++, len--; 1600 } 1601 return (len == 1 && *str == 0); 1602 } 1603 1604 static void 1605 detail_nis_attrs(outdent) 1606 int outdent; /* Crock to get indentation right. Normally zero; */ 1607 /* set to four instead to remove leading spaces */ 1608 { 1609 unsigned nattrs; 1610 1611 nattrs = showxdr_u_long(outdent + " Number of attributes = %lu"); 1612 while (nattrs-- > 0) { 1613 char *str; 1614 unsigned len; 1615 int pos; 1616 1617 showxdr_string(NIS_MAXATTRNAME, 1618 outdent + " AttrName = %s"); 1619 pos = getxdr_pos(); 1620 str = getxdr_bytes(&len); 1621 if (is_printable(str, len)) { 1622 setxdr_pos(pos); 1623 showxdr_string(NIS_MAXATTRVAL, outdent + 1624 " AttrVal = ASCII \"%s\""); 1625 } else { 1626 setxdr_pos(pos); 1627 len = getxdr_u_long(); /* Yes, we knew it already */ 1628 showxdr_longhex(len, outdent + 1629 " AttrVal = Binary %s"); 1630 } 1631 } 1632 } 1633 1634 static void 1635 detail_log_entry() 1636 { 1637 int pos; 1638 long val; 1639 1640 showxdr_time(" Log Time = %s"); 1641 pos = getxdr_pos(); 1642 val = getxdr_long(); 1643 sprintf(get_line(pos, getxdr_pos()), " Log Type = %d (%s)", 1644 val, stringof_entry_t(val)); 1645 SHOW_NIS_NAME(" Principal = %s"); 1646 SHOW_NIS_NAME(" Table/dir = %s"); 1647 detail_nis_attrs(0); 1648 sprintf(get_line(0, 0), " Object Value:"); 1649 detail_nis_object(); 1650 } 1651 1652 static void 1653 detail_log_result() 1654 { 1655 unsigned len, nents, en; 1656 int pos; 1657 1658 detail_nis_error(); 1659 pos = getxdr_pos(); 1660 len = getxdr_u_long(); 1661 detail_cookie(); 1662 nents = showxdr_u_long("Number of log entries = %lu"); 1663 for (en = 1; en <= nents; en++) { 1664 if (nents != 1) { 1665 sprintf(get_line(0, 0), " Log Entry %d", en); 1666 } 1667 detail_log_entry(); 1668 } 1669 } 1670 1671 static void 1672 detail_bool() 1673 { 1674 int pos; 1675 unsigned val; 1676 1677 pos = getxdr_pos(); 1678 val = getxdr_u_long(); 1679 sprintf(get_line(pos, getxdr_pos()), 1680 "Result = %s", val ? "true" : "false"); 1681 } 1682 1683 static void 1684 detail_cptime() 1685 { 1686 showxdr_time("Time = %s"); 1687 } 1688 1689 static void 1690 detail_cp_result() 1691 { 1692 detail_nis_error(); 1693 showxdr_u_long("Ticks (Server) = %lu"); 1694 showxdr_u_long(" (Database) = %lu"); 1695 } 1696