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