xref: /illumos-gate/usr/src/cmd/auditconfig/auditconfig.c (revision 80ab886d233f514d54c2a6bdeb9fdfd951bd6881)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * auditconfig - set and display audit parameters
30  */
31 
32 #include <locale.h>
33 #include <sys/types.h>
34 #include <ctype.h>
35 #include <stdlib.h>
36 #include <stdarg.h>
37 #include <unistd.h>
38 #include <errno.h>
39 #include <sys/param.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <strings.h>
43 #include <nlist.h>
44 #include <fcntl.h>
45 #include <sys/socket.h>
46 #include <netdb.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <sys/mkdev.h>
50 #include <sys/param.h>
51 #include <pwd.h>
52 #include <libintl.h>
53 #include <zone.h>
54 #include <tsol/label.h>
55 
56 #include <bsm/audit.h>
57 #include <bsm/audit_record.h>
58 #include <bsm/libbsm.h>
59 
60 #if !defined(TEXT_DOMAIN)
61 #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
62 #endif
63 
64 #define	AC_ARG_AUDIT			0
65 #define	AC_ARG_CHKCONF			1
66 #define	AC_ARG_CONF			2
67 #define	AC_ARG_GETASID			3	/* same as GETSID */
68 #define	AC_ARG_GETAUDIT			4
69 #define	AC_ARG_GETAUID			5
70 #define	AC_ARG_GETCAR			6
71 #define	AC_ARG_GETCLASS			7	/* same as GETESTATE */
72 #define	AC_ARG_GETCOND			8
73 #define	AC_ARG_GETCWD			9
74 #define	AC_ARG_GETESTATE		10
75 #define	AC_ARG_GETKERNSTATE		11
76 #define	AC_ARG_GETKMASK			12	/* same as GETKERNSTATE */
77 #define	AC_ARG_GETPINFO			13
78 #define	AC_ARG_GETPOLICY		14
79 #define	AC_ARG_GETQBUFSZ		15
80 #define	AC_ARG_GETQCTRL			16
81 #define	AC_ARG_GETQDELAY		17
82 #define	AC_ARG_GETQHIWATER		18
83 #define	AC_ARG_GETQLOWATER		19
84 #define	AC_ARG_GETSID			20
85 #define	AC_ARG_GETSTAT			21
86 #define	AC_ARG_GETTERMID		22
87 #define	AC_ARG_GETUSERAUDIT		23	/* only CMW syscall w/out */
88 #define	AC_ARG_LSEVENT			24
89 #define	AC_ARG_LSPOLICY			25
90 #define	AC_ARG_SETASID			26
91 #define	AC_ARG_SETAUDIT			27
92 #define	AC_ARG_SETAUID			28
93 #define	AC_ARG_SETCLASS			29	/* same as SETESTATE */
94 /*	AC_ARG_SETCOND			30 */
95 #define	AC_ARG_SETESTATE		31
96 #define	AC_ARG_SETKERNSTATE		32
97 #define	AC_ARG_SETKMASK			33	/* same as SETKERNSTATE */
98 #define	AC_ARG_SETPMASK			34
99 #define	AC_ARG_SETSMASK			35
100 #define	AC_ARG_SETSTAT			36
101 #define	AC_ARG_SETPOLICY		37
102 #define	AC_ARG_SETQBUFSZ		38
103 #define	AC_ARG_SETQCTRL			39
104 #define	AC_ARG_SETQDELAY		40
105 #define	AC_ARG_SETQHIWATER		41
106 #define	AC_ARG_SETQLOWATER		42
107 #define	AC_ARG_SETTERMID		43
108 #define	AC_ARG_SETUMASK			44
109 #define	AC_ARG_SETUSERAUDIT		45
110 #define	AC_ARG_GETFSIZE			46
111 #define	AC_ARG_SETFSIZE			47
112 #define	AC_ARG_GETKAUDIT		48
113 #define	AC_ARG_SETKAUDIT		49
114 #define	AC_ARG_ACONF			50
115 #define	AC_ARG_CHKACONF			51
116 
117 #define	AC_KERN_EVENT 		0
118 #define	AC_USER_EVENT 		1
119 
120 /* defines for policy entry flags: */
121 
122 #define	AC_TSOL 		1	/* policy is TSOL-only */
123 
124 #define	NONE(s) (!strlen(s) ? gettext("none") : s)
125 
126 #define	ALL_POLICIES   (AUDIT_AHLT|\
127 			AUDIT_ARGE|\
128 			AUDIT_ARGV|\
129 			AUDIT_CNT|\
130 			AUDIT_GROUP|\
131 			AUDIT_PASSWD|\
132 			AUDIT_WINDATA|\
133 			AUDIT_SEQ|\
134 			AUDIT_TRAIL|\
135 			AUDIT_PATH|\
136 			AUDIT_PUBLIC|\
137 			AUDIT_ZONENAME|\
138 			AUDIT_PERZONE|\
139 			AUDIT_WINDATA_DOWN|\
140 			AUDIT_WINDATA_UP)
141 
142 #define	NO_POLICIES  (0)
143 
144 #define	ONEK 1024
145 
146 /* This should be defined in <string.h>, but it is not */
147 extern int strncasecmp();
148 
149 /*
150  * remove this after the audit.h is fixed
151  */
152 
153 struct arg_entry {
154 	char *arg_str;
155 	char *arg_opts;
156 	int auditconfig_cmd;
157 };
158 
159 struct policy_entry {
160 	char *policy_str;
161 	uint_t policy_mask;
162 	uint_t policy_flags;
163 	char *policy_desc;
164 };
165 
166 static struct arg_entry arg_table[] = {
167 	{ "-aconf",		"",			AC_ARG_ACONF},
168 	{ "-audit",	"event sorf retval string",	AC_ARG_AUDIT},
169 	{ "-chkaconf",		"",			AC_ARG_CHKACONF},
170 	{ "-chkconf",		"",			AC_ARG_CHKCONF},
171 	{ "-conf",		"",			AC_ARG_CONF},
172 	{ "-getasid",		"",			AC_ARG_GETASID},
173 	{ "-getaudit",		"",			AC_ARG_GETAUDIT},
174 	{ "-getauid",		"",			AC_ARG_GETAUID},
175 	{ "-getcar",		"",			AC_ARG_GETCAR},
176 	{ "-getclass",		"",			AC_ARG_GETCLASS},
177 	{ "-getcond",		"",			AC_ARG_GETCOND},
178 	{ "-getcwd",		"",			AC_ARG_GETCWD},
179 	{ "-getestate",		"event",		AC_ARG_GETESTATE},
180 	{ "-getfsize",		"",			AC_ARG_GETFSIZE},
181 	{ "-getkaudit",		"",			AC_ARG_GETKAUDIT},
182 	{ "-getkernstate",	"",			AC_ARG_GETKERNSTATE},
183 	{ "-getkmask",		"",			AC_ARG_GETKMASK},
184 	{ "-getpinfo",		"",			AC_ARG_GETPINFO},
185 	{ "-getpolicy",		"",			AC_ARG_GETPOLICY},
186 	{ "-getqbufsz",		"",			AC_ARG_GETQBUFSZ},
187 	{ "-getqctrl",		"",			AC_ARG_GETQCTRL},
188 	{ "-getqdelay",		"",			AC_ARG_GETQDELAY},
189 	{ "-getqhiwater",	"",			AC_ARG_GETQHIWATER},
190 	{ "-getqlowater",	"",			AC_ARG_GETQLOWATER},
191 	{ "-getsid",		"",			AC_ARG_GETSID},
192 	{ "-getstat",		"",			AC_ARG_GETSTAT},
193 	{ "-gettermid",		"",			AC_ARG_GETTERMID},
194 	{ "-gettid",		"",			AC_ARG_GETTERMID},
195 	{ "-getuseraudit",	"user",			AC_ARG_GETUSERAUDIT},
196 	{ "-lsevent",		"",			AC_ARG_LSEVENT},
197 	{ "-lspolicy",		"",			AC_ARG_LSPOLICY},
198 	{ "-setasid",		"asid [cmd]",		AC_ARG_SETASID},
199 	{ "-setaudit",	"auid audit_flags termid sid [cmd]",
200 							AC_ARG_SETAUDIT},
201 	{ "-setauid",		"auid [cmd]",		AC_ARG_SETAUID},
202 	{ "-setclass",		"event audit_flags",	AC_ARG_SETCLASS},
203 	{ "-setestate",		"event audit_flags",	AC_ARG_SETESTATE},
204 	{ "-setfsize",		"filesize",		AC_ARG_SETFSIZE},
205 	{ "-setkaudit",		"type IP_address",	AC_ARG_SETKAUDIT},
206 	{ "-setkernstate",	"audit_flags",		AC_ARG_SETKERNSTATE},
207 	{ "-setkmask",		"audit_flags",		AC_ARG_SETKMASK},
208 	{ "-setpmask",	"pid audit_flags [cmd]",	AC_ARG_SETPMASK},
209 	{ "-setpolicy",		"policy_flags",		AC_ARG_SETPOLICY},
210 	{ "-setqbufsz",		"bufsz",		AC_ARG_SETQBUFSZ},
211 	{ "-setqctrl",	"hiwater lowater bufsz delay",	AC_ARG_SETQCTRL},
212 	{ "-setqdelay",		"delay",		AC_ARG_SETQDELAY},
213 	{ "-setqhiwater",	"hiwater",		AC_ARG_SETQHIWATER},
214 	{ "-setqlowater",	"lowater",		AC_ARG_SETQLOWATER},
215 	{ "-setsmask",		"asid audit_flags",	AC_ARG_SETSMASK},
216 	{ "-setstat",		"",			AC_ARG_SETSTAT},
217 	{ "-settid",		"tid [cmd]",		AC_ARG_SETTERMID},
218 	{ "-setumask",		"user audit_flags",	AC_ARG_SETUMASK},
219 	{ "-setuseraudit",	"user audit_flags",	AC_ARG_SETUSERAUDIT}
220 };
221 
222 #define	ARG_TBL_SZ (sizeof (arg_table) / sizeof (struct arg_entry))
223 
224 static struct arg_entry arg2_table[] = {
225 	{ "-chkconf",	"",				AC_ARG_CHKCONF},
226 	{ "-conf",	"",				AC_ARG_CONF},
227 	{ "-getcond",	"",				AC_ARG_GETCOND},
228 	{ "-getclass",	"event",			AC_ARG_GETCLASS},
229 	{ "-setclass",	"event audit_flags",		AC_ARG_SETCLASS},
230 	{ "-lsevent",	"",				AC_ARG_LSEVENT},
231 	{ "-lspolicy",	"",				AC_ARG_LSPOLICY},
232 	{ "-getpolicy",	"",				AC_ARG_GETPOLICY},
233 	{ "-setpolicy",	"policy_flags",			AC_ARG_SETPOLICY},
234 	{ "-getstat",	"",				AC_ARG_GETSTAT},
235 	{ "-getpinfo",	"pid",				AC_ARG_GETPINFO},
236 	{ "-setpmask",	"pid audit_flags",		AC_ARG_SETPMASK},
237 	{ "-setsmask",	"asid audit_flags",		AC_ARG_SETSMASK},
238 	{ "-setumask",	"user audit_flags",		AC_ARG_SETUMASK},
239 	{ "-getfsize",	"",				AC_ARG_GETFSIZE},
240 	{ "-setfsize",	"filesize",			AC_ARG_SETFSIZE}
241 	};
242 
243 #define	ARG2_TBL_SZ (sizeof (arg2_table) / sizeof (struct arg_entry))
244 
245 static struct policy_entry policy_table[] = {
246 	{"ahlt",	AUDIT_AHLT,	NULL,
247 	    "halt machine if it can not record an async event"},
248 	{"arge",	AUDIT_ARGE,	NULL,
249 	    "include exec environment args in audit recs"},
250 	{"argv",	AUDIT_ARGV,	NULL,
251 	    "include exec command line args in audit recs"},
252 	{"cnt",		AUDIT_CNT,	NULL,
253 	    "when no more space, drop recs and keep a cnt"},
254 	{"group",	AUDIT_GROUP,	NULL,
255 	    "include supplementary groups in audit recs"},
256 	{"path",	AUDIT_PATH,	NULL,
257 	    "allow multiple paths per event"},
258 	{"public",	AUDIT_PUBLIC,	NULL,	"audit public files"},
259 	{"seq",		AUDIT_SEQ,	NULL,
260 	    "include a sequence number in audit recs"},
261 	{"trail",	AUDIT_TRAIL,	NULL,
262 	    "include trailer token in audit recs"},
263 	{"windata_down",	AUDIT_WINDATA_DOWN,	AC_TSOL,
264 		"include downgraded information in audit recs"},
265 	{"windata_up",		AUDIT_WINDATA_UP,	AC_TSOL,
266 		"include upgraded information in audit recs"},
267 	{"zonename",	AUDIT_ZONENAME,	NULL,	"generate zonename token"},
268 	{"perzone",	AUDIT_PERZONE,	NULL,
269 	    "use a separate queue and auditd per zone"},
270 	{"all",		ALL_POLICIES,	NULL,	"all policies"},
271 	{"none",	NO_POLICIES,	NULL,	"no policies"}
272 	};
273 
274 #define	POLICY_TBL_SZ (sizeof (policy_table) / sizeof (struct policy_entry))
275 
276 static char *progname;
277 
278 int	tsol_on;			/* is TSOL installed? */
279 
280 static au_event_ent_t *egetauevnam();
281 static au_event_ent_t *egetauevnum();
282 static char *strtolower();
283 static int arg_ent_compare();
284 static int cond2str();
285 static int policy2str();
286 static int str2type();
287 static int str2policy();
288 static int str2ipaddr();
289 static int strisflags();
290 static int strisipaddr();
291 static int strisnum();
292 static struct arg_entry *get_arg_ent();
293 static struct policy_entry *get_policy_ent();
294 static uid_t get_user_id();
295 static void chk_event_num();
296 static void chk_event_str();
297 static void chk_retval();
298 static void chk_sorf();
299 static void chk_tid();
300 static void do_aconf();
301 static void do_args();
302 static void do_audit();
303 static void do_chkaconf();
304 static void do_chkconf();
305 static void do_conf();
306 static void do_getasid();
307 static void do_getaudit();
308 static void do_getkaudit();
309 static void do_setkaudit();
310 static void do_getauid();
311 static void do_getcar();
312 static void do_getclass();
313 static void do_getcond();
314 static void do_getcwd();
315 static void do_getkmask();
316 static void do_getpinfo();
317 static void do_getpolicy();
318 static void do_getqbufsz();
319 static void do_getqctrl();
320 static void do_getqdelay();
321 static void do_getqhiwater();
322 static void do_getqlowater();
323 static void do_getstat();
324 static void do_gettermid();
325 static void do_getuseraudit();
326 static void do_lsevent();
327 static void do_lspolicy();
328 static void do_setasid();
329 static void do_setaudit();
330 static void do_setauid();
331 static void do_setclass();
332 static void do_setkmask();
333 static void do_setpmask();
334 static void do_setsmask();
335 static void do_setumask();
336 static void do_setpolicy();
337 static void do_setqbufsz();
338 static void do_setqctrl();
339 static void do_setqdelay();
340 static void do_setqhiwater();
341 static void do_setqlowater();
342 static void do_setstat();
343 static void do_settid();
344 static void do_setuseraudit();
345 static void do_getfsize();
346 static void do_setfsize();
347 static void str2mask();
348 static void str2tid();
349 static void strsplit();
350 
351 static void eauditon();
352 static void egetaudit();
353 static void egetkaudit();
354 static void esetkaudit();
355 static void egetauditflagsbin();
356 static void egetauid();
357 static void esetaudit();
358 static void esetauid();
359 static void execit();
360 static void exit_error(char *, ...);
361 static void exit_usage();
362 static void parse_args();
363 static void print_asid();
364 static void print_auid();
365 static void print_mask();
366 static void print_mask1();
367 static void print_stats();
368 static void print_tid_ex();
369 
370 int
371 main(argc, argv)
372 	int argc;
373 	char **argv;
374 {
375 	progname = "auditconfig";
376 
377 	(void) setlocale(LC_ALL, "");
378 	(void) textdomain(TEXT_DOMAIN);
379 
380 	if (argc == 1) {
381 		exit_usage(0);
382 		exit(0);
383 	}
384 
385 	if (argc == 2 &&
386 		(argv[1][0] == '?' ||
387 		strcmp(argv[1], "-h") == 0 ||
388 		strcmp(argv[1], "-?") == 0))
389 		exit_usage(0);
390 
391 	tsol_on = is_system_labeled();
392 
393 	parse_args(argv);
394 
395 	do_args(argv);
396 
397 	return (0);
398 }
399 
400 /*
401  * parse_args()
402  *     Desc: Checks command line argument syntax.
403  *     Inputs: Command line argv;
404  *     Returns: If a syntax error is detected, a usage message is printed
405  *              and exit() is called. If a syntax error is not detected,
406  *              parse_args() returns without a value.
407  */
408 static void
409 parse_args(char **argv)
410 {
411 	struct arg_entry *ae;
412 
413 	au_mask_t pmask;
414 	au_mask_t smask;
415 	au_mask_t umask;
416 	uint_t type;
417 	uint_t addr[4];
418 
419 	for (++argv; *argv; argv++) {
420 		if ((ae = get_arg_ent(*argv)) == (struct arg_entry *)0) {
421 			exit_usage(1);
422 		}
423 
424 		switch (ae->auditconfig_cmd) {
425 
426 		case AC_ARG_AUDIT:
427 			++argv;
428 			if (!*argv)
429 				exit_usage(1);
430 			if (strisnum(*argv)) {
431 				chk_event_num(AC_USER_EVENT,
432 					(au_event_t)atol(*argv));
433 			} else
434 				chk_event_str(AC_USER_EVENT, *argv);
435 			++argv;
436 			if (!*argv)
437 				exit_usage(1);
438 			chk_sorf(*argv);
439 			++argv;
440 			if (!*argv)
441 				exit_usage(1);
442 			chk_retval(*argv);
443 			++argv;
444 			if (!*argv)
445 				exit_usage(1);
446 			break;
447 
448 		case AC_ARG_CHKCONF:
449 			break;
450 
451 		case AC_ARG_CONF:
452 			break;
453 
454 		case AC_ARG_ACONF:
455 			break;
456 
457 		case AC_ARG_CHKACONF:
458 			break;
459 
460 		case AC_ARG_GETASID:
461 		case AC_ARG_GETSID:
462 			break;
463 
464 		case AC_ARG_GETAUID:
465 			break;
466 
467 		case AC_ARG_GETAUDIT:
468 			break;
469 
470 		case AC_ARG_GETKAUDIT:
471 			break;
472 
473 		case AC_ARG_GETCLASS:
474 		case AC_ARG_GETESTATE:
475 			++argv;
476 			if (!*argv)
477 				exit_usage(1);
478 			if (strisnum(*argv))
479 				chk_event_num(AC_KERN_EVENT,
480 					(au_event_t)atol(*argv));
481 			else
482 				chk_event_str(AC_KERN_EVENT, *argv);
483 			break;
484 
485 		case AC_ARG_GETCAR:
486 			break;
487 
488 		case AC_ARG_GETCOND:
489 			break;
490 
491 		case AC_ARG_GETCWD:
492 			break;
493 
494 		case AC_ARG_GETKERNSTATE:
495 		case AC_ARG_GETKMASK:
496 			break;
497 
498 		case AC_ARG_GETPOLICY:
499 			break;
500 
501 		case AC_ARG_GETQBUFSZ:
502 			break;
503 
504 		case AC_ARG_GETQCTRL:
505 			break;
506 
507 		case AC_ARG_GETQDELAY:
508 			break;
509 
510 		case AC_ARG_GETQHIWATER:
511 			break;
512 
513 		case AC_ARG_GETQLOWATER:
514 			break;
515 
516 		case AC_ARG_GETSTAT:
517 			break;
518 
519 		case AC_ARG_GETTERMID:
520 			break;
521 
522 		case AC_ARG_GETUSERAUDIT:
523 			++argv;
524 			if (!*argv)
525 				exit_usage(1);
526 			break;
527 
528 		case AC_ARG_LSEVENT:
529 			break;
530 
531 		case AC_ARG_LSPOLICY:
532 			break;
533 
534 		case AC_ARG_SETASID:
535 			++argv;
536 			if (!*argv)
537 				exit_usage(1);
538 
539 			while (*argv)
540 				++argv;
541 			--argv;
542 
543 			break;
544 
545 		case AC_ARG_SETAUID:
546 			++argv;
547 			if (!*argv)
548 				exit_usage(1);
549 
550 			while (*argv)
551 				++argv;
552 			--argv;
553 
554 			break;
555 
556 		case AC_ARG_SETAUDIT:
557 			++argv;
558 			if (!*argv)
559 				exit_usage(1);
560 
561 			while (*argv)
562 				++argv;
563 			--argv;
564 
565 			break;
566 
567 		case AC_ARG_SETKAUDIT:
568 			++argv;
569 			if (!*argv)
570 				exit_usage(1);
571 			if (str2type (*argv, &type))
572 				exit_error(gettext(
573 					"Invalid IP address type specified."));
574 			++argv;
575 			if (!*argv)
576 				exit_usage(1);
577 
578 			if (str2ipaddr(*argv, addr, type))
579 				exit_error(gettext(
580 					"Invalid IP address specified."));
581 			break;
582 
583 		case AC_ARG_SETCLASS:
584 		case AC_ARG_SETESTATE:
585 			++argv;
586 			if (!*argv)
587 				exit_usage(1);
588 			if (strisnum(*argv))
589 				chk_event_num(AC_KERN_EVENT,
590 					(au_event_t)atol(*argv));
591 			else
592 				chk_event_str(AC_KERN_EVENT, *argv);
593 			++argv;
594 			if (!*argv)
595 				exit_usage(1);
596 			str2mask(*argv, &pmask);
597 			break;
598 
599 		case AC_ARG_SETKERNSTATE:
600 		case AC_ARG_SETKMASK:
601 			++argv;
602 			if (!*argv)
603 				exit_usage(1);
604 			str2mask(*argv, &pmask);
605 			break;
606 
607 		case AC_ARG_SETPOLICY:
608 			++argv;
609 			if (!*argv)
610 				exit_usage(1);
611 			break;
612 
613 		case AC_ARG_SETSTAT:
614 			break;
615 
616 		case AC_ARG_GETPINFO:
617 			++argv;
618 			if (!*argv)
619 				exit_usage(1);
620 			break;
621 
622 		case AC_ARG_SETPMASK:
623 			++argv;
624 			if (!*argv)
625 				exit_usage(1);
626 			++argv;
627 			if (!*argv)
628 				exit_usage(1);
629 			str2mask(*argv, &pmask);
630 			break;
631 
632 		case AC_ARG_SETQBUFSZ:
633 			++argv;
634 			if (!*argv)
635 				exit_usage(1);
636 			if (!strisnum(*argv))
637 				exit_error(gettext("Invalid bufsz specified."));
638 			break;
639 
640 		case AC_ARG_SETQCTRL:
641 			++argv;
642 			if (!*argv)
643 				exit_usage(1);
644 			if (!strisnum(*argv))
645 				exit_error(gettext(
646 					"Invalid hiwater specified."));
647 			++argv;
648 			if (!*argv)
649 				exit_usage(1);
650 			if (!strisnum(*argv))
651 				exit_error(gettext(
652 					gettext("Invalid lowater specified.")));
653 			++argv;
654 			if (!*argv)
655 				exit_usage(1);
656 			if (!strisnum(*argv))
657 				exit_error(gettext("Invalid bufsz specified."));
658 			++argv;
659 			if (!*argv)
660 				exit_usage(1);
661 			if (!strisnum(*argv))
662 				exit_error(gettext("Invalid delay specified."));
663 			break;
664 
665 		case AC_ARG_SETQDELAY:
666 			++argv;
667 			if (!*argv)
668 				exit_usage(1);
669 			if (!strisnum(*argv))
670 				exit_error(gettext("Invalid delay specified."));
671 			break;
672 
673 		case AC_ARG_SETQHIWATER:
674 			++argv;
675 			if (!*argv)
676 				exit_usage(1);
677 			if (!strisnum(*argv))
678 				exit_error(gettext(
679 					"Invalid hiwater specified."));
680 			break;
681 
682 		case AC_ARG_SETQLOWATER:
683 			++argv;
684 			if (!*argv)
685 				exit_usage(1);
686 			if (!strisnum(*argv))
687 				exit_error(gettext(
688 					"Invalid lowater specified."));
689 			break;
690 
691 		case AC_ARG_SETTERMID:
692 			++argv;
693 			if (!*argv)
694 				exit_usage(1);
695 			chk_tid(*argv);
696 			break;
697 
698 		case AC_ARG_SETUSERAUDIT:
699 			++argv;
700 			if (!*argv)
701 				exit_usage(1);
702 			++argv;
703 			if (!*argv)
704 				exit_usage(1);
705 			break;
706 		case AC_ARG_SETSMASK:
707 			++argv;
708 			if (!*argv)
709 				exit_usage(1);
710 			++argv;
711 			if (!*argv)
712 				exit_usage(1);
713 			str2mask(*argv, &smask);
714 			break;
715 
716 		case AC_ARG_SETUMASK:
717 			++argv;
718 			if (!*argv)
719 				exit_usage(1);
720 			++argv;
721 			if (!*argv)
722 				exit_usage(1);
723 			str2mask(*argv, &umask);
724 			break;
725 
726 		case AC_ARG_GETFSIZE:
727 			break;
728 
729 		case AC_ARG_SETFSIZE:
730 			++argv;
731 			if (!*argv)
732 				exit_usage(1);
733 			if (!strisnum(*argv))
734 				exit_error(gettext(
735 					"Invalid hiwater specified."));
736 			break;
737 
738 		default:
739 			exit_error(gettext("Internal error #1."));
740 			break;
741 
742 
743 		}
744 	}
745 }
746 
747 
748 /*
749  * do_args()
750  *     Desc: Do command line arguments in the order in which they appear.
751  */
752 static void
753 do_args(argv)
754 	char **argv;
755 {
756 	struct arg_entry *ae;
757 
758 	for (++argv; *argv; argv++) {
759 		ae = get_arg_ent(*argv);
760 
761 		switch (ae->auditconfig_cmd) {
762 
763 		case AC_ARG_AUDIT:
764 			{
765 				char sorf;
766 				int  retval;
767 				char *event_name;
768 				char *audit_str;
769 
770 				++argv;
771 				event_name = *argv;
772 				++argv;
773 				sorf = (char)atoi(*argv);
774 				++argv;
775 				retval = atoi(*argv);
776 				++argv;
777 				audit_str = *argv;
778 				do_audit(event_name, sorf, retval, audit_str);
779 			}
780 			break;
781 
782 		case AC_ARG_CHKCONF:
783 			do_chkconf();
784 			break;
785 
786 		case AC_ARG_CONF:
787 			do_conf();
788 			break;
789 
790 		case AC_ARG_CHKACONF:
791 			do_chkaconf();
792 			break;
793 
794 		case AC_ARG_ACONF:
795 			do_aconf();
796 			break;
797 
798 		case AC_ARG_GETASID:
799 		case AC_ARG_GETSID:
800 			do_getasid();
801 			break;
802 
803 		case AC_ARG_GETAUID:
804 			do_getauid();
805 			break;
806 
807 		case AC_ARG_GETAUDIT:
808 			do_getaudit();
809 			break;
810 
811 		case AC_ARG_GETKAUDIT:
812 			do_getkaudit();
813 			break;
814 
815 		case AC_ARG_GETCLASS:
816 		case AC_ARG_GETESTATE:
817 			++argv;
818 			do_getclass(*argv);
819 			break;
820 
821 		case AC_ARG_GETCAR:
822 			do_getcar();
823 			break;
824 
825 		case AC_ARG_GETCOND:
826 			do_getcond();
827 			break;
828 
829 		case AC_ARG_GETCWD:
830 			do_getcwd();
831 			break;
832 
833 		case AC_ARG_GETKERNSTATE:
834 		case AC_ARG_GETKMASK:
835 			do_getkmask();
836 			break;
837 
838 		case AC_ARG_GETPOLICY:
839 			do_getpolicy();
840 			break;
841 
842 		case AC_ARG_GETQBUFSZ:
843 			do_getqbufsz();
844 			break;
845 
846 		case AC_ARG_GETQCTRL:
847 			do_getqctrl();
848 			break;
849 
850 		case AC_ARG_GETQDELAY:
851 			do_getqdelay();
852 			break;
853 
854 		case AC_ARG_GETQHIWATER:
855 			do_getqhiwater();
856 			break;
857 
858 		case AC_ARG_GETQLOWATER:
859 			do_getqlowater();
860 			break;
861 
862 		case AC_ARG_GETSTAT:
863 			do_getstat();
864 			break;
865 
866 		case AC_ARG_GETTERMID:
867 			do_gettermid();
868 			break;
869 
870 		case AC_ARG_GETUSERAUDIT:
871 			++argv;
872 			do_getuseraudit(*argv);
873 			break;
874 
875 		case AC_ARG_LSEVENT:
876 			do_lsevent();
877 			break;
878 
879 		case AC_ARG_LSPOLICY:
880 			do_lspolicy();
881 			break;
882 
883 		case AC_ARG_SETASID:
884 			{
885 				char *sid_str;
886 
887 				++argv;
888 				sid_str = *argv;
889 				++argv;
890 				do_setasid(sid_str, argv);
891 			}
892 			break;
893 
894 		case AC_ARG_SETAUID:
895 			{
896 				char *user;
897 
898 				++argv;
899 				user = *argv;
900 				++argv;
901 				do_setauid(user, argv);
902 			}
903 			break;
904 
905 		case AC_ARG_SETAUDIT:
906 			{
907 				char *user_str;
908 				char *mask_str;
909 				char *tid_str;
910 				char *sid_str;
911 
912 				++argv;
913 				user_str = *argv;
914 				++argv;
915 				mask_str = *argv;
916 				++argv;
917 				tid_str = *argv;
918 				++argv;
919 				sid_str = *argv;
920 				++argv;
921 				do_setaudit(user_str, mask_str,
922 				    tid_str, sid_str, argv);
923 			}
924 			break;
925 
926 		case AC_ARG_SETKAUDIT:
927 			{
928 				char *address_type, *address;
929 
930 				++argv; address_type = *argv;
931 				++argv; address = *argv;
932 				do_setkaudit(address_type, address);
933 			}
934 			break;
935 
936 		case AC_ARG_SETCLASS:
937 		case AC_ARG_SETESTATE:
938 			{
939 				char *event_str, *audit_flags;
940 
941 				++argv; event_str = *argv;
942 				++argv; audit_flags = *argv;
943 				do_setclass(event_str, audit_flags);
944 			}
945 			break;
946 
947 		case AC_ARG_SETKERNSTATE:
948 		case AC_ARG_SETKMASK:
949 			++argv;
950 			do_setkmask(*argv);
951 			break;
952 
953 		case AC_ARG_SETPOLICY:
954 			++argv;
955 			do_setpolicy(*argv);
956 			break;
957 
958 		case AC_ARG_GETPINFO:
959 			{
960 				char *pid_str;
961 
962 				++argv;
963 				pid_str = *argv;
964 				do_getpinfo(pid_str);
965 			}
966 			break;
967 
968 		case AC_ARG_SETPMASK:
969 			{
970 				char *pid_str;
971 				char *audit_flags;
972 
973 				++argv;
974 				pid_str = *argv;
975 				++argv;
976 				audit_flags = *argv;
977 				do_setpmask(pid_str, audit_flags);
978 			}
979 			break;
980 
981 		case AC_ARG_SETSTAT:
982 			do_setstat();
983 			break;
984 
985 		case AC_ARG_SETQBUFSZ:
986 			++argv;
987 			do_setqbufsz(*argv);
988 			break;
989 
990 		case AC_ARG_SETQCTRL:
991 			{
992 				char *hiwater, *lowater, *bufsz, *delay;
993 
994 				++argv; hiwater = *argv;
995 				++argv; lowater = *argv;
996 				++argv; bufsz = *argv;
997 				++argv; delay = *argv;
998 				do_setqctrl(hiwater, lowater, bufsz, delay);
999 			}
1000 			break;
1001 		case AC_ARG_SETQDELAY:
1002 			++argv;
1003 			do_setqdelay(*argv);
1004 			break;
1005 
1006 		case AC_ARG_SETQHIWATER:
1007 			++argv;
1008 			do_setqhiwater(*argv);
1009 			break;
1010 
1011 		case AC_ARG_SETQLOWATER:
1012 			++argv;
1013 			do_setqlowater(*argv);
1014 			break;
1015 
1016 		case AC_ARG_SETTERMID:
1017 			++argv;
1018 			do_settid(*argv);
1019 			break;
1020 
1021 		case AC_ARG_SETUSERAUDIT:
1022 			{
1023 				char *user;
1024 				char *aflags;
1025 
1026 				++argv;
1027 				user = *argv;
1028 				++argv;
1029 				aflags = *argv;
1030 				do_setuseraudit(user, aflags);
1031 			}
1032 			break;
1033 		case AC_ARG_SETSMASK:
1034 			{
1035 				char *asid_str;
1036 				char *audit_flags;
1037 
1038 				++argv;
1039 				asid_str = *argv;
1040 				++argv;
1041 				audit_flags = *argv;
1042 				do_setsmask(asid_str, audit_flags);
1043 			}
1044 			break;
1045 		case AC_ARG_SETUMASK:
1046 			{
1047 				char *auid_str;
1048 				char *audit_flags;
1049 
1050 				++argv;
1051 				auid_str = *argv;
1052 				++argv;
1053 				audit_flags = *argv;
1054 				do_setumask(auid_str, audit_flags);
1055 			}
1056 			break;
1057 		case AC_ARG_GETFSIZE:
1058 			do_getfsize();
1059 			break;
1060 		case AC_ARG_SETFSIZE:
1061 			++argv;
1062 			do_setfsize(*argv);
1063 			break;
1064 
1065 		default:
1066 			exit_error(gettext("Internal error #2."));
1067 			break;
1068 
1069 		}
1070 	}
1071 
1072 }
1073 
1074 /*
1075  * The returned value is for the global zone unless AUDIT_PERZONE is
1076  * set.
1077  */
1078 
1079 static void
1080 do_chkconf()
1081 {
1082 	register au_event_ent_t *evp;
1083 	au_mask_t pmask;
1084 	char conf_aflags[256];
1085 	char run_aflags[256];
1086 	au_stat_t as;
1087 	int class;
1088 	int			len;
1089 	struct au_evclass_map	cmap;
1090 
1091 	pmask.am_success = pmask.am_failure = 0;
1092 	eauditon(A_GETSTAT, (caddr_t)&as, 0);
1093 
1094 	setauevent();
1095 	if ((evp = getauevent()) == (au_event_ent_t *)NULL) {
1096 		(void) exit_error(gettext(
1097 			"NO AUDIT EVENTS: Could not read %s\n."),
1098 			AUDITEVENTFILE);
1099 	}
1100 
1101 	setauevent();
1102 	while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
1103 		cmap.ec_number = evp->ae_number;
1104 		len = sizeof (struct au_evclass_map);
1105 		if (evp->ae_number <= as.as_numevent)
1106 			if (auditon(A_GETCLASS, (caddr_t)&cmap, len) == -1) {
1107 				(void) printf("%s(%d):%s",
1108 				evp->ae_name, evp->ae_number, gettext(
1109 "UNKNOWN EVENT: Could not get class for event. Configuration may be bad.\n"));
1110 			} else {
1111 				class = cmap.ec_class;
1112 				if (class != evp->ae_class) {
1113 					conf_aflags[0] = run_aflags[0] = '\0';
1114 					pmask.am_success = class;
1115 					pmask.am_failure = class;
1116 					(void) getauditflagschar(run_aflags,
1117 						&pmask, 0);
1118 					pmask.am_success = evp->ae_class;
1119 					pmask.am_failure = evp->ae_class;
1120 					(void) getauditflagschar(conf_aflags,
1121 						&pmask, 0);
1122 
1123 					(void) printf(gettext(
1124 "%s(%d): CLASS MISMATCH: runtime class (%s) != configured class (%s)\n"),
1125 					evp->ae_name, evp->ae_number,
1126 					NONE(run_aflags), NONE(conf_aflags));
1127 				}
1128 			}
1129 	}
1130 	endauevent();
1131 
1132 }
1133 
1134 /*
1135  * The returned value is for the global zone unless AUDIT_PERZONE is
1136  * set.
1137  */
1138 static void
1139 do_conf()
1140 {
1141 	register au_event_ent_t *evp;
1142 	register int i;
1143 	au_evclass_map_t ec;
1144 	au_stat_t as;
1145 
1146 	eauditon(A_GETSTAT, (caddr_t)&as, 0);
1147 
1148 	i = 0;
1149 	setauevent();
1150 	while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
1151 		if (evp->ae_number <= as.as_numevent) {
1152 			++i;
1153 			ec.ec_number = evp->ae_number;
1154 			ec.ec_class = evp->ae_class;
1155 			eauditon(A_SETCLASS, (caddr_t)&ec, (int)sizeof (ec));
1156 		}
1157 	}
1158 	endauevent();
1159 	(void) printf(gettext("Configured %d kernel events.\n"), i);
1160 
1161 }
1162 
1163 /*
1164  * The returned value is for the global zone unless AUDIT_PERZONE is
1165  * set.
1166  */
1167 
1168 static void
1169 do_chkaconf()
1170 {
1171 	char buf[1024];
1172 	au_mask_t pmask, kmask;
1173 
1174 	if (getacna(buf, sizeof (buf)) < 0) {
1175 		(void) fprintf(stderr,
1176 		    gettext("bad non-attributable flags in audit_control\n"));
1177 		exit(1);
1178 	}
1179 
1180 	if (getauditflagsbin(buf, &pmask) < 0) {
1181 		(void) fprintf(stderr,
1182 		    gettext("bad audit flag value encountered\n"));
1183 		exit(1);
1184 	}
1185 
1186 	eauditon(A_GETKMASK, (caddr_t)&kmask, (int)sizeof (kmask));
1187 
1188 	if ((pmask.am_success != kmask.am_success) ||
1189 	    (pmask.am_failure != kmask.am_failure)) {
1190 		char kbuf[2048];
1191 		if (getauditflagschar(kbuf, &kmask, 0) < 0) {
1192 			(void) fprintf(stderr,
1193 			    gettext("bad kernel non-attributable mask\n"));
1194 			exit(1);
1195 		}
1196 		(void) printf(gettext("non-attributable event mismatch "));
1197 		(void) printf(gettext("audit_control(%s) kernel(%s)\n"),
1198 			buf, kbuf);
1199 	}
1200 }
1201 
1202 /*
1203  * The returned value is for the global zone unless AUDIT_PERZONE is
1204  * set.
1205  */
1206 
1207 static void
1208 do_aconf()
1209 {
1210 	char buf[2048];
1211 	au_mask_t pmask;
1212 
1213 	if (getacna(buf, sizeof (buf)) < 0) {
1214 		(void) fprintf(stderr,
1215 		    gettext("bad non-attributable flags in audit_control\n"));
1216 		exit(1);
1217 	}
1218 
1219 	if (getauditflagsbin(buf, &pmask) < 0) {
1220 		(void) fprintf(stderr,
1221 		    gettext("bad audit flag value encountered\n"));
1222 		exit(1);
1223 	}
1224 
1225 	eauditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
1226 
1227 	(void) printf(gettext("Configured non-attributable events.\n"));
1228 }
1229 
1230 static void
1231 do_audit(event, sorf, retval, audit_str)
1232 	char *event;
1233 	char sorf;
1234 	int retval;
1235 	char *audit_str;
1236 {
1237 	int rtn;
1238 	int rd;
1239 	au_event_t event_num;
1240 	au_event_ent_t *evp;
1241 	auditinfo_addr_t ai;
1242 	token_t *tokp;
1243 
1244 	egetaudit(&ai, sizeof (ai));
1245 
1246 	if (strisnum(event)) {
1247 		event_num = (au_event_t)atoi(event);
1248 		evp = egetauevnum(event_num);
1249 	} else
1250 		evp = egetauevnam(event);
1251 
1252 	rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
1253 		AU_PRS_USECACHE);
1254 
1255 	if (rtn == -1)
1256 		exit_error("%s\n%s %d\n",
1257 			gettext("Check audit event configuration."),
1258 			gettext("Could not get audit class for event number"),
1259 			evp->ae_number);
1260 
1261 	/* record is preselected */
1262 	if (rtn == 1) {
1263 		if ((rd = au_open()) == -1)
1264 			exit_error(gettext(
1265 				"Could not get and audit record descriptor\n"));
1266 		if ((tokp = au_to_me()) == (token_t *)NULL)
1267 			exit_error(gettext(
1268 				"Could not allocate subject token\n"));
1269 		if (au_write(rd, tokp) == -1)
1270 exit_error(gettext("Could not construct subject token of audit record\n"));
1271 
1272 		if (tsol_on) {
1273 			if ((tokp = au_to_mylabel()) == (token_t *)NULL)
1274 				exit_error(gettext(
1275 				    "Could not allocate slabel token\n"));
1276 			if (au_write(rd, tokp) == -1)
1277 exit_error(gettext("Could not construct slabel token of audit record\n"));
1278 		}
1279 
1280 		if ((tokp = au_to_text(audit_str)) == (token_t *)NULL)
1281 			exit_error(gettext("Could not allocate text token\n"));
1282 		if (au_write(rd, tokp) == -1)
1283 exit_error(gettext("Could not construct text token of audit record\n"));
1284 #ifdef _LP64
1285 		if ((tokp = au_to_return64(sorf, retval)) == (token_t *)NULL)
1286 #else
1287 		if ((tokp = au_to_return32(sorf, retval)) == (token_t *)NULL)
1288 #endif
1289 			exit_error(gettext(
1290 				"Could not allocate return token\n"));
1291 		if (au_write(rd, tokp) == -1)
1292 			exit_error(gettext(
1293 			"Could not construct return token of audit record\n"));
1294 		if (au_close(rd, 1, evp->ae_number) == -1)
1295 			exit_error(gettext(
1296 				"Could not write audit record: %s\n"),
1297 					strerror(errno));
1298 	}
1299 }
1300 
1301 static void
1302 do_getauid()
1303 {
1304 	au_id_t auid;
1305 
1306 	egetauid(&auid);
1307 	print_auid(auid);
1308 }
1309 
1310 static void
1311 do_getaudit()
1312 {
1313 	auditinfo_addr_t ai;
1314 
1315 	egetaudit(&ai, sizeof (ai));
1316 	print_auid(ai.ai_auid);
1317 	print_mask(gettext("process preselection mask"), &ai.ai_mask);
1318 	print_tid_ex(&ai.ai_termid);
1319 	print_asid(ai.ai_asid);
1320 }
1321 
1322 static void
1323 do_getkaudit()
1324 {
1325 	auditinfo_addr_t ai;
1326 
1327 	egetkaudit(&ai, sizeof (ai));
1328 	print_auid(ai.ai_auid);
1329 	print_mask(gettext("process preselection mask"), &ai.ai_mask);
1330 	print_tid_ex(&ai.ai_termid);
1331 	print_asid(ai.ai_asid);
1332 }
1333 
1334 /*
1335  * per zone if AUDIT_PERZONE set, else only in global zone.
1336  */
1337 
1338 static void
1339 do_setkaudit(t, s)
1340 	char *t;
1341 	char *s;
1342 {
1343 	uint_t type;
1344 	auditinfo_addr_t ai;
1345 
1346 	egetkaudit(&ai, sizeof (ai));
1347 	(void) str2type(t, &type);
1348 	(void) str2ipaddr(s, &ai.ai_termid.at_addr[0], type);
1349 	ai.ai_termid.at_type = type;
1350 	esetkaudit(&ai, sizeof (ai));
1351 }
1352 
1353 /*
1354  * returns zone-relative root
1355  */
1356 
1357 static void
1358 do_getcar()
1359 {
1360 	char path[MAXPATHLEN];
1361 
1362 	eauditon(A_GETCAR, (caddr_t)path, (int)sizeof (path));
1363 	(void) printf(gettext("current active root = %s\n"), path);
1364 }
1365 
1366 /*
1367  * The returned value is for the global zone unless AUDIT_PERZONE is
1368  * set.
1369  */
1370 
1371 static void
1372 do_getclass(event_str)
1373 	char *event_str;
1374 {
1375 	au_evclass_map_t ec;
1376 	au_event_ent_t *evp;
1377 	au_event_t event_number;
1378 	char *event_name;
1379 	char desc[256];
1380 
1381 	if (strisnum(event_str)) {
1382 		event_number = atol(event_str);
1383 		if ((evp = egetauevnum(event_number)) !=
1384 				(au_event_ent_t *)NULL) {
1385 			event_number = evp->ae_number;
1386 			event_name = evp->ae_name;
1387 		} else
1388 			event_name = gettext("unknown");
1389 	} else {
1390 		event_name = event_str;
1391 		if ((evp = egetauevnam(event_str)) != (au_event_ent_t *)NULL)
1392 			event_number = evp->ae_number;
1393 	}
1394 
1395 	ec.ec_number = event_number;
1396 	eauditon(A_GETCLASS, (caddr_t)&ec, 0);
1397 
1398 	(void) sprintf(desc, gettext("audit class mask for event %s(%d)"),
1399 			event_name, event_number);
1400 	print_mask1(desc, ec.ec_class);
1401 }
1402 
1403 /*
1404  * The returned value is for the global zone unless AUDIT_PERZONE is
1405  * set.  (AUC_DISABLED is always global, the other states are per zone
1406  * if AUDIT_PERZONE is set)
1407  */
1408 
1409 static void
1410 do_getcond()
1411 {
1412 	char cond_str[16];
1413 	uint_t cond;
1414 
1415 	eauditon(A_GETCOND, (caddr_t)&cond, (int)sizeof (cond));
1416 
1417 	(void) cond2str(cond, cond_str);
1418 	(void) printf(gettext("audit condition = %s\n"), cond_str);
1419 }
1420 
1421 /*
1422  * returned path is relative to zone root
1423  */
1424 
1425 static void
1426 do_getcwd()
1427 {
1428 	char path[MAXPATHLEN];
1429 
1430 	eauditon(A_GETCWD, (caddr_t)path, (int)sizeof (path));
1431 	(void) printf(gettext("current working directory = %s\n"), path);
1432 }
1433 
1434 /*
1435  * The returned value is for the global zone unless AUDIT_PERZONE is
1436  * set.
1437  */
1438 
1439 static void
1440 do_getkmask()
1441 {
1442 	au_mask_t pmask;
1443 
1444 	eauditon(A_GETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
1445 	print_mask(gettext("audit flags for non-attributable events"), &pmask);
1446 }
1447 
1448 /*
1449  * The returned value is for the global zone unless AUDIT_PERZONE is
1450  * set. (some policies can only be set from the global zone, but all
1451  * can be read from anywhere.)
1452  */
1453 
1454 static void
1455 do_getpolicy()
1456 {
1457 	char policy_str[1024];
1458 	uint_t policy;
1459 
1460 	eauditon(A_GETPOLICY, (caddr_t)&policy, 0);
1461 	(void) policy2str(policy, policy_str, sizeof (policy_str));
1462 	(void) printf(gettext("audit policies = %s\n"), policy_str);
1463 }
1464 
1465 static void
1466 do_getpinfo(pid_str)
1467 	char *pid_str;
1468 {
1469 	struct auditpinfo_addr ap;
1470 
1471 	if (strisnum(pid_str))
1472 		ap.ap_pid = (pid_t)atoi(pid_str);
1473 	else
1474 		exit_usage(1);
1475 
1476 	eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
1477 
1478 	print_auid(ap.ap_auid);
1479 	print_mask(gettext("process preselection mask"), &(ap.ap_mask));
1480 	print_tid_ex(&(ap.ap_termid));
1481 	print_asid(ap.ap_asid);
1482 }
1483 
1484 /*
1485  * The returned value is for the global zone unless AUDIT_PERZONE is
1486  * set.
1487  */
1488 
1489 static void
1490 do_getqbufsz()
1491 {
1492 	struct au_qctrl qctrl;
1493 
1494 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1495 	(void) printf(gettext("audit queue buffer size (bytes) = %ld\n"),
1496 		qctrl.aq_bufsz);
1497 }
1498 
1499 /*
1500  * The returned value is for the global zone unless AUDIT_PERZONE is
1501  * set.
1502  */
1503 
1504 static void
1505 do_getqctrl()
1506 {
1507 	struct au_qctrl qctrl;
1508 
1509 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1510 	(void) printf(gettext("audit queue hiwater mark (records) = %ld\n"),
1511 		qctrl.aq_hiwater);
1512 	(void) printf(gettext("audit queue lowater mark (records) = %ld\n"),
1513 		qctrl.aq_lowater);
1514 	(void) printf(gettext("audit queue buffer size (bytes) = %ld\n"),
1515 		qctrl.aq_bufsz);
1516 	(void) printf(gettext("audit queue delay (ticks) = %ld\n"),
1517 		qctrl.aq_delay);
1518 }
1519 
1520 /*
1521  * The returned value is for the global zone unless AUDIT_PERZONE is
1522  * set.
1523  */
1524 
1525 static void
1526 do_getqdelay()
1527 {
1528 	struct au_qctrl qctrl;
1529 
1530 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1531 	(void) printf(gettext("audit queue delay (ticks) = %ld\n"),
1532 		qctrl.aq_delay);
1533 }
1534 
1535 /*
1536  * The returned value is for the global zone unless AUDIT_PERZONE is
1537  * set.
1538  */
1539 
1540 static void
1541 do_getqhiwater()
1542 {
1543 	struct au_qctrl qctrl;
1544 
1545 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1546 	(void) printf(gettext("audit queue hiwater mark (records) = %ld\n"),
1547 		qctrl.aq_hiwater);
1548 }
1549 
1550 /*
1551  * The returned value is for the global zone unless AUDIT_PERZONE is
1552  * set.
1553  */
1554 
1555 static void
1556 do_getqlowater()
1557 {
1558 	struct au_qctrl qctrl;
1559 
1560 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1561 	(void) printf(gettext("audit queue lowater mark (records) = %ld\n"),
1562 		qctrl.aq_lowater);
1563 }
1564 
1565 static void
1566 do_getasid()
1567 {
1568 	auditinfo_addr_t ai;
1569 
1570 	if (getaudit_addr(&ai, sizeof (ai))) {
1571 		exit_error(gettext("getaudit_addr(2) failed"));
1572 	}
1573 	print_asid(ai.ai_asid);
1574 }
1575 
1576 /*
1577  * The stats are for the entire system unless AUDIT_PERZONE is set.
1578  */
1579 
1580 static void
1581 do_getstat()
1582 {
1583 	au_stat_t as;
1584 
1585 	eauditon(A_GETSTAT, (caddr_t)&as, 0);
1586 	print_stats(&as);
1587 }
1588 
1589 static void
1590 do_gettermid()
1591 {
1592 	auditinfo_addr_t ai;
1593 
1594 	if (getaudit_addr(&ai, sizeof (ai))) {
1595 		exit_error(gettext("getaudit_addr(2) failed"));
1596 	}
1597 	print_tid_ex(&ai.ai_termid);
1598 }
1599 
1600 /*
1601  * The returned value is for the global zone unless AUDIT_PERZONE is
1602  * set.
1603  */
1604 
1605 static void
1606 do_getfsize()
1607 {
1608 	au_fstat_t fstat;
1609 
1610 	eauditon(A_GETFSIZE, (caddr_t)&fstat, 0);
1611 	(void) printf(gettext("Maximum file size %d, current file size %d\n"),
1612 		fstat.af_filesz, fstat.af_currsz);
1613 }
1614 
1615 /*ARGSUSED*/
1616 static void
1617 do_getuseraudit(user)
1618 char *user;
1619 {
1620 	(void) printf(gettext("-getuseraudit supported on SunOS CMW only.\n"));
1621 }
1622 
1623 /*
1624  * The returned value is for the global zone unless AUDIT_PERZONE is
1625  * set.
1626  */
1627 
1628 static void
1629 do_lsevent()
1630 {
1631 	register au_event_ent_t *evp;
1632 	au_mask_t pmask;
1633 	char auflags[256];
1634 
1635 	setauevent();
1636 	if ((evp = getauevent()) == (au_event_ent_t *)NULL) {
1637 		(void) exit_error(gettext(
1638 			"NO AUDIT EVENTS: Could not read %s\n."),
1639 			AUDITEVENTFILE);
1640 	}
1641 
1642 	setauevent();
1643 	while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
1644 		pmask.am_success = pmask.am_failure = evp->ae_class;
1645 		if (getauditflagschar(auflags, &pmask, 0) == -1)
1646 			(void) strcpy(auflags, "unknown");
1647 		(void) printf("%-30s %5d %s %s\n",
1648 			evp->ae_name, evp->ae_number, auflags, evp->ae_desc);
1649 	}
1650 	endauevent();
1651 }
1652 
1653 /*
1654  * The returned value is for the global zone unless AUDIT_PERZONE is
1655  * set.
1656  */
1657 
1658 static void
1659 do_lspolicy()
1660 {
1661 	int i;
1662 
1663 	/*
1664 	 * TRANSLATION_NOTE
1665 	 *	Print a properly aligned header.
1666 	 */
1667 	(void) printf(gettext("policy string    description:\n"));
1668 	for (i = 0; i < POLICY_TBL_SZ; i++) {
1669 		if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
1670 			continue;	/* skip this entry */
1671 		(void) printf("%-17s%s\n", policy_table[i].policy_str,
1672 		    gettext(policy_table[i].policy_desc));
1673 	}
1674 }
1675 
1676 static void
1677 do_setasid(sid_str, argv)
1678 	char *sid_str;
1679 	char **argv;
1680 {
1681 	struct auditinfo_addr ai;
1682 
1683 	if (getaudit_addr(&ai, sizeof (ai))) {
1684 		exit_error(gettext("getaudit_addr(2) failed"));
1685 	}
1686 	ai.ai_asid = (au_asid_t)atol(sid_str);
1687 	if (setaudit_addr(&ai, sizeof (ai))) {
1688 		exit_error(gettext("setaudit_addr(2) failed"));
1689 	}
1690 	execit(argv);
1691 }
1692 
1693 static void
1694 do_setaudit(user_str, mask_str, tid_str, sid_str, argv)
1695 	char *user_str;
1696 	char *mask_str;
1697 	char *tid_str;
1698 	char *sid_str;
1699 	char **argv;
1700 {
1701 	auditinfo_addr_t ai;
1702 
1703 	ai.ai_auid = (au_id_t)get_user_id(user_str);
1704 	str2mask(mask_str, &ai.ai_mask),
1705 	str2tid(tid_str, &ai.ai_termid);
1706 	ai.ai_asid = (au_asid_t)atol(sid_str);
1707 
1708 	esetaudit(&ai, sizeof (ai));
1709 	execit(argv);
1710 }
1711 
1712 static void
1713 do_setauid(user, argv)
1714 	char *user;
1715 	char **argv;
1716 {
1717 	au_id_t auid;
1718 
1719 	auid = get_user_id(user);
1720 	esetauid(&auid);
1721 	execit(argv);
1722 }
1723 
1724 static void
1725 do_setpmask(pid_str, audit_flags)
1726 	char *pid_str;
1727 	char *audit_flags;
1728 {
1729 	struct auditpinfo ap;
1730 
1731 	if (strisnum(pid_str))
1732 		ap.ap_pid = (pid_t)atoi(pid_str);
1733 	else
1734 		exit_usage(1);
1735 
1736 	str2mask(audit_flags, &ap.ap_mask);
1737 
1738 	eauditon(A_SETPMASK, (caddr_t)&ap, (int)sizeof (ap));
1739 }
1740 
1741 static void
1742 do_setsmask(asid_str, audit_flags)
1743 	char *asid_str;
1744 	char *audit_flags;
1745 {
1746 	struct auditinfo ainfo;
1747 
1748 	if (strisnum(asid_str))
1749 		ainfo.ai_asid = (pid_t)atoi(asid_str);
1750 	else
1751 		exit_usage(1);
1752 
1753 	str2mask(audit_flags, &ainfo.ai_mask);
1754 
1755 	eauditon(A_SETSMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
1756 }
1757 
1758 static void
1759 do_setumask(auid_str, audit_flags)
1760 	char *auid_str;
1761 	char *audit_flags;
1762 {
1763 	struct auditinfo ainfo;
1764 
1765 	if (strisnum(auid_str))
1766 		ainfo.ai_auid = (pid_t)atoi(auid_str);
1767 	else
1768 		exit_usage(1);
1769 
1770 	str2mask(audit_flags, &ainfo.ai_mask);
1771 
1772 	eauditon(A_SETUMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
1773 }
1774 
1775 /*
1776  * local zone use is valid if AUDIT_PERZONE is set, otherwise the
1777  * syscall returns EPERM.
1778  */
1779 
1780 static void
1781 do_setstat()
1782 {
1783 	au_stat_t as;
1784 
1785 	as.as_audit	= (uint_t)-1;
1786 	as.as_auditctl	= (uint_t)-1;
1787 	as.as_dropped	= (uint_t)-1;
1788 	as.as_enqueue	= (uint_t)-1;
1789 	as.as_generated	= (uint_t)-1;
1790 	as.as_kernel	= (uint_t)-1;
1791 	as.as_nonattrib	= (uint_t)-1;
1792 	as.as_rblocked	= (uint_t)-1;
1793 	as.as_totalsize	= (uint_t)-1;
1794 	as.as_wblocked	= (uint_t)-1;
1795 	as.as_written	= (uint_t)-1;
1796 
1797 	eauditon(A_SETSTAT, (caddr_t)&as, (int)sizeof (as));
1798 	(void) puts(gettext("audit stats reset"));
1799 }
1800 
1801 /*ARGSUSED*/
1802 static void
1803 do_setuseraudit(user, auditflags)
1804 	char *user;
1805 	char *auditflags;
1806 {
1807 	(void) printf(gettext("-setuseraudit supported on SunOS CMW only.\n"));
1808 }
1809 
1810 /*
1811  * AUDIT_PERZONE set:  valid in all zones
1812  * AUDIT_PERZONE not set: valid in global zone only
1813  */
1814 
1815 static void
1816 do_setclass(event_str, audit_flags)
1817 	char *event_str;
1818 	char *audit_flags;
1819 {
1820 	au_event_t event;
1821 	int mask;
1822 	au_mask_t pmask;
1823 	au_evclass_map_t ec;
1824 	au_event_ent_t *evp;
1825 
1826 	if (strisnum(event_str))
1827 		event = (uint_t)atol(event_str);
1828 	else {
1829 		if ((evp = egetauevnam(event_str)) != (au_event_ent_t *)NULL)
1830 			event = evp->ae_number;
1831 	}
1832 
1833 	if (strisnum(audit_flags))
1834 		mask = atoi(audit_flags);
1835 	else {
1836 		str2mask(audit_flags, &pmask);
1837 		mask = pmask.am_success | pmask.am_failure;
1838 	}
1839 
1840 	ec.ec_number = event;
1841 	ec.ec_class = mask;
1842 	eauditon(A_SETCLASS, (caddr_t)&ec, (int)sizeof (ec));
1843 }
1844 
1845 /*
1846  * AUDIT_PERZONE set:  valid in all zones
1847  * AUDIT_PERZONE not set: valid in global zone only
1848  */
1849 
1850 static void
1851 do_setkmask(audit_flags)
1852 char *audit_flags;
1853 {
1854 	au_mask_t pmask;
1855 
1856 	str2mask(audit_flags, &pmask);
1857 	eauditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
1858 	print_mask(gettext("audit flags for non-attributable events"), &pmask);
1859 }
1860 
1861 /*
1862  * ahlt and perzone are global zone only; the other policies are valid
1863  * in a local zone if AUDIT_PERZONE is set.  The kernel insures that
1864  * a local zone can't change ahlt and perzone (EINVAL).
1865  */
1866 
1867 static void
1868 do_setpolicy(policy_str)
1869 char *policy_str;
1870 {
1871 	uint_t	policy;
1872 
1873 	switch (str2policy(policy_str, &policy)) {
1874 	case 2:
1875 		exit_error(gettext(
1876 			"policy (%s) invalid in a local zone."),
1877 			policy_str);
1878 		break;
1879 	default:
1880 		exit_error(gettext(
1881 		    "Invalid policy (%s) specified."),
1882 		    policy_str);
1883 		break;
1884 	case 0:
1885 		eauditon(A_SETPOLICY, (caddr_t)&policy, 0);
1886 		break;
1887 	}
1888 }
1889 
1890 /*
1891  * AUDIT_PERZONE set:  valid in all zones
1892  * AUDIT_PERZONE not set: valid in global zone only
1893  */
1894 
1895 static void
1896 do_setqbufsz(bufsz)
1897 char *bufsz;
1898 {
1899 	struct au_qctrl qctrl;
1900 
1901 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1902 	qctrl.aq_bufsz = atol(bufsz);
1903 	eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
1904 }
1905 
1906 /*
1907  * AUDIT_PERZONE set:  valid in all zones
1908  * AUDIT_PERZONE not set: valid in global zone only
1909  */
1910 
1911 static void
1912 do_setqctrl(hiwater, lowater, bufsz, delay)
1913 	char *hiwater;
1914 	char *lowater;
1915 	char *bufsz;
1916 	char *delay;
1917 {
1918 	struct au_qctrl qctrl;
1919 
1920 	qctrl.aq_hiwater = atol(hiwater);
1921 	qctrl.aq_lowater = atol(lowater);
1922 	qctrl.aq_bufsz = atol(bufsz);
1923 	qctrl.aq_delay = atol(delay);
1924 	eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
1925 }
1926 
1927 /*
1928  * AUDIT_PERZONE set:  valid in all zones
1929  * AUDIT_PERZONE not set: valid in global zone only
1930  */
1931 
1932 static void
1933 do_setqdelay(delay)
1934 char *delay;
1935 {
1936 	struct au_qctrl qctrl;
1937 
1938 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1939 	qctrl.aq_delay = atol(delay);
1940 	eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
1941 }
1942 
1943 /*
1944  * AUDIT_PERZONE set:  valid in all zones
1945  * AUDIT_PERZONE not set: valid in global zone only
1946  */
1947 
1948 static void
1949 do_setqhiwater(hiwater)
1950 char *hiwater;
1951 {
1952 	struct au_qctrl qctrl;
1953 
1954 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1955 	qctrl.aq_hiwater = atol(hiwater);
1956 	eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
1957 }
1958 
1959 /*
1960  * AUDIT_PERZONE set:  valid in all zones
1961  * AUDIT_PERZONE not set: valid in global zone only
1962  */
1963 
1964 static void
1965 do_setqlowater(lowater)
1966 	char *lowater;
1967 {
1968 	struct au_qctrl qctrl;
1969 
1970 	eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1971 	qctrl.aq_lowater = atol(lowater);
1972 	eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
1973 }
1974 
1975 /*
1976  * AUDIT_PERZONE set:  valid in all zones
1977  * AUDIT_PERZONE not set: valid in global zone only
1978  */
1979 
1980 static void
1981 do_settid(char *tid_str)
1982 {
1983 	struct auditinfo_addr ai;
1984 
1985 	if (getaudit_addr(&ai, sizeof (ai))) {
1986 		exit_error(gettext("getaudit_addr(2) failed"));
1987 	}
1988 
1989 	str2tid(tid_str, &ai.ai_termid);
1990 
1991 	if (setaudit_addr(&ai, sizeof (ai))) {
1992 		exit_error(gettext("setaudit_addr(2) failed"));
1993 	}
1994 }
1995 
1996 /*
1997  * AUDIT_PERZONE set:  valid in all zones
1998  * AUDIT_PERZONE not set: valid in global zone only
1999  */
2000 
2001 static void
2002 do_setfsize(size)
2003 	char *size;
2004 {
2005 	au_fstat_t fstat;
2006 
2007 	fstat.af_filesz = atol(size);
2008 	eauditon(A_SETFSIZE, (caddr_t)&fstat, 0);
2009 }
2010 
2011 static void
2012 eauditon(cmd, data, length)
2013 	int cmd;
2014 	caddr_t data;
2015 	int length;
2016 {
2017 	if (auditon(cmd, data, length) == -1)
2018 		exit_error(gettext("auditon(2) failed."));
2019 }
2020 
2021 static void
2022 egetauid(auid)
2023 	au_id_t *auid;
2024 {
2025 	if (getauid(auid) == -1)
2026 		exit_error(gettext("getauid(2) failed."));
2027 }
2028 
2029 static void
2030 egetaudit(ai, size)
2031 	auditinfo_addr_t *ai;
2032 	int size;
2033 {
2034 	if (getaudit_addr(ai, size) == -1)
2035 		exit_error(gettext("getaudit_addr(2) failed."));
2036 }
2037 
2038 static void
2039 egetkaudit(ai, size)
2040 	auditinfo_addr_t *ai;
2041 	int size;
2042 {
2043 	if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
2044 		exit_error(gettext("auditon: A_GETKAUDIT failed."));
2045 }
2046 
2047 static void
2048 esetkaudit(ai, size)
2049 	auditinfo_addr_t *ai;
2050 	int size;
2051 {
2052 	if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
2053 		exit_error(gettext("auditon: A_SETKAUDIT failed."));
2054 }
2055 
2056 static void
2057 egetauditflagsbin(auditflags, pmask)
2058 	char *auditflags;
2059 	au_mask_t *pmask;
2060 {
2061 	pmask->am_success = pmask->am_failure = 0;
2062 
2063 	if (strcmp(auditflags, "none") == 0)
2064 		return;
2065 
2066 	if (getauditflagsbin(auditflags, pmask) < 0) {
2067 		exit_error(gettext("Could not get audit flags (%s)"),
2068 			auditflags);
2069 	}
2070 }
2071 
2072 static au_event_ent_t *
2073 egetauevnum(event_number)
2074 	au_event_t event_number;
2075 {
2076 	au_event_ent_t *evp;
2077 
2078 	if ((evp = getauevnum(event_number)) == (au_event_ent_t *)NULL)
2079 		exit_error(gettext("Could not get audit event %d"),
2080 			event_number);
2081 
2082 	return (evp);
2083 }
2084 
2085 static au_event_ent_t *
2086 egetauevnam(event_name)
2087 	char *event_name;
2088 {
2089 	register au_event_ent_t *evp;
2090 
2091 	if ((evp = getauevnam(event_name)) == (au_event_ent_t *)NULL)
2092 		exit_error(gettext("Could not get audit event %s"), event_name);
2093 
2094 	return (evp);
2095 }
2096 
2097 static void
2098 esetauid(auid)
2099 	au_id_t *auid;
2100 {
2101 	if (setauid(auid) == -1)
2102 		exit_error(gettext("setauid(2) failed."));
2103 }
2104 
2105 static void
2106 esetaudit(ai, size)
2107 	auditinfo_addr_t *ai;
2108 	int size;
2109 {
2110 	if (setaudit_addr(ai, size) == -1)
2111 		exit_error(gettext("setaudit_addr(2) failed."));
2112 }
2113 
2114 static uid_t
2115 get_user_id(user)
2116 	char *user;
2117 {
2118 	struct passwd *pwd;
2119 	uid_t uid;
2120 
2121 	setpwent();
2122 	if (isdigit(*user)) {
2123 		uid = atoi(user);
2124 		if ((pwd = getpwuid(uid)) == (struct passwd *)NULL) {
2125 			exit_error(gettext("Invalid user: %s"), user);
2126 		}
2127 	} else {
2128 		if ((pwd = getpwnam(user)) == (struct passwd *)NULL) {
2129 			exit_error(gettext("Invalid user: %s"), user);
2130 		}
2131 	}
2132 	endpwent();
2133 
2134 	return (pwd->pw_uid);
2135 }
2136 
2137 /*
2138  * get_arg_ent()
2139  *     Inputs: command line argument string
2140  *     Returns ptr to policy_entry if found; null, if not found
2141  */
2142 static struct arg_entry *
2143 get_arg_ent(arg_str)
2144 	char *arg_str;
2145 {
2146 	struct arg_entry key;
2147 
2148 	key.arg_str = arg_str;
2149 
2150 	return ((struct arg_entry *)bsearch((char *)&key,
2151 	    (char *)arg_table, ARG_TBL_SZ, sizeof (struct arg_entry),
2152 	    arg_ent_compare));
2153 }
2154 
2155 /*
2156  * arg_ent_compare()
2157  *     Compares two command line arguments to determine which is
2158  *       lexicographically greater.
2159  *     Inputs: two argument map table entry pointers
2160  *     Returns: > 1: aep1->arg_str > aep2->arg_str
2161  *              < 1: aep1->arg_str < aep2->arg_str
2162  *                0: aep1->arg_str = aep->arg_str2
2163  */
2164 static int
2165 arg_ent_compare(aep1, aep2)
2166 struct arg_entry *aep1, *aep2;
2167 {
2168 	return (strcmp(aep1->arg_str, aep2->arg_str));
2169 }
2170 
2171 /*
2172  * Convert mask of the following forms:
2173  *
2174  *    audit_flags (ie. +lo,-ad,pc)
2175  *    0xffffffff,0xffffffff
2176  *    ffffffff,ffffffff
2177  *    20,20
2178  */
2179 static void
2180 str2mask(mask_str, mp)
2181 	char *mask_str;
2182 	au_mask_t *mp;
2183 {
2184 
2185 	char sp[256];
2186 	char fp[256];
2187 
2188 	mp->am_success = 0;
2189 	mp->am_failure = 0;
2190 
2191 	/*
2192 	 * a mask of the form +aa,bb,cc,-dd
2193 	 */
2194 	if (strisflags(mask_str)) {
2195 		egetauditflagsbin(mask_str, mp);
2196 	/*
2197 	 * a mask of the form 0xffffffff,0xffffffff or 1,1
2198 	 */
2199 	} else {
2200 		strsplit(mask_str, sp, fp, ',');
2201 
2202 		if (strlen(sp) > (size_t)2 && !strncasecmp(sp, "0x", 2))
2203 			(void) sscanf(sp + 2, "%x", &mp->am_success);
2204 		else
2205 			(void) sscanf(sp, "%u", &mp->am_success);
2206 
2207 		if (strlen(fp) > (size_t)2 && !strncasecmp(fp, "0x", 2))
2208 			(void) sscanf(fp + 2, "%x", &mp->am_failure);
2209 		else
2210 			(void) sscanf(fp, "%u", &mp->am_failure);
2211 	}
2212 }
2213 
2214 /*
2215  * tid_str is major,minor,host  -- host is a name or an ip address
2216  */
2217 
2218 static void
2219 str2tid(char *tid_str, au_tid_addr_t *tp)
2220 {
2221 	char *major_str = (char *)NULL;
2222 	char *minor_str = (char *)NULL;
2223 	char *host_str = (char *)NULL;
2224 	major_t major = 0;
2225 	major_t minor = 0;
2226 	dev_t dev = 0;
2227 	struct hostent *phe;
2228 	int err;
2229 	uint32_t ibuf;
2230 	uint32_t ibuf6[4];
2231 
2232 	tp->at_port = 0;
2233 	tp->at_type = 0;
2234 	bzero(tp->at_addr, 16);
2235 
2236 	major_str = tid_str;
2237 	if ((minor_str = strchr(tid_str, ',')) != NULL) {
2238 		*minor_str = '\0';
2239 		minor_str++;
2240 	}
2241 
2242 	if (minor_str)
2243 		if ((host_str = strchr(minor_str, ',')) != NULL) {
2244 			*host_str = '\0';
2245 			host_str++;
2246 		}
2247 
2248 	if (major_str)
2249 		major = (major_t)atoi(major_str);
2250 
2251 	if (minor_str)
2252 		minor = (minor_t)atoi(minor_str);
2253 
2254 	if ((dev = makedev(major, minor)) != NODEV)
2255 		tp->at_port = dev;
2256 
2257 	if (host_str) {
2258 		if (strisipaddr(host_str)) {
2259 		    if (inet_pton(AF_INET, host_str, &ibuf)) {
2260 			tp->at_addr[0] = ibuf;
2261 			tp->at_type = AU_IPv4;
2262 		    } else if (inet_pton(AF_INET6, host_str, ibuf6)) {
2263 			tp->at_addr[0] = ibuf6[0];
2264 			tp->at_addr[1] = ibuf6[1];
2265 			tp->at_addr[2] = ibuf6[2];
2266 			tp->at_addr[3] = ibuf6[3];
2267 			tp->at_type = AU_IPv6;
2268 		    }
2269 		} else {
2270 			phe = getipnodebyname((const void *)host_str,
2271 				AF_INET, 0, &err);
2272 			if (phe == 0) {
2273 				phe = getipnodebyname((const void *)host_str,
2274 					AF_INET6, 0, &err);
2275 			}
2276 
2277 			if (phe != NULL) {
2278 				if (phe->h_addrtype == AF_INET6) {
2279 					/* address is IPv6 (128 bits) */
2280 					(void) memcpy(&tp->at_addr[0],
2281 						phe->h_addr_list[0], 16);
2282 					tp->at_type = AU_IPv6;
2283 				} else {
2284 					/* address is IPv4 (32 bits) */
2285 					(void) memcpy(&tp->at_addr[0],
2286 						phe->h_addr_list[0], 4);
2287 					tp->at_type = AU_IPv4;
2288 				}
2289 				freehostent(phe);
2290 			}
2291 		}
2292 	}
2293 }
2294 
2295 static int
2296 cond2str(cond, cond_str)
2297 	uint_t cond;
2298 	char *cond_str;
2299 {
2300 	*cond_str = '\0';
2301 
2302 	if (cond == AUC_AUDITING) {
2303 		(void) strcpy(cond_str, "auditing");
2304 		return (0);
2305 	}
2306 
2307 	if ((cond == AUC_NOAUDIT) || (cond == AUC_INIT_AUDIT)) {
2308 		(void) strcpy(cond_str, "noaudit");
2309 		return (0);
2310 	}
2311 
2312 	if (cond == AUC_UNSET) {
2313 		(void) strcpy(cond_str, "unset");
2314 		return (0);
2315 	}
2316 
2317 	if (cond == AUC_NOSPACE) {
2318 		(void) strcpy(cond_str, "nospace");
2319 		return (0);
2320 	}
2321 
2322 	return (1);
2323 }
2324 
2325 static struct policy_entry *
2326 get_policy_ent(policy)
2327 	char *policy;
2328 {
2329 	int i;
2330 
2331 	for (i = 0; i < POLICY_TBL_SZ; i++) {
2332 		if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
2333 			continue;	/* skip this entry */
2334 		if (strcmp(strtolower(policy), policy_table[i].policy_str) == 0)
2335 			return (&policy_table[i]);
2336 	}
2337 
2338 	return ((struct policy_entry *)NULL);
2339 }
2340 
2341 static int
2342 str2policy(char *policy_str, uint_t *policy_mask)
2343 {
2344 	char		*buf;
2345 	char		*tok;
2346 	char		pfix;
2347 	boolean_t	is_all = 0;
2348 	uint_t		pm = 0;
2349 	uint_t		curp = 0;
2350 	struct		policy_entry *pep;
2351 
2352 	pfix = *policy_str;
2353 
2354 	if (pfix == '-' || pfix == '+' || pfix == '=')
2355 		++policy_str;
2356 
2357 	if ((buf = strdup(policy_str)) == NULL)
2358 		return (1);
2359 
2360 	for (tok = strtok(buf, ","); tok != NULL;
2361 				tok = strtok(NULL, ",")) {
2362 		if ((pep = get_policy_ent(tok)) == NULL) {
2363 			return (1);
2364 		} else {
2365 			pm |= pep->policy_mask;
2366 			if (pep->policy_mask == ALL_POLICIES)
2367 				is_all = 1;
2368 		}
2369 	}
2370 
2371 	free(buf);
2372 
2373 	if (pfix == '-') {
2374 		if (!is_all && (getzoneid() != GLOBAL_ZONEID) &&
2375 		    (pm & ~AUDIT_LOCAL))
2376 			return (2);
2377 
2378 		eauditon(A_GETPOLICY, (caddr_t)&curp, 0);
2379 		if (getzoneid() != GLOBAL_ZONEID)
2380 			curp &= AUDIT_LOCAL;
2381 		*policy_mask = curp & ~pm;
2382 	} else if (pfix == '+') {
2383 		/*
2384 		 * if the user is in a local zone and tries ahlt or
2385 		 * perzone, that's an error.  But if the user uses "all"
2386 		 * then make it work
2387 		 */
2388 		if (!is_all && (getzoneid() != GLOBAL_ZONEID) &&
2389 		    (pm & ~AUDIT_LOCAL))
2390 			return (2);
2391 		eauditon(A_GETPOLICY, (caddr_t)&curp, 0);
2392 		if (getzoneid() != GLOBAL_ZONEID) {
2393 			curp &= AUDIT_LOCAL;
2394 			if (is_all)
2395 				pm &= AUDIT_LOCAL;
2396 		}
2397 		*policy_mask = curp | pm;
2398 	} else {
2399 		if (is_all && (getzoneid() != GLOBAL_ZONEID))
2400 			pm &= AUDIT_LOCAL;
2401 
2402 		*policy_mask = pm;
2403 	}
2404 	return (0);
2405 }
2406 
2407 static int
2408 policy2str(policy, policy_str, len)
2409 	uint_t policy;
2410 	char *policy_str;
2411 	size_t len;
2412 {
2413 	int i, j;
2414 
2415 	if (policy == ALL_POLICIES) {
2416 		(void) strcpy(policy_str, "all");
2417 		return (1);
2418 	}
2419 
2420 	if (policy == NO_POLICIES) {
2421 		(void) strcpy(policy_str, "none");
2422 		return (1);
2423 	}
2424 
2425 	*policy_str = '\0';
2426 
2427 	for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) {
2428 		if ((policy_table[i].policy_flags & AC_TSOL) && !tsol_on)
2429 			continue;	/* skip this entry */
2430 		if (policy & policy_table[i].policy_mask &&
2431 		    policy_table[i].policy_mask != ALL_POLICIES) {
2432 			if (j++)
2433 				(void) strcat(policy_str, ",");
2434 			(void) strlcat(policy_str,
2435 			    policy_table[i].policy_str, len);
2436 		}
2437 	}
2438 
2439 	if (*policy_str)
2440 		return (0);
2441 
2442 	return (1);
2443 }
2444 
2445 
2446 static int
2447 strisnum(s)
2448 	char *s;
2449 {
2450 	if (s == (char *)NULL || !*s)
2451 		return (0);
2452 
2453 	for (; *s == '-' || *s == '+'; s++)
2454 
2455 	if (!*s)
2456 		return (0);
2457 
2458 	for (; *s; s++)
2459 		if (!isdigit(*s))
2460 			return (0);
2461 
2462 	return (1);
2463 }
2464 
2465 static int
2466 strisflags(s)
2467 	char *s;
2468 {
2469 	if (s == (char *)NULL || !*s)
2470 		return (0);
2471 
2472 	for (; *s; s++) {
2473 		if (!isalpha(*s) &&
2474 			(*s != '+' && *s != '-' && *s != '^' && *s != ','))
2475 			return (0);
2476 	}
2477 
2478 	return (1);
2479 }
2480 
2481 static int
2482 strisipaddr(s)
2483 	char *s;
2484 {
2485 	int dot = 0;
2486 	int colon = 0;
2487 
2488 	/* no string */
2489 	if ((s == (char *)NULL) || (!*s))
2490 		return (0);
2491 
2492 	for (; *s; s++) {
2493 		if (!(isxdigit(*s) || *s != '.' || *s != ':'))
2494 			return (0);
2495 		if (*s == '.') dot++;
2496 		if (*s == ':') colon++;
2497 	}
2498 
2499 	if (dot && colon)
2500 		return (0);
2501 
2502 	if (!dot && !colon)
2503 		return (0);
2504 
2505 	return (1);
2506 }
2507 
2508 static void
2509 strsplit(s, p1, p2, c)
2510 	char *s;
2511 	char *p1;
2512 	char *p2;
2513 	char c;
2514 {
2515 	*p1 = *p2 = '\0';
2516 
2517 	while (*s != '\0' && *s != c)
2518 		*p1++ = *s++;
2519 	*p1 = '\0';
2520 	s++;
2521 
2522 	while (*s != '\0')
2523 		*p2++ = *s++;
2524 	*p2 = '\0';
2525 }
2526 
2527 static char *
2528 strtolower(s)
2529 	char *s;
2530 {
2531 	char *save;
2532 
2533 	for (save = s; *s; s++)
2534 		(void) tolower(*s);
2535 
2536 	return (save);
2537 }
2538 
2539 static void
2540 chk_event_num(etype, event)
2541 	int etype;
2542 	au_event_t event;
2543 {
2544 	au_stat_t as;
2545 
2546 	eauditon(A_GETSTAT, (caddr_t)&as, 0);
2547 
2548 	if (etype == AC_KERN_EVENT) {
2549 		if (event > as.as_numevent) {
2550 			exit_error(gettext("Invalid kernel audit event number "
2551 			"specified.\n\t%d is outside allowable range 0-%d."),
2552 			    event, as.as_numevent);
2553 		}
2554 	} else  { /* user event */
2555 		if (event <= as.as_numevent) {
2556 			exit_error(gettext(
2557 			"Invalid user level audit event number specified %d."),
2558 				event);
2559 		}
2560 	}
2561 }
2562 
2563 static void
2564 chk_event_str(etype, event_str)
2565 	int etype;
2566 	char *event_str;
2567 {
2568 	au_event_ent_t *evp;
2569 	au_stat_t as;
2570 
2571 	eauditon(A_GETSTAT, (caddr_t)&as, 0);
2572 
2573 	evp = egetauevnam(event_str);
2574 	if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) {
2575 		exit_error(
2576 		    gettext("Invalid kernel audit event string specified.\n"
2577 			"\t\"%s\" appears to be a user level event. "
2578 			"Check configuration."),
2579 		    event_str);
2580 	} else if (etype == AC_USER_EVENT &&
2581 			(evp->ae_number < as.as_numevent)) {
2582 		exit_error(
2583 		    gettext("Invalid user audit event string specified.\n"
2584 			"\t\"%s\" appears to be a kernel event. "
2585 			"Check configuration."),
2586 		    event_str);
2587 	}
2588 }
2589 
2590 static void
2591 chk_sorf(sorf_str)
2592 	char *sorf_str;
2593 {
2594 	if (!strisnum(sorf_str))
2595 		exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
2596 }
2597 
2598 static void
2599 chk_retval(retval_str)
2600 	char *retval_str;
2601 {
2602 	if (!strisnum(retval_str))
2603 		exit_error(gettext("Invalid retval specified: %s"), retval_str);
2604 }
2605 
2606 static void
2607 chk_tid(tid_str)
2608 	char *tid_str;
2609 {
2610 	int c;
2611 	char *p;
2612 
2613 	/* need two commas (maj,min,hostname) */
2614 
2615 
2616 	for (p = tid_str, c = 0; *p; p++)
2617 		if (*p == ',')
2618 			++c;
2619 	if (c != 2)
2620 		exit_error(gettext("Invalid tid specified: %s"), tid_str);
2621 }
2622 
2623 static void
2624 execit(argv)
2625 	char **argv;
2626 {
2627 	char *shell;
2628 
2629 	if (*argv)
2630 		(void) execvp(*argv, argv);
2631 	else {
2632 		if (((shell = getenv("SHELL")) == (char *)NULL) ||
2633 			*shell != '/')
2634 			shell = "/bin/csh";
2635 
2636 		(void) execlp(shell, shell, (char *)NULL);
2637 	}
2638 
2639 	exit_error(gettext("exec(2) failed"));
2640 }
2641 
2642 /*
2643  * exit_error()
2644  *     Desc: Prints an error message along with corresponding system
2645  *                  error number and error message, then exits.
2646  *     Inputs: Program name, program error message.
2647  */
2648 /*PRINTFLIKE1*/
2649 static void
2650 exit_error(char *fmt, ...)
2651 {
2652 	va_list args;
2653 
2654 	(void) fprintf(stderr, "%s: ", progname);
2655 
2656 	va_start(args, fmt);
2657 	(void) vfprintf(stderr, fmt, args);
2658 	va_end(args);
2659 
2660 	(void) fputc('\n', stderr);
2661 	if (errno)
2662 		(void) fprintf(stderr, gettext("%s: error = %s(%d)\n"),
2663 			progname, strerror(errno), errno);
2664 	(void) fflush(stderr);
2665 
2666 	exit(1);
2667 }
2668 
2669 static void
2670 exit_usage(status)
2671 	int status;
2672 {
2673 	FILE *fp;
2674 	int i;
2675 
2676 	fp = (status ? stderr : stdout);
2677 	(void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
2678 
2679 	for (i = 0; i < ARG2_TBL_SZ; i++)
2680 		(void) fprintf(fp, " %s %s\n",
2681 			arg2_table[i].arg_str, arg2_table[i].arg_opts);
2682 
2683 	exit(status);
2684 }
2685 
2686 static void
2687 print_asid(asid)
2688 	au_asid_t asid;
2689 {
2690 	(void) printf(gettext("audit session id = %u\n"), asid);
2691 }
2692 
2693 static void
2694 print_auid(auid)
2695 	au_id_t auid;
2696 {
2697 	struct passwd *pwd;
2698 	char *username;
2699 
2700 	setpwent();
2701 	if ((pwd = getpwuid((uid_t)auid)) != (struct passwd *)NULL)
2702 		username = pwd->pw_name;
2703 	else
2704 		username = gettext("unknown");
2705 	endpwent();
2706 
2707 	(void) printf(gettext("audit id = %s(%d)\n"), username, auid);
2708 }
2709 
2710 static void
2711 print_mask(desc, pmp)
2712 	char *desc;
2713 	au_mask_t *pmp;
2714 {
2715 	char auflags[512];
2716 
2717 	if (getauditflagschar(auflags, pmp, NULL) < 0)
2718 		(void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
2719 
2720 	(void) printf("%s = %s(0x%x,0x%x)\n",
2721 		desc, auflags, pmp->am_success, pmp->am_failure);
2722 }
2723 
2724 static void
2725 print_mask1(desc, mask1)
2726 	char *desc;
2727 	au_class_t	mask1;
2728 {
2729 	(void) printf("%s = 0x%x\n", desc, (int)mask1);
2730 }
2731 
2732 static void
2733 print_stats(s)
2734 	au_stat_t *s;
2735 {
2736 	int offset[12];   /* used to line the header up correctly */
2737 	char buf[512];
2738 
2739 	(void) sprintf(buf, "%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu "
2740 	    "%n%4lu %n%4lu %n%4lu %n%4lu %n%4lu%n",
2741 	    (ulong_t)s->as_generated,	&(offset[0]),
2742 	    (ulong_t)s->as_nonattrib,	&(offset[1]),
2743 	    (ulong_t)s->as_kernel,	&(offset[2]),
2744 	    (ulong_t)s->as_audit,	&(offset[3]),
2745 	    (ulong_t)s->as_auditctl,	&(offset[4]),
2746 	    (ulong_t)s->as_enqueue,	&(offset[5]),
2747 	    (ulong_t)s->as_written,	&(offset[6]),
2748 	    (ulong_t)s->as_wblocked,	&(offset[7]),
2749 	    (ulong_t)s->as_rblocked,	&(offset[8]),
2750 	    (ulong_t)s->as_dropped,	&(offset[9]),
2751 	    (ulong_t)s->as_totalsize / ONEK, &(offset[10]),
2752 	    (ulong_t)s->as_memused / ONEK, &(offset[11]));
2753 
2754 	/*
2755 	 * TRANSLATION_NOTE
2756 	 *	Print a properly aligned header.
2757 	 */
2758 	(void) printf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n",
2759 		offset[0] - 1,			gettext("gen"),
2760 		offset[1] - offset[0] -1,	gettext("nona"),
2761 		offset[2] - offset[1] -1,	gettext("kern"),
2762 		offset[3] - offset[2] -1,	gettext("aud"),
2763 		offset[4] - offset[3] -1,	gettext("ctl"),
2764 		offset[5] - offset[4] -1,	gettext("enq"),
2765 		offset[6] - offset[5] -1,	gettext("wrtn"),
2766 		offset[7] - offset[6] -1,	gettext("wblk"),
2767 		offset[8] - offset[7] -1,	gettext("rblk"),
2768 		offset[9] - offset[8] -1,	gettext("drop"),
2769 		offset[10] - offset[9] -1,	gettext("tot"),
2770 		offset[11] - offset[10],	gettext("mem"));
2771 
2772 	(void) puts(buf);
2773 }
2774 
2775 static void
2776 print_tid_ex(tidp)
2777 	au_tid_addr_t *tidp;
2778 {
2779 	struct hostent *phe;
2780 	char *hostname;
2781 	struct in_addr ia;
2782 	uint32_t *addr;
2783 	int err;
2784 	char buf[256];
2785 	char *bufp;
2786 
2787 
2788 	/* IPV6 or IPV4 address */
2789 	if (tidp->at_type == AU_IPv4) {
2790 		if ((phe = gethostbyaddr((char *)&tidp->at_addr[0],
2791 					sizeof (tidp->at_addr[0]),
2792 					AF_INET)) != (struct hostent *)NULL)
2793 			hostname = phe->h_name;
2794 		else
2795 			hostname = gettext("unknown");
2796 
2797 		ia.s_addr = tidp->at_addr[0];
2798 
2799 		(void) printf(gettext(
2800 			"terminal id (maj,min,host) = %u,%u,%s(%s)\n"),
2801 			major(tidp->at_port), minor(tidp->at_port),
2802 			hostname, inet_ntoa(ia));
2803 	} else {
2804 		addr = &tidp->at_addr[0];
2805 		phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
2806 
2807 		bzero(buf, sizeof (buf));
2808 
2809 		(void) inet_ntop(AF_INET6, (void *)addr, buf,
2810 						sizeof (buf));
2811 		if (phe == (struct hostent *)0) {
2812 			bufp = gettext("unknown");
2813 		} else
2814 			bufp = phe->h_name;
2815 
2816 		(void) printf(gettext(
2817 			"terminal id (maj,min,host) = %u,%u,%s(%s)\n"),
2818 			major(tidp->at_port), minor(tidp->at_port),
2819 			bufp, buf);
2820 		if (phe)
2821 			freehostent(phe);
2822 	}
2823 }
2824 
2825 static int
2826 str2ipaddr(s, addr, type)
2827 	char *s;
2828 	uint32_t *addr;
2829 	uint32_t type;
2830 {
2831 	int j, sl;
2832 	char *ss;
2833 	unsigned int v;
2834 
2835 	bzero(addr, 16);
2836 	if (strisipaddr(s)) {
2837 		if (type == AU_IPv4) {
2838 			if (inet_pton(AF_INET, s, addr))
2839 				return (0);
2840 			return (1);
2841 		}
2842 		if (type == AU_IPv6) {
2843 			if (inet_pton(AF_INET6, s, addr))
2844 				return (0);
2845 			return (1);
2846 		}
2847 		return (1);
2848 	} else {
2849 		if (type == AU_IPv4) {
2850 			(void) sscanf(s, "%x", &addr[0]);
2851 			return (0);
2852 		}
2853 		if (type == AU_IPv6) {
2854 			sl = strlen(s);
2855 			ss = s;
2856 			for (j = 3; j >= 0; j--) {
2857 				if ((sl - 8) <= 0) {
2858 					(void) sscanf(s, "%x", &v);
2859 					addr[j] = v;
2860 					return (0);
2861 				}
2862 				ss = &s[sl-8];
2863 				(void) sscanf(ss, "%x", &v);
2864 				addr[j] = v;
2865 				sl -= 8;
2866 				*ss = '\0';
2867 			}
2868 		}
2869 		return (0);
2870 	}
2871 }
2872 
2873 static int
2874 str2type(s, type)
2875 	char *s;
2876 	uint_t *type;
2877 {
2878 	if (strcmp(s, "ipv6") == 0) {
2879 		*type = AU_IPv6;
2880 		return (0);
2881 	}
2882 	if (strcmp(s, "ipv4") == 0) {
2883 		*type = AU_IPv4;
2884 		return (0);
2885 	}
2886 
2887 	return (1);
2888 }
2889