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 1991,2001-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" /* SunOS */ 28 29 #include <sys/types.h> 30 #include <sys/errno.h> 31 #include <sys/tiuser.h> 32 #include <setjmp.h> 33 #include <pwd.h> 34 #include <grp.h> 35 36 #include <rpc/types.h> 37 #include <rpc/xdr.h> 38 #include <rpc/auth.h> 39 #include <rpc/clnt.h> 40 #include <rpc/rpc_msg.h> 41 #include <string.h> 42 #include "snoop.h" 43 44 #include <sys/stat.h> 45 46 extern char *get_sum_line(); 47 extern void check_retransmit(); 48 extern char *sum_nfsfh(); 49 extern int sum_nfsstat(); 50 extern int detail_nfsstat(); 51 extern void detail_nfsfh(); 52 extern void detail_fattr(); 53 extern void skip_fattr(); 54 extern char *sum_nfsfh3(); 55 extern int sum_nfsstat3(); 56 extern int detail_nfsstat3(); 57 extern void detail_post_op_attr(); 58 extern void detail_nfsfh3(); 59 extern int sum_nfsstat4(); 60 extern int detail_nfsstat4(); 61 62 extern jmp_buf xdr_err; 63 64 static void aclcall2(); 65 static void aclreply2(); 66 static void aclcall3(); 67 static void aclreply3(); 68 static void aclcall4(); 69 static void aclreply4(); 70 static void detail_access2(); 71 static char *sum_access2(); 72 static void detail_mask(); 73 static void detail_secattr(); 74 static void detail_aclent(); 75 static char *detail_uname(); 76 static char *detail_gname(); 77 static char *detail_perm(ushort_t); 78 79 #define ACLPROC2_NULL ((unsigned long)(0)) 80 #define ACLPROC2_GETACL ((unsigned long)(1)) 81 #define ACLPROC2_SETACL ((unsigned long)(2)) 82 #define ACLPROC2_GETATTR ((unsigned long)(3)) 83 #define ACLPROC2_ACCESS ((unsigned long)(4)) 84 #define ACLPROC2_GETXATTRDIR ((unsigned long)(5)) 85 86 #define ACLPROC3_NULL ((unsigned long)(0)) 87 #define ACLPROC3_GETACL ((unsigned long)(1)) 88 #define ACLPROC3_SETACL ((unsigned long)(2)) 89 #define ACLPROC3_GETXATTRDIR ((unsigned long)(3)) 90 91 #define ACLPROC4_NULL ((unsigned long)(0)) 92 #define ACLPROC4_GETACL ((unsigned long)(1)) 93 #define ACLPROC4_SETACL ((unsigned long)(2)) 94 95 #define NA_USER_OBJ 0x1 96 #define NA_USER 0x2 97 #define NA_GROUP_OBJ 0x4 98 #define NA_GROUP 0x8 99 #define NA_CLASS_OBJ 0x10 100 #define NA_OTHER_OBJ 0x20 101 #define NA_ACL_DEFAULT 0x1000 102 103 #define NA_DEF_USER_OBJ (NA_USER_OBJ | NA_ACL_DEFAULT) 104 #define NA_DEF_USER (NA_USER | NA_ACL_DEFAULT) 105 #define NA_DEF_GROUP_OBJ (NA_GROUP_OBJ | NA_ACL_DEFAULT) 106 #define NA_DEF_GROUP (NA_GROUP | NA_ACL_DEFAULT) 107 #define NA_DEF_CLASS_OBJ (NA_CLASS_OBJ | NA_ACL_DEFAULT) 108 #define NA_DEF_OTHER_OBJ (NA_OTHER_OBJ | NA_ACL_DEFAULT) 109 110 #define NA_ACL 0x1 111 #define NA_ACLCNT 0x2 112 #define NA_DFACL 0x4 113 #define NA_DFACLCNT 0x8 114 115 #define ACCESS2_READ 0x0001 116 #define ACCESS2_LOOKUP 0x0002 117 #define ACCESS2_MODIFY 0x0004 118 #define ACCESS2_EXTEND 0x0008 119 #define ACCESS2_DELETE 0x0010 120 #define ACCESS2_EXECUTE 0x0020 121 122 static char *procnames_short_v2[] = { 123 "NULL2", /* 0 */ 124 "GETACL2", /* 1 */ 125 "SETACL2", /* 2 */ 126 "GETATTR2", /* 3 */ 127 "ACCESS2", /* 4 */ 128 "GETXATTRDIR2", /* 5 */ 129 }; 130 static char *procnames_short_v3[] = { 131 "NULL3", /* 0 */ 132 "GETACL3", /* 1 */ 133 "SETACL3", /* 2 */ 134 "GETXATTRDIR3", /* 3 */ 135 }; 136 static char *procnames_short_v4[] = { 137 "NULL4", /* 0 */ 138 "GETACL4", /* 1 */ 139 "SETACL4", /* 2 */ 140 }; 141 142 static char *procnames_long_v2[] = { 143 "Null procedure", /* 0 */ 144 "Get file access control list", /* 1 */ 145 "Set file access control list", /* 2 */ 146 "Get file attributes", /* 3 */ 147 "Check access permission", /* 4 */ 148 "Get extended attribute directory", /* 5 */ 149 }; 150 static char *procnames_long_v3[] = { 151 "Null procedure", /* 0 */ 152 "Get file access control list", /* 1 */ 153 "Set file access control list", /* 2 */ 154 "Get extended attribute directory", /* 3 */ 155 }; 156 static char *procnames_long_v4[] = { 157 "Null procedure", /* 0 */ 158 "Get file access control list", /* 1 */ 159 "Set file access control list", /* 2 */ 160 }; 161 162 #define MAXPROC_V2 5 163 #define MAXPROC_V3 3 164 #define MAXPROC_V4 2 165 166 /* ARGSUSED */ 167 void 168 interpret_nfs_acl(flags, type, xid, vers, proc, data, len) 169 int flags, type, xid, vers, proc; 170 char *data; 171 int len; 172 { 173 174 if (vers == 2) { 175 interpret_nfs_acl2(flags, type, xid, vers, proc, data, len); 176 return; 177 } 178 179 if (vers == 3) { 180 interpret_nfs_acl3(flags, type, xid, vers, proc, data, len); 181 return; 182 } 183 184 if (vers == 4) { 185 interpret_nfs_acl4(flags, type, xid, vers, proc, data, len); 186 return; 187 } 188 } 189 190 interpret_nfs_acl2(flags, type, xid, vers, proc, data, len) 191 int flags, type, xid, vers, proc; 192 char *data; 193 int len; 194 { 195 char *line; 196 char buff[2048]; 197 int off, sz; 198 char *fh; 199 ulong_t mask; 200 201 if (proc < 0 || proc > MAXPROC_V2) 202 return; 203 204 if (flags & F_SUM) { 205 line = get_sum_line(); 206 207 if (type == CALL) { 208 (void) sprintf(line, "NFS_ACL C %s", 209 procnames_short_v2[proc]); 210 line += strlen(line); 211 switch (proc) { 212 case ACLPROC2_GETACL: 213 fh = sum_nfsfh(); 214 mask = getxdr_u_long(); 215 (void) sprintf(line, "%s mask=%lu", fh, mask); 216 break; 217 case ACLPROC2_SETACL: 218 (void) sprintf(line, sum_nfsfh()); 219 break; 220 case ACLPROC2_GETATTR: 221 (void) sprintf(line, sum_nfsfh()); 222 break; 223 case ACLPROC2_ACCESS: 224 fh = sum_nfsfh(); 225 (void) sprintf(line, "%s (%s)", fh, 226 sum_access2()); 227 break; 228 case ACLPROC2_GETXATTRDIR: 229 fh = sum_nfsfh(); 230 (void) sprintf(line, "%s create=%s", fh, 231 getxdr_bool() ? "true" : "false"); 232 break; 233 default: 234 break; 235 } 236 237 check_retransmit(line, (ulong_t)xid); 238 } else { 239 (void) sprintf(line, "NFS_ACL R %s ", 240 procnames_short_v2[proc]); 241 line += strlen(line); 242 switch (proc) { 243 case ACLPROC2_GETACL: 244 (void) sum_nfsstat(line); 245 break; 246 case ACLPROC2_SETACL: 247 (void) sum_nfsstat(line); 248 break; 249 case ACLPROC2_GETATTR: 250 (void) sum_nfsstat(line); 251 break; 252 case ACLPROC2_ACCESS: 253 if (sum_nfsstat(line) == 0) { 254 skip_fattr(); 255 line += strlen(line); 256 (void) sprintf(line, " (%s)", 257 sum_access2()); 258 } 259 break; 260 case ACLPROC2_GETXATTRDIR: 261 if (sum_nfsstat(line) == 0) { 262 line += strlen(line); 263 (void) sprintf(line, sum_nfsfh()); 264 } 265 break; 266 default: 267 break; 268 } 269 } 270 } 271 272 if (flags & F_DTAIL) { 273 show_header("NFS_ACL: ", "Sun NFS_ACL", len); 274 show_space(); 275 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 276 proc, procnames_long_v2[proc]); 277 if (type == CALL) 278 aclcall2(proc); 279 else 280 aclreply2(proc); 281 show_trailer(); 282 } 283 } 284 285 interpret_nfs_acl3(flags, type, xid, vers, proc, data, len) 286 int flags, type, xid, vers, proc; 287 char *data; 288 int len; 289 { 290 char *line; 291 char buff[2048]; 292 int off, sz; 293 char *fh; 294 ulong_t mask; 295 296 if (proc < 0 || proc > MAXPROC_V3) 297 return; 298 299 if (flags & F_SUM) { 300 line = get_sum_line(); 301 302 if (type == CALL) { 303 (void) sprintf(line, "NFS_ACL C %s", 304 procnames_short_v3[proc]); 305 line += strlen(line); 306 switch (proc) { 307 case ACLPROC3_GETACL: 308 fh = sum_nfsfh3(); 309 mask = getxdr_u_long(); 310 (void) sprintf(line, "%s mask=%lu", fh, mask); 311 break; 312 case ACLPROC3_SETACL: 313 (void) sprintf(line, sum_nfsfh3()); 314 break; 315 case ACLPROC3_GETXATTRDIR: 316 fh = sum_nfsfh3(); 317 (void) sprintf(line, "%s create=%s", fh, 318 getxdr_bool() ? "true" : "false"); 319 break; 320 default: 321 break; 322 } 323 324 check_retransmit(line, (ulong_t)xid); 325 } else { 326 (void) sprintf(line, "NFS_ACL R %s ", 327 procnames_short_v3[proc]); 328 line += strlen(line); 329 switch (proc) { 330 case ACLPROC3_GETACL: 331 (void) sum_nfsstat3(line); 332 break; 333 case ACLPROC3_SETACL: 334 (void) sum_nfsstat3(line); 335 break; 336 case ACLPROC3_GETXATTRDIR: 337 if (sum_nfsstat3(line) == 0) { 338 line += strlen(line); 339 (void) sprintf(line, sum_nfsfh3()); 340 } 341 break; 342 default: 343 break; 344 } 345 } 346 } 347 348 if (flags & F_DTAIL) { 349 show_header("NFS_ACL: ", "Sun NFS_ACL", len); 350 show_space(); 351 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 352 proc, procnames_long_v3[proc]); 353 if (type == CALL) 354 aclcall3(proc); 355 else 356 aclreply3(proc); 357 show_trailer(); 358 } 359 } 360 361 interpret_nfs_acl4(flags, type, xid, vers, proc, data, len) 362 int flags, type, xid, vers, proc; 363 char *data; 364 int len; 365 { 366 char *line; 367 char buff[2048]; 368 int off, sz; 369 char *fh; 370 ulong_t mask; 371 372 if (proc < 0 || proc > MAXPROC_V4) 373 return; 374 375 if (flags & F_SUM) { 376 line = get_sum_line(); 377 378 if (type == CALL) { 379 (void) sprintf(line, "NFS_ACL C %s", 380 procnames_short_v4[proc]); 381 line += strlen(line); 382 switch (proc) { 383 case ACLPROC4_GETACL: 384 fh = sum_nfsfh3(); 385 mask = getxdr_u_long(); 386 (void) sprintf(line, "%s mask=%lu", fh, mask); 387 break; 388 case ACLPROC4_SETACL: 389 (void) sprintf(line, sum_nfsfh3()); 390 break; 391 default: 392 break; 393 } 394 395 check_retransmit(line, (ulong_t)xid); 396 } else { 397 (void) sprintf(line, "NFS_ACL R %s ", 398 procnames_short_v4[proc]); 399 line += strlen(line); 400 switch (proc) { 401 case ACLPROC4_GETACL: 402 (void) sum_nfsstat4(line); 403 break; 404 case ACLPROC4_SETACL: 405 (void) sum_nfsstat4(line); 406 break; 407 default: 408 break; 409 } 410 } 411 } 412 413 if (flags & F_DTAIL) { 414 show_header("NFS_ACL: ", "Sun NFS_ACL", len); 415 show_space(); 416 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 417 proc, procnames_long_v4[proc]); 418 if (type == CALL) 419 aclcall4(proc); 420 else 421 aclreply4(proc); 422 show_trailer(); 423 } 424 } 425 426 int 427 sum_nfsstat4(char *line) 428 { 429 ulong_t status; 430 char *p, *nfsstat4_to_name(int); 431 432 status = getxdr_long(); 433 p = nfsstat4_to_name(status); 434 (void) strcpy(line, p); 435 return (status); 436 } 437 438 int 439 detail_nfsstat4() 440 { 441 ulong_t status; 442 char buff[64]; 443 int pos; 444 445 pos = getxdr_pos(); 446 status = sum_nfsstat4(buff); 447 448 (void) sprintf(get_line(pos, getxdr_pos()), "Status = %d (%s)", 449 status, buff); 450 451 return ((int)status); 452 } 453 454 /* 455 * Print out version 2 NFS_ACL call packets 456 */ 457 static void 458 aclcall2(proc) 459 int proc; 460 { 461 462 switch (proc) { 463 case ACLPROC2_GETACL: 464 detail_nfsfh(); 465 detail_mask(); 466 break; 467 case ACLPROC2_SETACL: 468 detail_nfsfh(); 469 detail_secattr(); 470 break; 471 case ACLPROC2_GETATTR: 472 detail_nfsfh(); 473 break; 474 case ACLPROC2_ACCESS: 475 detail_nfsfh(); 476 detail_access2(); 477 break; 478 default: 479 break; 480 } 481 } 482 483 /* 484 * Print out version 2 NFS_ACL reply packets 485 */ 486 static void 487 aclreply2(proc) 488 int proc; 489 { 490 491 switch (proc) { 492 case ACLPROC2_GETACL: 493 if (detail_nfsstat() == 0) { 494 detail_fattr(); 495 detail_secattr(); 496 } 497 break; 498 case ACLPROC2_SETACL: 499 if (detail_nfsstat() == 0) 500 detail_fattr(); 501 break; 502 case ACLPROC2_GETATTR: 503 if (detail_nfsstat() == 0) 504 detail_fattr(); 505 break; 506 case ACLPROC2_ACCESS: 507 if (detail_nfsstat() == 0) { 508 detail_fattr(); 509 detail_access2(); 510 } 511 break; 512 default: 513 break; 514 } 515 } 516 517 /* 518 * Print out version 3 NFS_ACL call packets 519 */ 520 static void 521 aclcall3(proc) 522 int proc; 523 { 524 525 switch (proc) { 526 case ACLPROC3_GETACL: 527 detail_nfsfh3(); 528 detail_mask(); 529 break; 530 case ACLPROC3_SETACL: 531 detail_nfsfh3(); 532 detail_secattr(); 533 break; 534 default: 535 break; 536 } 537 } 538 539 /* 540 * Print out version 3 NFS_ACL reply packets 541 */ 542 static void 543 aclreply3(proc) 544 int proc; 545 { 546 547 switch (proc) { 548 case ACLPROC3_GETACL: 549 if (detail_nfsstat3() == 0) { 550 detail_post_op_attr(""); 551 detail_secattr(); 552 } 553 break; 554 case ACLPROC3_SETACL: 555 if (detail_nfsstat3() == 0) 556 detail_post_op_attr(""); 557 break; 558 default: 559 break; 560 } 561 } 562 563 /* 564 * Print out version 4 NFS_ACL call packets 565 */ 566 static void 567 aclcall4(proc) 568 int proc; 569 { 570 571 switch (proc) { 572 case ACLPROC4_GETACL: 573 detail_nfsfh3(); 574 detail_mask(); 575 break; 576 case ACLPROC4_SETACL: 577 detail_nfsfh3(); 578 detail_secattr(); 579 break; 580 default: 581 break; 582 } 583 } 584 585 /* 586 * Print out version 4 NFS_ACL reply packets 587 */ 588 static void 589 aclreply4(proc) 590 int proc; 591 { 592 593 switch (proc) { 594 case ACLPROC4_GETACL: 595 if (detail_nfsstat4() == 0) { 596 detail_post_op_attr(""); 597 detail_secattr(); 598 } 599 break; 600 case ACLPROC4_SETACL: 601 if (detail_nfsstat4() == 0) 602 detail_post_op_attr(""); 603 break; 604 default: 605 break; 606 } 607 } 608 609 static void 610 detail_access2() 611 { 612 uint_t bits; 613 614 bits = showxdr_u_long("Access bits = 0x%08x"); 615 (void) sprintf(get_line(0, 0), " %s", 616 getflag(bits, ACCESS2_READ, "Read", "(no read)")); 617 (void) sprintf(get_line(0, 0), " %s", 618 getflag(bits, ACCESS2_LOOKUP, "Lookup", "(no lookup)")); 619 (void) sprintf(get_line(0, 0), " %s", 620 getflag(bits, ACCESS2_MODIFY, "Modify", "(no modify)")); 621 (void) sprintf(get_line(0, 0), " %s", 622 getflag(bits, ACCESS2_EXTEND, "Extend", "(no extend)")); 623 (void) sprintf(get_line(0, 0), " %s", 624 getflag(bits, ACCESS2_DELETE, "Delete", "(no delete)")); 625 (void) sprintf(get_line(0, 0), " %s", 626 getflag(bits, ACCESS2_EXECUTE, "Execute", "(no execute)")); 627 } 628 629 static char * 630 sum_access2() 631 { 632 int bits; 633 static char buff[22]; 634 635 bits = getxdr_u_long(); 636 buff[0] = '\0'; 637 638 if (bits & ACCESS2_READ) 639 (void) strcat(buff, "read,"); 640 if (bits & ACCESS2_LOOKUP) 641 (void) strcat(buff, "lookup,"); 642 if (bits & ACCESS2_MODIFY) 643 (void) strcat(buff, "modify,"); 644 if (bits & ACCESS2_EXTEND) 645 (void) strcat(buff, "extend,"); 646 if (bits & ACCESS2_DELETE) 647 (void) strcat(buff, "delete,"); 648 if (bits & ACCESS2_EXECUTE) 649 (void) strcat(buff, "execute,"); 650 if (buff[0] != '\0') 651 buff[strlen(buff) - 1] = '\0'; 652 653 return (buff); 654 } 655 656 static void 657 detail_mask() 658 { 659 ulong_t mask; 660 661 mask = showxdr_u_long("Mask = 0x%lx"); 662 (void) sprintf(get_line(0, 0), " %s", 663 getflag(mask, NA_ACL, "aclent", "(no aclent)")); 664 (void) sprintf(get_line(0, 0), " %s", 665 getflag(mask, NA_ACLCNT, "aclcnt", "(no aclcnt)")); 666 (void) sprintf(get_line(0, 0), " %s", 667 getflag(mask, NA_DFACL, "dfaclent", "(no dfaclent)")); 668 (void) sprintf(get_line(0, 0), " %s", 669 getflag(mask, NA_DFACLCNT, "dfaclcnt", "(no dfaclcnt)")); 670 } 671 672 static void 673 detail_secattr() 674 { 675 676 detail_mask(); 677 showxdr_long("Aclcnt = %d"); 678 detail_aclent(); 679 showxdr_long("Dfaclcnt = %d"); 680 detail_aclent(); 681 } 682 683 static void 684 detail_aclent() 685 { 686 int count; 687 int type; 688 int id; 689 ushort_t perm; 690 691 count = getxdr_long(); 692 while (count-- > 0) { 693 type = getxdr_long(); 694 id = getxdr_long(); 695 perm = getxdr_u_short(); 696 switch (type) { 697 case NA_USER: 698 (void) sprintf(get_line(0, 0), "\tuser:%s:%s", 699 detail_uname(id), detail_perm(perm)); 700 break; 701 case NA_USER_OBJ: 702 (void) sprintf(get_line(0, 0), "\tuser::%s", 703 detail_perm(perm)); 704 break; 705 case NA_GROUP: 706 (void) sprintf(get_line(0, 0), "\tgroup:%s:%s", 707 detail_gname(id), detail_perm(perm)); 708 break; 709 case NA_GROUP_OBJ: 710 (void) sprintf(get_line(0, 0), "\tgroup::%s", 711 detail_perm(perm)); 712 break; 713 case NA_CLASS_OBJ: 714 (void) sprintf(get_line(0, 0), "\tmask:%s", 715 detail_perm(perm)); 716 break; 717 case NA_OTHER_OBJ: 718 (void) sprintf(get_line(0, 0), "\tother:%s", 719 detail_perm(perm)); 720 break; 721 case NA_DEF_USER: 722 (void) sprintf(get_line(0, 0), "\tdefault:user:%s:%s", 723 detail_uname(id), detail_perm(perm)); 724 break; 725 case NA_DEF_USER_OBJ: 726 (void) sprintf(get_line(0, 0), "\tdefault:user::%s", 727 detail_perm(perm)); 728 break; 729 case NA_DEF_GROUP: 730 (void) sprintf(get_line(0, 0), "\tdefault:group:%s:%s", 731 detail_gname(id), detail_perm(perm)); 732 break; 733 case NA_DEF_GROUP_OBJ: 734 (void) sprintf(get_line(0, 0), "\tdefault:group::%s", 735 detail_perm(perm)); 736 break; 737 case NA_DEF_CLASS_OBJ: 738 (void) sprintf(get_line(0, 0), "\tdefault:mask:%s", 739 detail_perm(perm)); 740 break; 741 case NA_DEF_OTHER_OBJ: 742 (void) sprintf(get_line(0, 0), "\tdefault:other:%s", 743 detail_perm(perm)); 744 break; 745 default: 746 (void) sprintf(get_line(0, 0), "\tunrecognized entry"); 747 break; 748 } 749 } 750 } 751 752 static char * 753 detail_uname(uid_t uid) 754 { 755 struct passwd *pwd; 756 static char uidp[10]; 757 758 pwd = getpwuid(uid); 759 if (pwd == NULL) { 760 sprintf(uidp, "%d", uid); 761 return (uidp); 762 } 763 return (pwd->pw_name); 764 } 765 766 static char * 767 detail_gname(gid_t gid) 768 { 769 struct group *grp; 770 static char gidp[10]; 771 772 grp = getgrgid(gid); 773 if (grp == NULL) { 774 sprintf(gidp, "%d", gid); 775 return (gidp); 776 } 777 return (grp->gr_name); 778 } 779 780 static char *perms[] = { 781 "---", 782 "--x", 783 "-w-", 784 "-wx", 785 "r--", 786 "r-x", 787 "rw-", 788 "rwx" 789 }; 790 static char * 791 detail_perm(ushort_t perm) 792 { 793 794 if (perm > sizeof (perms) / sizeof (perms[0])) 795 return ("?"); 796 return (perms[perm]); 797 } 798