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