dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.sbin / snoop / snoop_nfs_acl.c
blob4883ed5e2367c1393626550540af85a11825a233
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
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>
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"
44 #include <sys/stat.h>
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();
62 extern jmp_buf xdr_err;
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 static void interpret_nfs_acl2(int, int, int, int, int, char *, int);
79 static void interpret_nfs_acl3(int, int, int, int, int, char *, int);
80 static void interpret_nfs_acl4(int, int, int, int, int, char *, int);
82 #define ACLPROC2_NULL ((unsigned long)(0))
83 #define ACLPROC2_GETACL ((unsigned long)(1))
84 #define ACLPROC2_SETACL ((unsigned long)(2))
85 #define ACLPROC2_GETATTR ((unsigned long)(3))
86 #define ACLPROC2_ACCESS ((unsigned long)(4))
87 #define ACLPROC2_GETXATTRDIR ((unsigned long)(5))
89 #define ACLPROC3_NULL ((unsigned long)(0))
90 #define ACLPROC3_GETACL ((unsigned long)(1))
91 #define ACLPROC3_SETACL ((unsigned long)(2))
92 #define ACLPROC3_GETXATTRDIR ((unsigned long)(3))
94 #define ACLPROC4_NULL ((unsigned long)(0))
95 #define ACLPROC4_GETACL ((unsigned long)(1))
96 #define ACLPROC4_SETACL ((unsigned long)(2))
98 #define NA_USER_OBJ 0x1
99 #define NA_USER 0x2
100 #define NA_GROUP_OBJ 0x4
101 #define NA_GROUP 0x8
102 #define NA_CLASS_OBJ 0x10
103 #define NA_OTHER_OBJ 0x20
104 #define NA_ACL_DEFAULT 0x1000
106 #define NA_DEF_USER_OBJ (NA_USER_OBJ | NA_ACL_DEFAULT)
107 #define NA_DEF_USER (NA_USER | NA_ACL_DEFAULT)
108 #define NA_DEF_GROUP_OBJ (NA_GROUP_OBJ | NA_ACL_DEFAULT)
109 #define NA_DEF_GROUP (NA_GROUP | NA_ACL_DEFAULT)
110 #define NA_DEF_CLASS_OBJ (NA_CLASS_OBJ | NA_ACL_DEFAULT)
111 #define NA_DEF_OTHER_OBJ (NA_OTHER_OBJ | NA_ACL_DEFAULT)
113 #define NA_ACL 0x1
114 #define NA_ACLCNT 0x2
115 #define NA_DFACL 0x4
116 #define NA_DFACLCNT 0x8
118 #define ACCESS2_READ 0x0001
119 #define ACCESS2_LOOKUP 0x0002
120 #define ACCESS2_MODIFY 0x0004
121 #define ACCESS2_EXTEND 0x0008
122 #define ACCESS2_DELETE 0x0010
123 #define ACCESS2_EXECUTE 0x0020
125 static char *procnames_short_v2[] = {
126 "NULL2", /* 0 */
127 "GETACL2", /* 1 */
128 "SETACL2", /* 2 */
129 "GETATTR2", /* 3 */
130 "ACCESS2", /* 4 */
131 "GETXATTRDIR2", /* 5 */
133 static char *procnames_short_v3[] = {
134 "NULL3", /* 0 */
135 "GETACL3", /* 1 */
136 "SETACL3", /* 2 */
137 "GETXATTRDIR3", /* 3 */
139 static char *procnames_short_v4[] = {
140 "NULL4", /* 0 */
141 "GETACL4", /* 1 */
142 "SETACL4", /* 2 */
145 static char *procnames_long_v2[] = {
146 "Null procedure", /* 0 */
147 "Get file access control list", /* 1 */
148 "Set file access control list", /* 2 */
149 "Get file attributes", /* 3 */
150 "Check access permission", /* 4 */
151 "Get extended attribute directory", /* 5 */
153 static char *procnames_long_v3[] = {
154 "Null procedure", /* 0 */
155 "Get file access control list", /* 1 */
156 "Set file access control list", /* 2 */
157 "Get extended attribute directory", /* 3 */
159 static char *procnames_long_v4[] = {
160 "Null procedure", /* 0 */
161 "Get file access control list", /* 1 */
162 "Set file access control list", /* 2 */
165 #define MAXPROC_V2 5
166 #define MAXPROC_V3 3
167 #define MAXPROC_V4 2
169 /* ARGSUSED */
170 void
171 interpret_nfs_acl(flags, type, xid, vers, proc, data, len)
172 int flags, type, xid, vers, proc;
173 char *data;
174 int len;
177 if (vers == 2) {
178 interpret_nfs_acl2(flags, type, xid, vers, proc, data, len);
179 return;
182 if (vers == 3) {
183 interpret_nfs_acl3(flags, type, xid, vers, proc, data, len);
184 return;
187 if (vers == 4) {
188 interpret_nfs_acl4(flags, type, xid, vers, proc, data, len);
189 return;
193 static void
194 interpret_nfs_acl2(int flags, int type, int xid, int vers, int proc,
195 char *data, int len)
197 char *line;
198 char buff[2048];
199 int off, sz;
200 char *fh;
201 ulong_t mask;
203 if (proc < 0 || proc > MAXPROC_V2)
204 return;
206 if (flags & F_SUM) {
207 line = get_sum_line();
209 if (type == CALL) {
210 (void) sprintf(line, "NFS_ACL C %s",
211 procnames_short_v2[proc]);
212 line += strlen(line);
213 switch (proc) {
214 case ACLPROC2_GETACL:
215 fh = sum_nfsfh();
216 mask = getxdr_u_long();
217 (void) sprintf(line, "%s mask=0x%lx", fh, mask);
218 break;
219 case ACLPROC2_SETACL:
220 (void) sprintf(line, sum_nfsfh());
221 break;
222 case ACLPROC2_GETATTR:
223 (void) sprintf(line, sum_nfsfh());
224 break;
225 case ACLPROC2_ACCESS:
226 fh = sum_nfsfh();
227 (void) sprintf(line, "%s (%s)", fh,
228 sum_access2());
229 break;
230 case ACLPROC2_GETXATTRDIR:
231 fh = sum_nfsfh();
232 (void) sprintf(line, "%s create=%s", fh,
233 getxdr_bool() ? "true" : "false");
234 break;
235 default:
236 break;
239 check_retransmit(line, (ulong_t)xid);
240 } else {
241 (void) sprintf(line, "NFS_ACL R %s ",
242 procnames_short_v2[proc]);
243 line += strlen(line);
244 switch (proc) {
245 case ACLPROC2_GETACL:
246 (void) sum_nfsstat(line);
247 break;
248 case ACLPROC2_SETACL:
249 (void) sum_nfsstat(line);
250 break;
251 case ACLPROC2_GETATTR:
252 (void) sum_nfsstat(line);
253 break;
254 case ACLPROC2_ACCESS:
255 if (sum_nfsstat(line) == 0) {
256 skip_fattr();
257 line += strlen(line);
258 (void) sprintf(line, " (%s)",
259 sum_access2());
261 break;
262 case ACLPROC2_GETXATTRDIR:
263 if (sum_nfsstat(line) == 0) {
264 line += strlen(line);
265 (void) sprintf(line, sum_nfsfh());
267 break;
268 default:
269 break;
274 if (flags & F_DTAIL) {
275 show_header("NFS_ACL: ", "Sun NFS_ACL", len);
276 show_space();
277 (void) sprintf(get_line(0, 0), "Proc = %d (%s)",
278 proc, procnames_long_v2[proc]);
279 if (type == CALL)
280 aclcall2(proc);
281 else
282 aclreply2(proc);
283 show_trailer();
287 static void
288 interpret_nfs_acl3(int flags, int type, int xid, int vers, int proc,
289 char *data, int len)
291 char *line;
292 char buff[2048];
293 int off, sz;
294 char *fh;
295 ulong_t mask;
297 if (proc < 0 || proc > MAXPROC_V3)
298 return;
300 if (flags & F_SUM) {
301 line = get_sum_line();
303 if (type == CALL) {
304 (void) sprintf(line, "NFS_ACL C %s",
305 procnames_short_v3[proc]);
306 line += strlen(line);
307 switch (proc) {
308 case ACLPROC3_GETACL:
309 fh = sum_nfsfh3();
310 mask = getxdr_u_long();
311 (void) sprintf(line, "%s mask=0x%lx", fh, mask);
312 break;
313 case ACLPROC3_SETACL:
314 (void) sprintf(line, sum_nfsfh3());
315 break;
316 case ACLPROC3_GETXATTRDIR:
317 fh = sum_nfsfh3();
318 (void) sprintf(line, "%s create=%s", fh,
319 getxdr_bool() ? "true" : "false");
320 break;
321 default:
322 break;
325 check_retransmit(line, (ulong_t)xid);
326 } else {
327 (void) sprintf(line, "NFS_ACL R %s ",
328 procnames_short_v3[proc]);
329 line += strlen(line);
330 switch (proc) {
331 case ACLPROC3_GETACL:
332 (void) sum_nfsstat3(line);
333 break;
334 case ACLPROC3_SETACL:
335 (void) sum_nfsstat3(line);
336 break;
337 case ACLPROC3_GETXATTRDIR:
338 if (sum_nfsstat3(line) == 0) {
339 line += strlen(line);
340 (void) sprintf(line, sum_nfsfh3());
342 break;
343 default:
344 break;
349 if (flags & F_DTAIL) {
350 show_header("NFS_ACL: ", "Sun NFS_ACL", len);
351 show_space();
352 (void) sprintf(get_line(0, 0), "Proc = %d (%s)",
353 proc, procnames_long_v3[proc]);
354 if (type == CALL)
355 aclcall3(proc);
356 else
357 aclreply3(proc);
358 show_trailer();
362 static void
363 interpret_nfs_acl4(int flags, int type, int xid, int vers, int proc,
364 char *data, int len)
366 char *line;
367 char buff[2048];
368 int off, sz;
369 char *fh;
370 ulong_t mask;
372 if (proc < 0 || proc > MAXPROC_V4)
373 return;
375 if (flags & F_SUM) {
376 line = get_sum_line();
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=0x%lx", fh, mask);
387 break;
388 case ACLPROC4_SETACL:
389 (void) sprintf(line, sum_nfsfh3());
390 break;
391 default:
392 break;
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;
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();
427 sum_nfsstat4(char *line)
429 ulong_t status;
430 char *p, *nfsstat4_to_name(int);
432 status = getxdr_long();
433 p = nfsstat4_to_name(status);
434 (void) strcpy(line, p);
435 return (status);
439 detail_nfsstat4()
441 ulong_t status;
442 char buff[64];
443 int pos;
445 pos = getxdr_pos();
446 status = sum_nfsstat4(buff);
448 (void) sprintf(get_line(pos, getxdr_pos()), "Status = %d (%s)",
449 status, buff);
451 return ((int)status);
455 * Print out version 2 NFS_ACL call packets
457 static void
458 aclcall2(proc)
459 int proc;
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;
484 * Print out version 2 NFS_ACL reply packets
486 static void
487 aclreply2(proc)
488 int proc;
491 switch (proc) {
492 case ACLPROC2_GETACL:
493 if (detail_nfsstat() == 0) {
494 detail_fattr();
495 detail_secattr();
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();
511 break;
512 default:
513 break;
518 * Print out version 3 NFS_ACL call packets
520 static void
521 aclcall3(proc)
522 int proc;
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;
540 * Print out version 3 NFS_ACL reply packets
542 static void
543 aclreply3(proc)
544 int proc;
547 switch (proc) {
548 case ACLPROC3_GETACL:
549 if (detail_nfsstat3() == 0) {
550 detail_post_op_attr("");
551 detail_secattr();
553 break;
554 case ACLPROC3_SETACL:
555 if (detail_nfsstat3() == 0)
556 detail_post_op_attr("");
557 break;
558 default:
559 break;
564 * Print out version 4 NFS_ACL call packets
566 static void
567 aclcall4(proc)
568 int proc;
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;
586 * Print out version 4 NFS_ACL reply packets
588 static void
589 aclreply4(proc)
590 int proc;
593 switch (proc) {
594 case ACLPROC4_GETACL:
595 if (detail_nfsstat4() == 0) {
596 detail_post_op_attr("");
597 detail_secattr();
599 break;
600 case ACLPROC4_SETACL:
601 if (detail_nfsstat4() == 0)
602 detail_post_op_attr("");
603 break;
604 default:
605 break;
609 static void
610 detail_access2()
612 uint_t bits;
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)"));
629 static char *
630 sum_access2()
632 int bits;
633 static char buff[22];
635 bits = getxdr_u_long();
636 buff[0] = '\0';
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';
653 return (buff);
656 static void
657 detail_mask()
659 ulong_t mask;
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)"));
672 static void
673 detail_secattr()
676 detail_mask();
677 showxdr_long("Aclcnt = %d");
678 detail_aclent();
679 showxdr_long("Dfaclcnt = %d");
680 detail_aclent();
683 static void
684 detail_aclent()
686 int count;
687 int type;
688 int id;
689 ushort_t perm;
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;
752 static char *
753 detail_uname(uid_t uid)
755 struct passwd *pwd;
756 static char uidp[10];
758 pwd = getpwuid(uid);
759 if (pwd == NULL) {
760 sprintf(uidp, "%d", uid);
761 return (uidp);
763 return (pwd->pw_name);
766 static char *
767 detail_gname(gid_t gid)
769 struct group *grp;
770 static char gidp[10];
772 grp = getgrgid(gid);
773 if (grp == NULL) {
774 sprintf(gidp, "%d", gid);
775 return (gidp);
777 return (grp->gr_name);
780 static char *perms[] = {
781 "---",
782 "--x",
783 "-w-",
784 "-wx",
785 "r--",
786 "r-x",
787 "rw-",
788 "rwx"
790 static char *
791 detail_perm(ushort_t perm)
794 if (perm >= sizeof (perms) / sizeof (perms[0]))
795 return ("?");
796 return (perms[perm]);