dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / auditconfig / auditconfig.c
blobe77754af38f70138435a0516777e2499d9d2c28d
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
26 * auditconfig - set and display audit parameters
29 #include <locale.h>
30 #include <sys/types.h>
31 #include <ctype.h>
32 #include <stdlib.h>
33 #include <stdarg.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #include <sys/param.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <nlist.h>
41 #include <fcntl.h>
42 #include <sys/socket.h>
43 #include <netdb.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <sys/mkdev.h>
47 #include <sys/param.h>
48 #include <pwd.h>
49 #include <libintl.h>
50 #include <zone.h>
51 #include <libscf_priv.h>
52 #include <bsm/libbsm.h>
53 #include <audit_policy.h>
54 #include <audit_scf.h>
56 enum commands {
57 AC_ARG_ACONF,
58 AC_ARG_AUDIT,
59 AC_ARG_CHKACONF,
60 AC_ARG_CHKCONF,
61 AC_ARG_CONF,
62 AC_ARG_GETASID,
63 AC_ARG_GETAUDIT,
64 AC_ARG_GETAUID,
65 AC_ARG_GETCAR,
66 AC_ARG_GETCLASS,
67 AC_ARG_GETCOND,
68 AC_ARG_GETCWD,
69 AC_ARG_GETESTATE,
70 AC_ARG_GETFLAGS,
71 AC_ARG_GETKAUDIT,
72 AC_ARG_GETKMASK,
73 AC_ARG_GETNAFLAGS,
74 AC_ARG_GETPINFO,
75 AC_ARG_GETPLUGIN,
76 AC_ARG_GETPOLICY,
77 AC_ARG_GETQBUFSZ,
78 AC_ARG_GETQCTRL,
79 AC_ARG_GETQDELAY,
80 AC_ARG_GETQHIWATER,
81 AC_ARG_GETQLOWATER,
82 AC_ARG_GETSTAT,
83 AC_ARG_GETTERMID,
84 AC_ARG_LSEVENT,
85 AC_ARG_LSPOLICY,
86 AC_ARG_SETASID,
87 AC_ARG_SETAUDIT,
88 AC_ARG_SETAUID,
89 AC_ARG_SETCLASS,
90 AC_ARG_SETFLAGS,
91 AC_ARG_SETKAUDIT,
92 AC_ARG_SETKMASK,
93 AC_ARG_SETNAFLAGS,
94 AC_ARG_SETPLUGIN,
95 AC_ARG_SETPMASK,
96 AC_ARG_SETPOLICY,
97 AC_ARG_SETQBUFSZ,
98 AC_ARG_SETQCTRL,
99 AC_ARG_SETQDELAY,
100 AC_ARG_SETQHIWATER,
101 AC_ARG_SETQLOWATER,
102 AC_ARG_SETSMASK,
103 AC_ARG_SETSTAT,
104 AC_ARG_SETUMASK,
105 AC_ARG_SET_TEMPORARY
108 #define AC_KERN_EVENT 0
109 #define AC_USER_EVENT 1
111 #define NONE(s) (!strlen(s) ? gettext("none") : s)
113 #define ONEK 1024
116 * remove this after the audit.h is fixed
118 struct arg_entry {
119 char *arg_str;
120 char *arg_opts;
121 enum commands auditconfig_cmd;
122 boolean_t temporary_allowed; /* -t allowed for the option */
124 typedef struct arg_entry arg_entry_t;
126 /* arg_table - command option and usage message table */
127 static arg_entry_t arg_table[] = {
128 { "-aconf", "", AC_ARG_ACONF, B_FALSE},
129 { "-audit", " event sorf retval string", AC_ARG_AUDIT, B_FALSE},
130 { "-chkaconf", "", AC_ARG_CHKACONF, B_FALSE},
131 { "-chkconf", "", AC_ARG_CHKCONF, B_FALSE},
132 { "-conf", "", AC_ARG_CONF, B_FALSE},
133 { "-getasid", "", AC_ARG_GETASID, B_FALSE},
134 { "-getaudit", "", AC_ARG_GETAUDIT, B_FALSE},
135 { "-getauid", "", AC_ARG_GETAUID, B_FALSE},
136 { "-getcar", "", AC_ARG_GETCAR, B_FALSE},
137 { "-getclass", " event", AC_ARG_GETCLASS, B_FALSE},
138 { "-getcond", "", AC_ARG_GETCOND, B_FALSE},
139 { "-getcwd", "", AC_ARG_GETCWD, B_FALSE},
140 { "-getestate", " event", AC_ARG_GETESTATE, B_FALSE},
141 { "-getflags", "", AC_ARG_GETFLAGS, B_FALSE},
142 { "-getkaudit", "", AC_ARG_GETKAUDIT, B_FALSE},
143 { "-getkmask", "", AC_ARG_GETKMASK, B_FALSE},
144 { "-getnaflags", "", AC_ARG_GETNAFLAGS, B_FALSE},
145 { "-getpinfo", " pid", AC_ARG_GETPINFO, B_FALSE},
146 { "-getplugin", " [plugin]", AC_ARG_GETPLUGIN, B_FALSE},
147 { "-getpolicy", "", AC_ARG_GETPOLICY, B_TRUE},
148 { "-getqbufsz", "", AC_ARG_GETQBUFSZ, B_TRUE},
149 { "-getqctrl", "", AC_ARG_GETQCTRL, B_TRUE},
150 { "-getqdelay", "", AC_ARG_GETQDELAY, B_TRUE},
151 { "-getqhiwater", "", AC_ARG_GETQHIWATER, B_TRUE},
152 { "-getqlowater", "", AC_ARG_GETQLOWATER, B_TRUE},
153 { "-getstat", "", AC_ARG_GETSTAT, B_FALSE},
154 { "-gettid", "", AC_ARG_GETTERMID, B_FALSE},
155 { "-lsevent", "", AC_ARG_LSEVENT, B_FALSE},
156 { "-lspolicy", "", AC_ARG_LSPOLICY, B_FALSE},
157 { "-setasid", " asid [cmd]", AC_ARG_SETASID, B_FALSE},
158 { "-setaudit", " auid audit_flags termid asid [cmd]",
159 AC_ARG_SETAUDIT, B_FALSE},
160 { "-setauid", " auid [cmd]", AC_ARG_SETAUID, B_FALSE},
161 { "-setclass", " event audit_flags", AC_ARG_SETCLASS, B_FALSE},
162 { "-setflags", " audit_flags", AC_ARG_SETFLAGS, B_FALSE},
163 { "-setkaudit", " type IP_address", AC_ARG_SETKAUDIT, B_FALSE},
164 { "-setkmask", " audit_flags", AC_ARG_SETKMASK, B_FALSE},
165 { "-setnaflags", " audit_naflags", AC_ARG_SETNAFLAGS, B_FALSE},
166 { "-setplugin", " name active|inactive [attributes [qsize]]",
167 AC_ARG_SETPLUGIN, B_FALSE},
168 { "-setpmask", " pid audit_flags", AC_ARG_SETPMASK, B_FALSE},
169 { "-setpolicy", " [+|-]policy_flags", AC_ARG_SETPOLICY, B_TRUE},
170 { "-setqbufsz", " bufsz", AC_ARG_SETQBUFSZ, B_TRUE},
171 { "-setqctrl", " hiwater lowater bufsz delay",
172 AC_ARG_SETQCTRL, B_TRUE},
173 { "-setqdelay", " delay", AC_ARG_SETQDELAY, B_TRUE},
174 { "-setqhiwater", " hiwater", AC_ARG_SETQHIWATER, B_TRUE},
175 { "-setqlowater", " lowater", AC_ARG_SETQLOWATER, B_TRUE},
176 { "-setsmask", " asid audit_flags", AC_ARG_SETSMASK, B_FALSE},
177 { "-setstat", "", AC_ARG_SETSTAT, B_FALSE},
178 { "-setumask", " user audit_flags", AC_ARG_SETUMASK, B_FALSE},
179 { "-t", "", AC_ARG_SET_TEMPORARY, B_FALSE},
182 #define ARG_TBL_SZ (sizeof (arg_table) / sizeof (arg_entry_t))
184 char *progname = "auditconfig";
187 * temporary_set true to get/set only kernel settings,
188 * false to get/set kernel settings and service properties
190 static boolean_t temporary_set = B_FALSE;
192 static au_event_ent_t *egetauevnam(char *event_name);
193 static au_event_ent_t *egetauevnum(au_event_t event_number);
194 static int arg_ent_compare(const void *aep1, const void *aep2);
195 static char *cond2str(void);
196 static int policy2str(uint32_t policy, char *policy_str, size_t len);
197 static int str2type(char *s, uint_t *type);
198 static int str2policy(char *policy_str, uint32_t *policy_mask);
199 static int str2ipaddr(char *s, uint32_t *addr, uint32_t type);
200 static int strisipaddr(char *s);
201 static int strisnum(char *s);
202 static arg_entry_t *get_arg_ent(char *arg_str);
203 static uid_t get_user_id(char *user);
204 static void chk_arg_len(char *argv, uint_t len);
205 static void chk_event_num(int etype, au_event_t event);
206 static void chk_event_str(int etype, char *event_str);
207 static void chk_known_plugin(char *plugin_str);
208 static void chk_retval(char *retval_str);
209 static void chk_sorf(char *sorf_str);
210 static void do_aconf(void);
211 static void do_args(char **argv, au_mask_t *mask);
212 static void do_audit(char *, char, int, char *);
213 static void do_chkaconf(void);
214 static void do_chkconf(void);
215 static void do_conf(void);
216 static void do_getasid(void);
217 static void do_getaudit(void);
218 static void do_getkaudit(void);
219 static void do_setkaudit(char *t, char *s);
220 static void do_getauid(void);
221 static void do_getcar(void);
222 static void do_getclass(char *event_str);
223 static void do_getcond(void);
224 static void do_getcwd(void);
225 static void do_getflags(void);
226 static void do_getkmask(void);
227 static void do_getnaflags(void);
228 static void do_getpinfo(char *pid_str);
229 static void do_getplugin(char *plugin_str);
230 static void do_getpolicy(void);
231 static void do_getqbufsz(void);
232 static void do_getqctrl(void);
233 static void do_getqdelay(void);
234 static void do_getqhiwater(void);
235 static void do_getqlowater(void);
236 static void do_getstat(void);
237 static void do_gettermid(void);
238 static void do_lsevent(void);
239 static void do_lspolicy(void);
240 static void do_setasid(char *sid_str, char **argv);
241 static void do_setaudit(char *user_str, char *mask_str, char *tid_str,
242 char *sid_str, char **argv);
243 static void do_setauid(char *user, char **argv);
244 static void do_setclass(char *event_str, au_mask_t *mask);
245 static void do_setflags(char *audit_flags, au_mask_t *amask);
246 static void do_setkmask(au_mask_t *pmask);
247 static void do_setnaflags(char *audit_naflags, au_mask_t *namask);
248 static void do_setpmask(char *pid_str, au_mask_t *mask);
249 static void do_setsmask(char *asid_str, au_mask_t *mask);
250 static void do_setumask(char *auid_str, au_mask_t *mask);
251 static void do_setplugin(char *plugin_str, boolean_t plugin_state,
252 char *plugin_attr, int plugin_qsize);
253 static void do_setpolicy(char *policy_str);
254 static void do_setqbufsz(char *bufsz);
255 static void do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay);
256 static void do_setqdelay(char *delay);
257 static void do_setqhiwater(char *hiwater);
258 static void do_setqlowater(char *lowater);
259 static void do_setstat(void);
260 static void str2tid(char *tid_str, au_tid_addr_t *tp);
262 static void eauditon(int cmd, caddr_t data, int length);
263 static void echkflags(char *auditflags, au_mask_t *mask);
264 static void egetaudit(auditinfo_addr_t *ai, int size);
265 static void egetauditflagsbin(char *auditflags, au_mask_t *pmask);
266 static void egetauid(au_id_t *auid);
267 static void egetkaudit(auditinfo_addr_t *ai, int size);
268 static void esetaudit(auditinfo_addr_t *ai, int size);
269 static void esetauid(au_id_t *auid);
270 static void esetkaudit(auditinfo_addr_t *ai, int size);
271 static void execit(char **argv);
272 static void exit_error(char *fmt, ...);
273 static void exit_usage(int status);
274 static void parse_args(int argc, char **argv, au_mask_t *mask);
275 static void print_asid(au_asid_t asid);
276 static void print_auid(au_id_t auid);
277 static void print_mask(char *desc, au_mask_t *pmp);
278 static void print_plugin(char *plugin_name, kva_t *plugin_kva);
279 static void print_tid_ex(au_tid_addr_t *tidp);
281 #if !defined(TEXT_DOMAIN)
282 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
283 #endif
286 main(int argc, char **argv)
288 au_mask_t mask; /* for options manipulating flags */
290 (void) setlocale(LC_ALL, "");
291 (void) textdomain(TEXT_DOMAIN);
293 if (argc == 1) {
294 exit_usage(0);
297 if (argc == 2 &&
298 (argv[1][0] == '?' ||
299 strcmp(argv[1], "-h") == 0 ||
300 strcmp(argv[1], "-?") == 0)) {
301 exit_usage(0);
304 parse_args(argc, argv, &mask);
305 do_args(argv, &mask);
307 return (0);
311 * parse_args()
312 * Desc: Checks command line argument syntax.
313 * Inputs: Command line argv;
314 * Returns: If a syntax error is detected, a usage message is printed
315 * and exit() is called. If a syntax error is not detected,
316 * parse_args() returns without a value.
318 static void
319 parse_args(int argc, char **argv, au_mask_t *mask)
321 arg_entry_t *ae;
323 uint_t type;
324 uint_t addr[4];
326 for (++argv; *argv; argv++) {
327 if ((ae = get_arg_ent(*argv)) == NULL) {
328 exit_usage(1);
331 switch (ae->auditconfig_cmd) {
333 case AC_ARG_AUDIT:
334 ++argv;
335 if (!*argv)
336 exit_usage(1);
337 if (strisnum(*argv)) {
338 chk_event_num(AC_USER_EVENT,
339 (au_event_t)atol(*argv));
340 } else {
341 chk_event_str(AC_USER_EVENT, *argv);
343 ++argv;
344 if (!*argv)
345 exit_usage(1);
346 chk_sorf(*argv);
347 ++argv;
348 if (!*argv)
349 exit_usage(1);
350 chk_retval(*argv);
351 ++argv;
352 if (!*argv)
353 exit_usage(1);
354 break;
356 case AC_ARG_CHKCONF:
357 case AC_ARG_CONF:
358 case AC_ARG_ACONF:
359 case AC_ARG_CHKACONF:
360 case AC_ARG_GETASID:
361 case AC_ARG_GETAUID:
362 case AC_ARG_GETAUDIT:
363 case AC_ARG_GETKAUDIT:
364 break;
366 case AC_ARG_GETCLASS:
367 case AC_ARG_GETESTATE:
368 ++argv;
369 if (!*argv)
370 exit_usage(1);
371 if (strisnum(*argv)) {
372 chk_event_num(AC_KERN_EVENT,
373 (au_event_t)atol(*argv));
374 } else {
375 chk_event_str(AC_KERN_EVENT, *argv);
377 break;
379 case AC_ARG_GETCAR:
380 case AC_ARG_GETCOND:
381 case AC_ARG_GETCWD:
382 case AC_ARG_GETFLAGS:
383 case AC_ARG_GETKMASK:
384 case AC_ARG_GETNAFLAGS:
385 break;
387 case AC_ARG_GETPLUGIN:
388 if (*++argv == NULL) {
389 --argv;
390 break;
392 if (get_arg_ent(*argv) != NULL) {
393 --argv;
394 } else {
395 chk_arg_len(*argv, PLUGIN_MAXBUF);
396 chk_known_plugin(*argv);
398 break;
400 case AC_ARG_GETPOLICY:
401 case AC_ARG_GETQBUFSZ:
402 case AC_ARG_GETQCTRL:
403 case AC_ARG_GETQDELAY:
404 case AC_ARG_GETQHIWATER:
405 case AC_ARG_GETQLOWATER:
406 case AC_ARG_GETSTAT:
407 case AC_ARG_GETTERMID:
408 case AC_ARG_LSEVENT:
409 case AC_ARG_LSPOLICY:
410 break;
412 case AC_ARG_SETASID:
413 case AC_ARG_SETAUID:
414 case AC_ARG_SETAUDIT:
415 ++argv;
416 if (!*argv)
417 exit_usage(1);
419 while (*argv)
420 ++argv;
421 --argv;
423 break;
425 case AC_ARG_SETKAUDIT:
426 ++argv;
427 if (!*argv)
428 exit_usage(1);
429 if (str2type (*argv, &type))
430 exit_error(gettext(
431 "Invalid IP address type specified."));
432 ++argv;
433 if (!*argv)
434 exit_usage(1);
436 if (str2ipaddr(*argv, addr, type))
437 exit_error(
438 gettext("Invalid IP address specified."));
439 break;
441 case AC_ARG_SETCLASS:
442 ++argv;
443 if (!*argv)
444 exit_usage(1);
445 if (strisnum(*argv))
446 chk_event_num(AC_KERN_EVENT,
447 (au_event_t)atol(*argv));
448 else
449 chk_event_str(AC_KERN_EVENT, *argv);
450 ++argv;
451 if (!*argv)
452 exit_usage(1);
453 echkflags(*argv, mask);
454 break;
456 case AC_ARG_SETFLAGS:
457 ++argv;
458 if (!*argv)
459 exit_usage(1);
460 chk_arg_len(*argv, PRESELECTION_MAXBUF);
461 echkflags(*argv, mask);
462 break;
464 case AC_ARG_SETKMASK:
465 ++argv;
466 if (!*argv)
467 exit_usage(1);
468 echkflags(*argv, mask);
469 break;
471 case AC_ARG_SETNAFLAGS:
472 ++argv;
473 if (!*argv)
474 exit_usage(1);
475 chk_arg_len(*argv, PRESELECTION_MAXBUF);
476 echkflags(*argv, mask);
477 break;
479 case AC_ARG_SETPLUGIN:
480 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
481 exit_usage(1);
483 chk_known_plugin(*argv);
484 chk_arg_len(*argv, PLUGIN_MAXBUF);
485 if (*++argv == NULL || strcmp(*argv, "active") != 0 &&
486 strcmp(*argv, "inactive") != 0) {
487 exit_usage(1);
489 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
490 --argv;
491 break;
493 chk_arg_len(*argv, PLUGIN_MAXATT);
494 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
495 --argv;
496 break;
498 if (atoi(*argv) < 0) {
499 exit_error(gettext("Incorrect qsize specified "
500 "(%s)."), *argv);
502 break;
504 case AC_ARG_SETPOLICY:
505 ++argv;
506 if (!*argv)
507 exit_usage(1);
508 break;
510 case AC_ARG_SETSTAT:
511 break;
513 case AC_ARG_GETPINFO:
514 ++argv;
515 if (!*argv)
516 exit_usage(1);
517 break;
519 case AC_ARG_SETPMASK:
520 ++argv;
521 if (!*argv)
522 exit_usage(1);
523 ++argv;
524 if (!*argv)
525 exit_usage(1);
526 echkflags(*argv, mask);
527 break;
529 case AC_ARG_SETQBUFSZ:
530 ++argv;
531 if (!*argv)
532 exit_usage(1);
533 if (!strisnum(*argv))
534 exit_error(gettext("Invalid bufsz specified."));
535 break;
537 case AC_ARG_SETQCTRL:
538 ++argv;
539 if (!*argv)
540 exit_usage(1);
541 if (!strisnum(*argv))
542 exit_error(
543 gettext("Invalid hiwater specified."));
544 ++argv;
545 if (!*argv)
546 exit_usage(1);
547 if (!strisnum(*argv))
548 exit_error(
549 gettext("Invalid lowater specified."));
550 ++argv;
551 if (!*argv)
552 exit_usage(1);
553 if (!strisnum(*argv))
554 exit_error(gettext("Invalid bufsz specified."));
555 ++argv;
556 if (!*argv)
557 exit_usage(1);
558 if (!strisnum(*argv))
559 exit_error(gettext("Invalid delay specified."));
560 break;
562 case AC_ARG_SETQDELAY:
563 ++argv;
564 if (!*argv)
565 exit_usage(1);
566 if (!strisnum(*argv))
567 exit_error(gettext("Invalid delay specified."));
568 break;
570 case AC_ARG_SETQHIWATER:
571 ++argv;
572 if (!*argv)
573 exit_usage(1);
574 if (!strisnum(*argv)) {
575 exit_error(
576 gettext("Invalid hiwater specified."));
578 break;
580 case AC_ARG_SETQLOWATER:
581 ++argv;
582 if (!*argv)
583 exit_usage(1);
584 if (!strisnum(*argv)) {
585 exit_error(
586 gettext("Invalid lowater specified."));
588 break;
590 case AC_ARG_SETSMASK:
591 case AC_ARG_SETUMASK:
592 ++argv;
593 if (!*argv)
594 exit_usage(1);
595 ++argv;
596 if (!*argv)
597 exit_usage(1);
598 echkflags(*argv, mask);
599 break;
601 case AC_ARG_SET_TEMPORARY:
602 /* Do not accept single -t option. */
603 if (argc == 2) {
604 exit_error(
605 gettext("Only the -t option specified "
606 "(it is not a standalone option)."));
608 temporary_set = B_TRUE;
609 break;
611 default:
612 exit_error(gettext("Internal error #1."));
613 break;
620 * do_args() - do command line arguments in the order in which they appear.
621 * Function return values returned by the underlying functions; the semantics
622 * they should follow is to return B_TRUE on successful execution, B_FALSE
623 * otherwise.
625 static void
626 do_args(char **argv, au_mask_t *mask)
628 arg_entry_t *ae;
630 for (++argv; *argv; argv++) {
631 ae = get_arg_ent(*argv);
633 switch (ae->auditconfig_cmd) {
635 case AC_ARG_AUDIT:
637 char sorf;
638 int retval;
639 char *event_name;
640 char *audit_str;
642 ++argv;
643 event_name = *argv;
644 ++argv;
645 sorf = (char)atoi(*argv);
646 ++argv;
647 retval = atoi(*argv);
648 ++argv;
649 audit_str = *argv;
650 do_audit(event_name, sorf, retval, audit_str);
652 break;
654 case AC_ARG_CHKCONF:
655 do_chkconf();
656 break;
658 case AC_ARG_CONF:
659 do_conf();
660 break;
662 case AC_ARG_CHKACONF:
663 do_chkaconf();
664 break;
666 case AC_ARG_ACONF:
667 do_aconf();
668 break;
670 case AC_ARG_GETASID:
671 do_getasid();
672 break;
674 case AC_ARG_GETAUID:
675 do_getauid();
676 break;
678 case AC_ARG_GETAUDIT:
679 do_getaudit();
680 break;
682 case AC_ARG_GETKAUDIT:
683 do_getkaudit();
684 break;
686 case AC_ARG_GETCLASS:
687 case AC_ARG_GETESTATE:
688 ++argv;
689 do_getclass(*argv);
690 break;
692 case AC_ARG_GETCAR:
693 do_getcar();
694 break;
696 case AC_ARG_GETCOND:
697 do_getcond();
698 break;
700 case AC_ARG_GETCWD:
701 do_getcwd();
702 break;
704 case AC_ARG_GETFLAGS:
705 do_getflags();
706 break;
708 case AC_ARG_GETKMASK:
709 do_getkmask();
710 break;
712 case AC_ARG_GETNAFLAGS:
713 do_getnaflags();
714 break;
716 case AC_ARG_GETPLUGIN:
718 char *plugin_str = NULL;
720 ++argv;
721 if (*argv != NULL) {
722 if (get_arg_ent(*argv) != NULL) {
723 --argv;
724 } else {
725 plugin_str = *argv;
727 } else {
728 --argv;
731 do_getplugin(plugin_str);
733 break;
735 case AC_ARG_GETPOLICY:
736 do_getpolicy();
737 break;
739 case AC_ARG_GETQBUFSZ:
740 do_getqbufsz();
741 break;
743 case AC_ARG_GETQCTRL:
744 do_getqctrl();
745 break;
747 case AC_ARG_GETQDELAY:
748 do_getqdelay();
749 break;
751 case AC_ARG_GETQHIWATER:
752 do_getqhiwater();
753 break;
755 case AC_ARG_GETQLOWATER:
756 do_getqlowater();
757 break;
759 case AC_ARG_GETSTAT:
760 do_getstat();
761 break;
763 case AC_ARG_GETTERMID:
764 do_gettermid();
765 break;
767 case AC_ARG_LSEVENT:
768 do_lsevent();
769 break;
771 case AC_ARG_LSPOLICY:
772 do_lspolicy();
773 break;
775 case AC_ARG_SETASID:
777 char *sid_str;
779 ++argv;
780 sid_str = *argv;
781 ++argv;
782 do_setasid(sid_str, argv);
784 break;
786 case AC_ARG_SETAUID:
788 char *user;
790 ++argv;
791 user = *argv;
792 ++argv;
793 do_setauid(user, argv);
795 break;
797 case AC_ARG_SETAUDIT:
799 char *user_str;
800 char *mask_str;
801 char *tid_str;
802 char *sid_str;
804 ++argv;
805 user_str = *argv;
806 ++argv;
807 mask_str = *argv;
808 ++argv;
809 tid_str = *argv;
810 ++argv;
811 sid_str = *argv;
812 ++argv;
813 do_setaudit(user_str, mask_str, tid_str,
814 sid_str, argv);
816 break;
818 case AC_ARG_SETKAUDIT:
820 char *address_type, *address;
822 ++argv; address_type = *argv;
823 ++argv; address = *argv;
824 do_setkaudit(address_type, address);
826 break;
828 case AC_ARG_SETCLASS:
830 char *event_str;
832 ++argv;
833 event_str = *argv;
834 do_setclass(event_str, mask);
836 ++argv;
838 break;
840 case AC_ARG_SETFLAGS:
841 ++argv;
842 do_setflags(*argv, mask);
843 break;
845 case AC_ARG_SETKMASK:
846 ++argv;
847 do_setkmask(mask);
848 break;
850 case AC_ARG_SETNAFLAGS:
851 ++argv;
852 do_setnaflags(*argv, mask);
853 break;
855 case AC_ARG_SETPLUGIN:
857 char *plugin_str = NULL;
858 boolean_t plugin_state = B_FALSE;
859 char *plugin_att = NULL;
860 int plugin_qsize = -1;
862 plugin_str = *++argv;
863 if (strcmp(*++argv, "active") == 0) {
864 plugin_state = B_TRUE;
866 if (*++argv != NULL &&
867 get_arg_ent(*argv) == NULL) {
868 plugin_att = *argv;
869 if (*++argv != NULL &&
870 get_arg_ent(*argv) == NULL) {
871 plugin_qsize = atoi(*argv);
872 } else {
873 --argv;
875 } else {
876 --argv;
879 do_setplugin(plugin_str, plugin_state,
880 plugin_att, plugin_qsize);
882 break;
884 case AC_ARG_SETPOLICY:
885 ++argv;
886 do_setpolicy(*argv);
887 break;
889 case AC_ARG_GETPINFO:
891 char *pid_str;
893 ++argv;
894 pid_str = *argv;
895 do_getpinfo(pid_str);
897 break;
899 case AC_ARG_SETPMASK:
901 char *pid_str;
903 ++argv;
904 pid_str = *argv;
905 do_setpmask(pid_str, mask);
907 ++argv;
909 break;
911 case AC_ARG_SETSTAT:
912 do_setstat();
913 break;
915 case AC_ARG_SETQBUFSZ:
916 ++argv;
917 do_setqbufsz(*argv);
918 break;
920 case AC_ARG_SETQCTRL:
922 char *hiwater, *lowater, *bufsz, *delay;
924 ++argv; hiwater = *argv;
925 ++argv; lowater = *argv;
926 ++argv; bufsz = *argv;
927 ++argv; delay = *argv;
928 do_setqctrl(hiwater, lowater, bufsz, delay);
930 break;
931 case AC_ARG_SETQDELAY:
932 ++argv;
933 do_setqdelay(*argv);
934 break;
936 case AC_ARG_SETQHIWATER:
937 ++argv;
938 do_setqhiwater(*argv);
939 break;
941 case AC_ARG_SETQLOWATER:
942 ++argv;
943 do_setqlowater(*argv);
944 break;
946 case AC_ARG_SETSMASK:
948 char *asid_str;
950 ++argv;
951 asid_str = *argv;
952 do_setsmask(asid_str, mask);
954 ++argv;
956 break;
957 case AC_ARG_SETUMASK:
959 char *auid_str;
961 ++argv;
962 auid_str = *argv;
963 do_setumask(auid_str, mask);
965 ++argv;
967 break;
968 case AC_ARG_SET_TEMPORARY:
969 break;
971 default:
972 exit_error(gettext("Internal error #2."));
973 break;
979 * do_chkconf() - the returned value is for the global zone unless AUDIT_PERZONE
980 * is set.
982 static void
983 do_chkconf(void)
985 register au_event_ent_t *evp;
986 au_mask_t pmask;
987 char conf_aflags[256];
988 char run_aflags[256];
989 au_stat_t as;
990 int class;
991 int len;
992 struct au_evclass_map cmap;
994 pmask.am_success = pmask.am_failure = 0;
995 eauditon(A_GETSTAT, (caddr_t)&as, 0);
997 setauevent();
998 if (getauevent() == NULL) {
999 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1000 AUDITEVENTFILE);
1003 setauevent();
1004 while ((evp = getauevent()) != NULL) {
1005 cmap.ec_number = evp->ae_number;
1006 len = sizeof (struct au_evclass_map);
1007 if (evp->ae_number <= as.as_numevent) {
1008 if (auditon(A_GETCLASS, (caddr_t)&cmap, len) == -1) {
1009 (void) printf("%s(%hu):%s",
1010 evp->ae_name, evp->ae_number,
1011 gettext("UNKNOWN EVENT: Could not get "
1012 "class for event. Configuration may "
1013 "be bad.\n"));
1014 } else {
1015 class = cmap.ec_class;
1016 if (class != evp->ae_class) {
1017 conf_aflags[0] = run_aflags[0] = '\0';
1018 pmask.am_success = class;
1019 pmask.am_failure = class;
1020 (void) getauditflagschar(run_aflags,
1021 &pmask, 0);
1022 pmask.am_success = evp->ae_class;
1023 pmask.am_failure = evp->ae_class;
1024 (void) getauditflagschar(conf_aflags,
1025 &pmask, 0);
1027 (void) printf(gettext(
1028 "%s(%hu): CLASS MISMATCH: "
1029 "runtime class (%s) != "
1030 "configured class (%s)\n"),
1031 evp->ae_name, evp->ae_number,
1032 NONE(run_aflags),
1033 NONE(conf_aflags));
1038 endauevent();
1042 * do_conf() - configure the kernel events. The value returned to the user is
1043 * for the global zone unless AUDIT_PERZONE is set.
1045 static void
1046 do_conf(void)
1048 register au_event_ent_t *evp;
1049 register int i;
1050 au_evclass_map_t ec;
1051 au_stat_t as;
1053 eauditon(A_GETSTAT, (caddr_t)&as, 0);
1055 i = 0;
1056 setauevent();
1057 while ((evp = getauevent()) != NULL) {
1058 if (evp->ae_number <= as.as_numevent) {
1059 ++i;
1060 ec.ec_number = evp->ae_number;
1061 ec.ec_class = evp->ae_class;
1062 eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1065 endauevent();
1066 (void) printf(gettext("Configured %d kernel events.\n"), i);
1071 * do_chkaconf() - report a mismatch if the runtime class mask of a kernel audit
1072 * event does not match the configured class mask. The value returned to the
1073 * user is for the global zone unless AUDIT_PERZONE is set.
1075 static void
1076 do_chkaconf(void)
1078 char *namask_cfg;
1079 au_mask_t pmask, kmask;
1081 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1082 exit_error(gettext("Could not get configured value."));
1084 egetauditflagsbin(namask_cfg, &pmask);
1086 eauditon(A_GETKMASK, (caddr_t)&kmask, sizeof (kmask));
1088 if ((pmask.am_success != kmask.am_success) ||
1089 (pmask.am_failure != kmask.am_failure)) {
1090 char kbuf[2048];
1091 if (getauditflagschar(kbuf, &kmask, 0) < 0) {
1092 free(namask_cfg);
1093 (void) fprintf(stderr,
1094 gettext("bad kernel non-attributable mask\n"));
1095 exit(1);
1097 (void) printf(
1098 gettext("non-attributable event flags mismatch:\n"));
1099 (void) printf(gettext("active non-attributable audit flags "
1100 "= %s\n"), kbuf);
1101 (void) printf(gettext("configured non-attributable audit flags "
1102 "= %s\n"), namask_cfg);
1104 free(namask_cfg);
1108 * do_aconf - configures the non-attributable events. The value returned to the
1109 * user is for the global zone unless AUDIT_PERZONE is set.
1111 static void
1112 do_aconf(void)
1114 au_mask_t namask;
1115 char *namask_cfg;
1117 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1118 exit_error(gettext("Could not get configured value."));
1120 egetauditflagsbin(namask_cfg, &namask);
1121 free(namask_cfg);
1123 eauditon(A_SETKMASK, (caddr_t)&namask, sizeof (namask));
1124 (void) printf(gettext("Configured non-attributable event mask.\n"));
1128 * do_audit() - construct an audit record for audit event event using the
1129 * process's audit characteristics containing a text token string audit_str. The
1130 * return token is constructed from the success/failure flag sort. Returned
1131 * value retval is an errno value.
1133 static void
1134 do_audit(char *event, char sorf, int retval, char *audit_str)
1136 int rtn;
1137 int rd;
1138 au_event_t event_num;
1139 au_event_ent_t *evp;
1140 auditinfo_addr_t ai;
1141 token_t *tokp;
1143 egetaudit(&ai, sizeof (ai));
1145 if (strisnum(event)) {
1146 event_num = (au_event_t)atoi(event);
1147 evp = egetauevnum(event_num);
1148 } else {
1149 evp = egetauevnam(event);
1152 rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
1153 AU_PRS_USECACHE);
1155 if (rtn == -1) {
1156 exit_error("%s\n%s %hu\n",
1157 gettext("Check audit event configuration."),
1158 gettext("Could not get audit class for event number"),
1159 evp->ae_number);
1162 /* record is preselected */
1163 if (rtn == 1) {
1164 if ((rd = au_open()) == -1) {
1165 exit_error(gettext(
1166 "Could not get and audit record descriptor\n"));
1168 if ((tokp = au_to_me()) == NULL) {
1169 exit_error(
1170 gettext("Could not allocate subject token\n"));
1172 if (au_write(rd, tokp) == -1) {
1173 exit_error(gettext("Could not construct subject token "
1174 "of audit record\n"));
1177 if ((tokp = au_to_text(audit_str)) == NULL)
1178 exit_error(gettext("Could not allocate text token\n"));
1179 if (au_write(rd, tokp) == -1)
1180 exit_error(gettext("Could not construct text token of "
1181 "audit record\n"));
1182 #ifdef _LP64
1183 if ((tokp = au_to_return64(sorf, retval)) == NULL)
1184 #else
1185 if ((tokp = au_to_return32(sorf, retval)) == NULL)
1186 #endif
1187 exit_error(
1188 gettext("Could not allocate return token\n"));
1189 if (au_write(rd, tokp) == -1) {
1190 exit_error(gettext("Could not construct return token "
1191 "of audit record\n"));
1193 if (au_close(rd, 1, evp->ae_number) == -1) {
1194 exit_error(
1195 gettext("Could not write audit record: %s\n"),
1196 strerror(errno));
1202 * do_getauid() - print the audit id of the current process.
1204 static void
1205 do_getauid(void)
1207 au_id_t auid;
1209 egetauid(&auid);
1210 print_auid(auid);
1214 * do_getaudit() - print the audit characteristics of the current process.
1216 static void
1217 do_getaudit(void)
1219 auditinfo_addr_t ai;
1221 egetaudit(&ai, sizeof (ai));
1222 print_auid(ai.ai_auid);
1223 print_mask(gettext("process preselection mask"), &ai.ai_mask);
1224 print_tid_ex(&ai.ai_termid);
1225 print_asid(ai.ai_asid);
1229 * do_getkaudit() - print the audit characteristics of the current zone.
1231 static void
1232 do_getkaudit(void)
1234 auditinfo_addr_t ai;
1236 egetkaudit(&ai, sizeof (ai));
1237 print_auid(ai.ai_auid);
1238 print_mask(gettext("process preselection mask"), &ai.ai_mask);
1239 print_tid_ex(&ai.ai_termid);
1240 print_asid(ai.ai_asid);
1244 * do_setkaudit() - set IP address_type/address of machine to specified values;
1245 * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1247 static void
1248 do_setkaudit(char *t, char *s)
1250 uint_t type;
1251 auditinfo_addr_t ai;
1253 egetkaudit(&ai, sizeof (ai));
1254 (void) str2type(t, &type);
1255 (void) str2ipaddr(s, &ai.ai_termid.at_addr[0], type);
1256 ai.ai_termid.at_type = type;
1257 esetkaudit(&ai, sizeof (ai));
1261 * do_getcar() - print the zone-relative root
1263 static void
1264 do_getcar(void)
1266 char path[MAXPATHLEN];
1268 eauditon(A_GETCAR, (caddr_t)path, sizeof (path));
1269 (void) printf(gettext("current active root = %s\n"), path);
1273 * do_getclass() - print the preselection mask associated with the specified
1274 * kernel audit event. The displayed value is for the global zone unless
1275 * AUDIT_PERZONE is set.
1277 static void
1278 do_getclass(char *event_str)
1280 au_evclass_map_t ec;
1281 au_event_ent_t *evp;
1282 au_event_t event_number;
1283 char *event_name;
1285 if (strisnum(event_str)) {
1286 event_number = atol(event_str);
1287 if ((evp = egetauevnum(event_number)) != NULL) {
1288 event_number = evp->ae_number;
1289 event_name = evp->ae_name;
1290 } else {
1291 event_name = gettext("unknown");
1293 } else {
1294 event_name = event_str;
1295 if ((evp = egetauevnam(event_str)) != NULL) {
1296 event_number = evp->ae_number;
1300 ec.ec_number = event_number;
1301 eauditon(A_GETCLASS, (caddr_t)&ec, 0);
1303 (void) printf(gettext("audit class mask for event %s(%hu) = 0x%x\n"),
1304 event_name, event_number, ec.ec_class);
1308 * do_getcond() - the printed value is for the global zone unless
1309 * AUDIT_PERZONE is set. (AUC_DISABLED is always global, the other states are
1310 * per zone if AUDIT_PERZONE is set)
1312 static void
1313 do_getcond(void)
1315 (void) printf(gettext("audit condition = %s\n"), cond2str());
1319 * do_getcwd() - the printed path is relative to the current zone root
1321 static void
1322 do_getcwd(void)
1324 char path[MAXPATHLEN];
1326 eauditon(A_GETCWD, (caddr_t)path, sizeof (path));
1327 (void) printf(gettext("current working directory = %s\n"), path);
1331 * do_getflags() - the printed value is for the global zone unless AUDIT_PERZONE
1332 * is set.
1334 static void
1335 do_getflags(void)
1337 au_mask_t amask;
1338 char *amask_cfg;
1340 eauditon(A_GETAMASK, (caddr_t)&amask, sizeof (amask));
1341 print_mask(gettext("active user default audit flags"), &amask);
1343 if (!do_getflags_scf(&amask_cfg) || amask_cfg == NULL) {
1344 exit_error(gettext("Could not get configured value."));
1346 egetauditflagsbin(amask_cfg, &amask);
1347 print_mask(gettext("configured user default audit flags"), &amask);
1348 free(amask_cfg);
1352 * do_getkmask() - the printed value is for the global zone unless AUDIT_PERZONE
1353 * is set.
1355 static void
1356 do_getkmask(void)
1358 au_mask_t pmask;
1360 eauditon(A_GETKMASK, (caddr_t)&pmask, sizeof (pmask));
1361 print_mask(gettext("active non-attributable audit flags"), &pmask);
1365 * do_getnaflags() - the printed value is for the global zone unless
1366 * AUDIT_PERZONE is set.
1368 static void
1369 do_getnaflags(void)
1371 au_mask_t namask;
1372 char *namask_cfg;
1374 eauditon(A_GETKMASK, (caddr_t)&namask, sizeof (namask));
1375 print_mask(gettext("active non-attributable audit flags"), &namask);
1377 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1378 exit_error(gettext("Could not get configured value."));
1380 egetauditflagsbin(namask_cfg, &namask);
1381 print_mask(gettext("configured non-attributable audit flags"), &namask);
1382 free(namask_cfg);
1386 * do_getpolicy() - print active and configured kernel audit policy relative to
1387 * the current zone.
1389 static void
1390 do_getpolicy(void)
1392 char policy_str[1024];
1393 uint32_t policy;
1395 if (!temporary_set) {
1396 if (!do_getpolicy_scf(&policy)) {
1397 exit_error(gettext("Could not get configured values."));
1399 (void) policy2str(policy, policy_str, sizeof (policy_str));
1400 (void) printf(gettext("configured audit policies = %s\n"),
1401 policy_str);
1404 eauditon(A_GETPOLICY, (caddr_t)&policy, 0);
1405 (void) policy2str(policy, policy_str, sizeof (policy_str));
1406 (void) printf(gettext("active audit policies = %s\n"), policy_str);
1411 * do_getpinfo() - print the audit ID, preselection mask, terminal ID, and
1412 * audit session ID for the specified process.
1414 static void
1415 do_getpinfo(char *pid_str)
1417 struct auditpinfo_addr ap;
1419 if (strisnum(pid_str))
1420 ap.ap_pid = (pid_t)atoi(pid_str);
1421 else
1422 exit_usage(1);
1424 eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
1426 print_auid(ap.ap_auid);
1427 print_mask(gettext("process preselection mask"), &(ap.ap_mask));
1428 print_tid_ex(&(ap.ap_termid));
1429 print_asid(ap.ap_asid);
1433 * do_getplugin() - print plugin configuration.
1435 static void
1436 do_getplugin(char *plugin_str)
1438 scf_plugin_kva_node_t *plugin_kva_ll;
1439 scf_plugin_kva_node_t *plugin_kva_ll_head;
1441 if (!do_getpluginconfig_scf(plugin_str, &plugin_kva_ll)) {
1442 exit_error(gettext("Could not get plugin configuration."));
1445 plugin_kva_ll_head = plugin_kva_ll;
1447 while (plugin_kva_ll != NULL) {
1448 print_plugin(plugin_kva_ll->plugin_name,
1449 plugin_kva_ll->plugin_kva);
1450 plugin_kva_ll = plugin_kva_ll->next;
1451 if (plugin_kva_ll != NULL) {
1452 (void) printf("\n");
1455 plugin_kva_ll_free(plugin_kva_ll_head);
1459 * do_getqbufsz() - print the active and configured audit queue write buffer
1460 * size relative to the current zone.
1462 static void
1463 do_getqbufsz(void)
1465 struct au_qctrl qctrl;
1467 if (!temporary_set) {
1468 if (!do_getqbufsz_scf(&qctrl.aq_bufsz)) {
1469 exit_error(gettext("Could not get configured value."));
1472 if (qctrl.aq_bufsz == 0) {
1473 (void) printf(gettext(
1474 "no configured audit queue buffer size\n"));
1475 } else {
1476 (void) printf(gettext("configured audit queue "
1477 "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1481 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1482 (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1483 qctrl.aq_bufsz);
1487 * do_getqctrl() - print the configured and active audit queue write buffer
1488 * size, audit queue hiwater mark, audit queue lowater mark, audit queue prod
1489 * interval (ticks) relative to the current zone.
1491 static void
1492 do_getqctrl(void)
1494 struct au_qctrl qctrl;
1496 if (!temporary_set) {
1497 if (!do_getqctrl_scf(&qctrl)) {
1498 exit_error(gettext("Could not get configured values."));
1501 if (qctrl.aq_hiwater == 0) {
1502 (void) printf(gettext(
1503 "no configured audit queue hiwater mark\n"));
1504 } else {
1505 (void) printf(gettext("configured audit queue "
1506 "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1508 if (qctrl.aq_lowater == 0) {
1509 (void) printf(gettext(
1510 "no configured audit queue lowater mark\n"));
1511 } else {
1512 (void) printf(gettext("configured audit queue "
1513 "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1515 if (qctrl.aq_bufsz == 0) {
1516 (void) printf(gettext(
1517 "no configured audit queue buffer size\n"));
1518 } else {
1519 (void) printf(gettext("configured audit queue "
1520 "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1522 if (qctrl.aq_delay == 0) {
1523 (void) printf(gettext(
1524 "no configured audit queue delay\n"));
1525 } else {
1526 (void) printf(gettext("configured audit queue "
1527 "delay (ticks) = %ld\n"), qctrl.aq_delay);
1531 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1532 (void) printf(gettext("active audit queue hiwater mark "
1533 "(records) = %d\n"), qctrl.aq_hiwater);
1534 (void) printf(gettext("active audit queue lowater mark "
1535 "(records) = %d\n"), qctrl.aq_lowater);
1536 (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1537 qctrl.aq_bufsz);
1538 (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1539 qctrl.aq_delay);
1543 * do_getqdelay() - print, relative to the current zone, the configured and
1544 * active interval at which audit queue is prodded to start output.
1546 static void
1547 do_getqdelay(void)
1549 struct au_qctrl qctrl;
1551 if (!temporary_set) {
1552 if (!do_getqdelay_scf(&qctrl.aq_delay)) {
1553 exit_error(gettext("Could not get configured value."));
1556 if (qctrl.aq_delay == 0) {
1557 (void) printf(gettext(
1558 "no configured audit queue delay\n"));
1559 } else {
1560 (void) printf(gettext("configured audit queue "
1561 "delay (ticks) = %ld\n"), qctrl.aq_delay);
1565 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1566 (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1567 qctrl.aq_delay);
1571 * do_getqhiwater() - print, relative to the current zone, the high water
1572 * point in undelivered audit records when audit generation will block.
1574 static void
1575 do_getqhiwater(void)
1577 struct au_qctrl qctrl;
1579 if (!temporary_set) {
1580 if (!do_getqhiwater_scf(&qctrl.aq_hiwater)) {
1581 exit_error(gettext("Could not get configured value."));
1584 if (qctrl.aq_hiwater == 0) {
1585 (void) printf(gettext(
1586 "no configured audit queue hiwater mark\n"));
1587 } else {
1588 (void) printf(gettext("configured audit queue "
1589 "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1593 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1594 (void) printf(gettext("active audit queue hiwater mark "
1595 "(records) = %d\n"), qctrl.aq_hiwater);
1599 * do_getqlowater() - print, relative to the current zone, the low water point
1600 * in undelivered audit records where blocked processes will resume.
1602 static void
1603 do_getqlowater(void)
1605 struct au_qctrl qctrl;
1607 if (!temporary_set) {
1608 if (!do_getqlowater_scf(&qctrl.aq_lowater)) {
1609 exit_error(gettext("Could not get configured value."));
1612 if (qctrl.aq_lowater == 0) {
1613 (void) printf(gettext(
1614 "no configured audit queue lowater mark\n"));
1615 } else {
1616 (void) printf(gettext("configured audit queue "
1617 "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1621 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1622 (void) printf(gettext("active audit queue lowater mark "
1623 "(records) = %d\n"), qctrl.aq_lowater);
1627 * do_getasid() - print out the audit session-ID.
1629 static void
1630 do_getasid(void)
1632 auditinfo_addr_t ai;
1634 if (getaudit_addr(&ai, sizeof (ai))) {
1635 exit_error(gettext("getaudit_addr(2) failed"));
1637 print_asid(ai.ai_asid);
1641 * do_getstat() - the printed statistics are for the entire system unless
1642 * AUDIT_PERZONE is set.
1644 static void
1645 do_getstat(void)
1647 au_stat_t as;
1648 int offset[12]; /* used to line the header up correctly */
1649 char buf[512];
1651 eauditon(A_GETSTAT, (caddr_t)&as, 0);
1652 (void) sprintf(buf, "%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu "
1653 "%n%4lu %n%4lu %n%4lu %n%4lu %n%4lu%n",
1654 (ulong_t)as.as_generated, &(offset[0]),
1655 (ulong_t)as.as_nonattrib, &(offset[1]),
1656 (ulong_t)as.as_kernel, &(offset[2]),
1657 (ulong_t)as.as_audit, &(offset[3]),
1658 (ulong_t)as.as_auditctl, &(offset[4]),
1659 (ulong_t)as.as_enqueue, &(offset[5]),
1660 (ulong_t)as.as_written, &(offset[6]),
1661 (ulong_t)as.as_wblocked, &(offset[7]),
1662 (ulong_t)as.as_rblocked, &(offset[8]),
1663 (ulong_t)as.as_dropped, &(offset[9]),
1664 (ulong_t)as.as_totalsize / ONEK, &(offset[10]),
1665 (ulong_t)as.as_memused / ONEK, &(offset[11]));
1668 * TRANSLATION_NOTE
1669 * Print a properly aligned header.
1671 (void) printf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n",
1672 offset[0] - 1, gettext("gen"),
1673 offset[1] - offset[0] -1, gettext("nona"),
1674 offset[2] - offset[1] -1, gettext("kern"),
1675 offset[3] - offset[2] -1, gettext("aud"),
1676 offset[4] - offset[3] -1, gettext("ctl"),
1677 offset[5] - offset[4] -1, gettext("enq"),
1678 offset[6] - offset[5] -1, gettext("wrtn"),
1679 offset[7] - offset[6] -1, gettext("wblk"),
1680 offset[8] - offset[7] -1, gettext("rblk"),
1681 offset[9] - offset[8] -1, gettext("drop"),
1682 offset[10] - offset[9] -1, gettext("tot"),
1683 offset[11] - offset[10], gettext("mem"));
1685 (void) printf("%s\n", buf);
1689 * do_gettermid() - print audit terminal ID for current process.
1691 static void
1692 do_gettermid(void)
1694 auditinfo_addr_t ai;
1696 if (getaudit_addr(&ai, sizeof (ai))) {
1697 exit_error(gettext("getaudit_addr(2) failed"));
1699 print_tid_ex(&ai.ai_termid);
1703 * do_lsevent() - display the active kernel and user level audit event
1704 * information. The printed events are for the global zone unless AUDIT_PERZONE
1705 * is set.
1707 static void
1708 do_lsevent(void)
1710 register au_event_ent_t *evp;
1711 au_mask_t pmask;
1712 char auflags[256];
1714 setauevent();
1715 if (getauevent() == NULL) {
1716 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1717 AUDITEVENTFILE);
1720 setauevent();
1721 while ((evp = getauevent()) != NULL) {
1722 pmask.am_success = pmask.am_failure = evp->ae_class;
1723 if (getauditflagschar(auflags, &pmask, 0) == -1)
1724 (void) strcpy(auflags, "unknown");
1725 (void) printf("%-30s %5hu %s %s\n",
1726 evp->ae_name, evp->ae_number, auflags, evp->ae_desc);
1728 endauevent();
1732 * do_lspolicy() - display the kernel audit policies with a description of each
1733 * policy. The printed value is for the global zone unless AUDIT_PERZONE is set.
1735 static void
1736 do_lspolicy(void)
1738 int i;
1741 * TRANSLATION_NOTE
1742 * Print a properly aligned header.
1744 (void) printf(gettext("policy string description:\n"));
1745 for (i = 0; i < POLICY_TBL_SZ; i++) {
1746 (void) printf("%-17s%s\n", policy_table[i].policy_str,
1747 gettext(policy_table[i].policy_desc));
1752 * do_setasid() - execute shell or cmd with specified session-ID.
1754 static void
1755 do_setasid(char *sid_str, char **argv)
1757 struct auditinfo_addr ai;
1759 if (getaudit_addr(&ai, sizeof (ai))) {
1760 exit_error(gettext("getaudit_addr(2) failed"));
1762 ai.ai_asid = (au_asid_t)atol(sid_str);
1763 if (setaudit_addr(&ai, sizeof (ai))) {
1764 exit_error(gettext("setaudit_addr(2) failed"));
1766 execit(argv);
1770 * do_setaudit() - execute shell or cmd with specified audit characteristics.
1772 static void
1773 do_setaudit(char *user_str, char *mask_str, char *tid_str, char *sid_str,
1774 char **argv)
1776 auditinfo_addr_t ai;
1778 ai.ai_auid = (au_id_t)get_user_id(user_str);
1779 egetauditflagsbin(mask_str, &ai.ai_mask),
1780 str2tid(tid_str, &ai.ai_termid);
1781 ai.ai_asid = (au_asid_t)atol(sid_str);
1783 esetaudit(&ai, sizeof (ai));
1784 execit(argv);
1788 * do_setauid() - execute shell or cmd with specified audit-ID.
1790 static void
1791 do_setauid(char *user, char **argv)
1793 au_id_t auid;
1795 auid = get_user_id(user);
1796 esetauid(&auid);
1797 execit(argv);
1801 * do_setpmask() - set the preselection mask of the specified process; valid
1802 * per zone if AUDIT_PERZONE is set, else only in global zone.
1804 static void
1805 do_setpmask(char *pid_str, au_mask_t *mask)
1807 struct auditpinfo ap;
1809 if (strisnum(pid_str)) {
1810 ap.ap_pid = (pid_t)atoi(pid_str);
1811 } else {
1812 exit_usage(1);
1815 ap.ap_mask.am_success = mask->am_success;
1816 ap.ap_mask.am_failure = mask->am_failure;
1818 eauditon(A_SETPMASK, (caddr_t)&ap, sizeof (ap));
1822 * do_setsmask() - set the preselection mask of all processes with the specified
1823 * audit session-ID; valid per zone if AUDIT_PERZONE is set, else only in global
1824 * zone.
1826 static void
1827 do_setsmask(char *asid_str, au_mask_t *mask)
1829 struct auditinfo ainfo;
1831 if (strisnum(asid_str)) {
1832 ainfo.ai_asid = (au_asid_t)atoi(asid_str);
1833 } else {
1834 exit_usage(1);
1837 ainfo.ai_mask.am_success = mask->am_success;
1838 ainfo.ai_mask.am_failure = mask->am_failure;
1840 eauditon(A_SETSMASK, (caddr_t)&ainfo, sizeof (ainfo));
1844 * do_setumask() - set the preselection mask of all processes with the
1845 * specified audit-ID; valid per zone if AUDIT_PERZONE is set, else only in
1846 * global zone.
1848 static void
1849 do_setumask(char *auid_str, au_mask_t *mask)
1851 struct auditinfo ainfo;
1853 if (strisnum(auid_str)) {
1854 ainfo.ai_auid = (au_id_t)atoi(auid_str);
1855 } else {
1856 exit_usage(1);
1859 ainfo.ai_mask.am_success = mask->am_success;
1860 ainfo.ai_mask.am_failure = mask->am_failure;
1862 eauditon(A_SETUMASK, (caddr_t)&ainfo, sizeof (ainfo));
1866 * do_setstat() - reset audit statistics counters; local zone use is valid if
1867 * AUDIT_PERZONE is set, otherwise the syscall returns EPERM.
1869 static void
1870 do_setstat(void)
1872 au_stat_t as;
1874 as.as_audit = (uint_t)-1;
1875 as.as_auditctl = (uint_t)-1;
1876 as.as_dropped = (uint_t)-1;
1877 as.as_enqueue = (uint_t)-1;
1878 as.as_generated = (uint_t)-1;
1879 as.as_kernel = (uint_t)-1;
1880 as.as_nonattrib = (uint_t)-1;
1881 as.as_rblocked = (uint_t)-1;
1882 as.as_totalsize = (uint_t)-1;
1883 as.as_wblocked = (uint_t)-1;
1884 as.as_written = (uint_t)-1;
1886 eauditon(A_SETSTAT, (caddr_t)&as, sizeof (as));
1887 (void) printf("%s\n", gettext("audit stats reset"));
1891 * do_setclass() - map the kernel event event_str to the classes specified by
1892 * audit flags (mask); valid per zone if AUDIT_PERZONE is set, else only in
1893 * global zone.
1895 static void
1896 do_setclass(char *event_str, au_mask_t *mask)
1898 au_event_t event;
1899 au_evclass_map_t ec;
1900 au_event_ent_t *evp;
1902 if (strisnum(event_str)) {
1903 event = (uint_t)atol(event_str);
1904 } else {
1905 if ((evp = egetauevnam(event_str)) != NULL) {
1906 event = evp->ae_number;
1910 ec.ec_number = event;
1911 ec.ec_class = (mask->am_success | mask->am_failure);
1913 eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1917 * do_setflags() - set configured and active default user preselection masks;
1918 * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1920 static void
1921 do_setflags(char *audit_flags, au_mask_t *amask)
1923 eauditon(A_SETAMASK, (caddr_t)amask, sizeof (*amask));
1925 if (!do_setflags_scf(audit_flags)) {
1926 print_mask(gettext("active user default audit flags"), amask);
1927 exit_error(gettext("Could not store configuration value."));
1929 print_mask(gettext("user default audit flags"), amask);
1933 * do_setkmask() - set non-attributable audit flags of machine; valid per zone
1934 * if AUDIT_PERZONE is set, else only in global zone.
1936 static void
1937 do_setkmask(au_mask_t *pmask)
1939 eauditon(A_SETKMASK, (caddr_t)pmask, sizeof (*pmask));
1940 print_mask(gettext("active non-attributable audit flags"), pmask);
1944 * do_setnaflags() - set configured and active non-attributable selection flags
1945 * of machine; valid per zone if AUDIT_PERZONE is set, else only in global zone.
1947 static void
1948 do_setnaflags(char *audit_naflags, au_mask_t *namask)
1950 eauditon(A_SETKMASK, (caddr_t)namask, sizeof (*namask));
1952 if (!do_setnaflags_scf(audit_naflags)) {
1953 print_mask(
1954 gettext("active non-attributable audit flags"), namask);
1955 exit_error(gettext("Could not store configuration value."));
1957 print_mask(gettext("non-attributable audit flags"), namask);
1961 * do_setplugin() - set the given plugin plugin_str configuration values.
1963 static void
1964 do_setplugin(char *plugin_str, boolean_t plugin_state, char *plugin_attr,
1965 int plugin_qsize)
1967 if (!do_setpluginconfig_scf(plugin_str, plugin_state, plugin_attr,
1968 plugin_qsize)) {
1969 exit_error(gettext("Could not set plugin configuration."));
1974 * do_setpolicy() - set the active and configured kernel audit policy; active
1975 * values can be changed per zone if AUDIT_PERZONE is set, else only in global
1976 * zone.
1978 * ahlt and perzone are global zone only. The kernel ensures that a local zone
1979 * can't change ahlt and perzone (EINVAL).
1981 static void
1982 do_setpolicy(char *policy_str)
1984 uint32_t policy = 0;
1986 switch (str2policy(policy_str, &policy)) {
1987 case 0:
1988 if (!temporary_set) {
1989 if (!do_getpolicy_scf(&policy)) {
1990 exit_error(gettext("Unable to get current "
1991 "policy values from the SMF repository"));
1993 (void) str2policy(policy_str, &policy);
1995 if (!do_setpolicy_scf(policy)) {
1996 exit_error(gettext("Could not store "
1997 "configuration values."));
2000 eauditon(A_SETPOLICY, (caddr_t)&policy, 0);
2001 break;
2002 case 2:
2003 exit_error(gettext("policy (%s) invalid in a local zone."),
2004 policy_str);
2005 break;
2006 default:
2007 exit_error(gettext("Invalid policy (%s) specified."),
2008 policy_str);
2009 break;
2014 * do_setqbufsz() - set the active and configured audit queue write buffer size
2015 * (bytes); active values can be changed per zone if AUDIT_PERZONE is set, else
2016 * only in global zone.
2018 static void
2019 do_setqbufsz(char *bufsz)
2021 struct au_qctrl qctrl;
2023 if (!temporary_set) {
2024 qctrl.aq_bufsz = (size_t)atol(bufsz);
2025 if (!do_setqbufsz_scf(&qctrl.aq_bufsz)) {
2026 exit_error(gettext(
2027 "Could not store configuration value."));
2029 if (qctrl.aq_bufsz == 0) {
2030 return;
2034 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2035 qctrl.aq_bufsz = (size_t)atol(bufsz);
2036 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2040 * do_setqctrl() - set the active and configured audit queue write buffer size
2041 * (bytes), hiwater audit record count, lowater audit record count, and wakeup
2042 * interval (ticks); active values can be changed per zone if AUDIT_PERZONE is
2043 * set, else only in global zone.
2045 static void
2046 do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay)
2048 struct au_qctrl qctrl;
2050 qctrl.aq_hiwater = (size_t)atol(hiwater);
2051 qctrl.aq_lowater = (size_t)atol(lowater);
2052 qctrl.aq_bufsz = (size_t)atol(bufsz);
2053 qctrl.aq_delay = (clock_t)atol(delay);
2055 if (!temporary_set) {
2056 struct au_qctrl qctrl_act;
2058 if (!do_setqctrl_scf(&qctrl)) {
2059 exit_error(gettext(
2060 "Could not store configuration values."));
2063 eauditon(A_GETQCTRL, (caddr_t)&qctrl_act, 0);
2064 if (qctrl.aq_hiwater == 0) {
2065 qctrl.aq_hiwater = qctrl_act.aq_hiwater;
2067 if (qctrl.aq_lowater == 0) {
2068 qctrl.aq_lowater = qctrl_act.aq_lowater;
2070 if (qctrl.aq_bufsz == 0) {
2071 qctrl.aq_bufsz = qctrl_act.aq_bufsz;
2073 if (qctrl.aq_delay == 0) {
2074 qctrl.aq_delay = qctrl_act.aq_delay;
2078 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2082 * do_setqdelay() - set the active and configured audit queue wakeup interval
2083 * (ticks); active values can be changed per zone if AUDIT_PERZONE is set, else
2084 * only in global zone.
2086 static void
2087 do_setqdelay(char *delay)
2089 struct au_qctrl qctrl;
2091 if (!temporary_set) {
2092 qctrl.aq_delay = (clock_t)atol(delay);
2093 if (!do_setqdelay_scf(&qctrl.aq_delay)) {
2094 exit_error(gettext(
2095 "Could not store configuration value."));
2097 if (qctrl.aq_delay == 0) {
2098 return;
2102 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2103 qctrl.aq_delay = (clock_t)atol(delay);
2104 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2108 * do_setqhiwater() - sets the active and configured number of undelivered audit
2109 * records in the audit queue at which audit record generation blocks; active
2110 * values can be changed per zone if AUDIT_PERZONE is set, else only in global
2111 * zone.
2113 static void
2114 do_setqhiwater(char *hiwater)
2116 struct au_qctrl qctrl;
2118 if (!temporary_set) {
2119 qctrl.aq_hiwater = (size_t)atol(hiwater);
2120 if (!do_setqhiwater_scf(&qctrl.aq_hiwater)) {
2121 exit_error(gettext(
2122 "Could not store configuration value."));
2124 if (qctrl.aq_hiwater == 0) {
2125 return;
2129 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2130 qctrl.aq_hiwater = (size_t)atol(hiwater);
2131 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2135 * do_setqlowater() - set the active and configured number of undelivered audit
2136 * records in the audit queue at which blocked auditing processes unblock;
2137 * active values can be changed per zone if AUDIT_PERZONE is set, else only in
2138 * global zone.
2140 static void
2141 do_setqlowater(char *lowater)
2143 struct au_qctrl qctrl;
2145 if (!temporary_set) {
2146 qctrl.aq_lowater = (size_t)atol(lowater);
2147 if (!do_setqlowater_scf(&qctrl.aq_lowater)) {
2148 exit_error(gettext(
2149 "Could not store configuration value."));
2151 if (qctrl.aq_lowater == 0) {
2152 return;
2156 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2157 qctrl.aq_lowater = (size_t)atol(lowater);
2158 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2161 static void
2162 eauditon(int cmd, caddr_t data, int length)
2164 if (auditon(cmd, data, length) == -1)
2165 exit_error(gettext("auditon(2) failed."));
2168 static void
2169 egetauid(au_id_t *auid)
2171 if (getauid(auid) == -1)
2172 exit_error(gettext("getauid(2) failed."));
2175 static void
2176 egetaudit(auditinfo_addr_t *ai, int size)
2178 if (getaudit_addr(ai, size) == -1)
2179 exit_error(gettext("getaudit_addr(2) failed."));
2182 static void
2183 egetkaudit(auditinfo_addr_t *ai, int size)
2185 if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
2186 exit_error(gettext("auditon: A_GETKAUDIT failed."));
2189 static void
2190 esetkaudit(auditinfo_addr_t *ai, int size)
2192 if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
2193 exit_error(gettext("auditon: A_SETKAUDIT failed."));
2196 static void
2197 egetauditflagsbin(char *auditflags, au_mask_t *pmask)
2199 if (strcmp(auditflags, "none") == 0) {
2200 pmask->am_success = pmask->am_failure = 0;
2201 return;
2204 if (getauditflagsbin(auditflags, pmask) < 0) {
2205 exit_error(gettext("Could not get audit flags (%s)"),
2206 auditflags);
2210 static void
2211 echkflags(char *auditflags, au_mask_t *mask)
2213 char *err = "";
2214 char *err_ptr;
2216 if (!__chkflags(auditflags, mask, B_FALSE, &err)) {
2217 err_ptr = err;
2218 while (*err_ptr != ',' && *err_ptr != '\0') {
2219 err_ptr++;
2221 *err_ptr = '\0';
2222 exit_error(gettext("Unknown audit flags and/or prefixes "
2223 "encountered: %s"), err);
2227 static au_event_ent_t *
2228 egetauevnum(au_event_t event_number)
2230 au_event_ent_t *evp;
2232 if ((evp = getauevnum(event_number)) == NULL) {
2233 exit_error(gettext("Could not get audit event %hu"),
2234 event_number);
2237 return (evp);
2240 static au_event_ent_t *
2241 egetauevnam(char *event_name)
2243 register au_event_ent_t *evp;
2245 if ((evp = getauevnam(event_name)) == NULL)
2246 exit_error(gettext("Could not get audit event %s"), event_name);
2248 return (evp);
2251 static void
2252 esetauid(au_id_t *auid)
2254 if (setauid(auid) == -1)
2255 exit_error(gettext("setauid(2) failed."));
2258 static void
2259 esetaudit(auditinfo_addr_t *ai, int size)
2261 if (setaudit_addr(ai, size) == -1)
2262 exit_error(gettext("setaudit_addr(2) failed."));
2265 static uid_t
2266 get_user_id(char *user)
2268 struct passwd *pwd;
2269 uid_t uid;
2271 if (isdigit(*user)) {
2272 uid = atoi(user);
2273 if ((pwd = getpwuid(uid)) == NULL) {
2274 exit_error(gettext("Invalid user: %s"), user);
2276 } else {
2277 if ((pwd = getpwnam(user)) == NULL) {
2278 exit_error(gettext("Invalid user: %s"), user);
2282 return (pwd->pw_uid);
2286 * get_arg_ent()
2287 * Inputs: command line argument string
2288 * Returns ptr to struct arg_entry if found; null, if not found
2290 static arg_entry_t *
2291 get_arg_ent(char *arg_str)
2293 arg_entry_t key;
2295 key.arg_str = arg_str;
2297 return ((arg_entry_t *)bsearch((char *)&key, (char *)arg_table,
2298 ARG_TBL_SZ, sizeof (arg_entry_t), arg_ent_compare));
2302 * arg_ent_compare()
2303 * Compares two command line arguments to determine which is
2304 * lexicographically greater.
2305 * Inputs: two argument map table entry pointers
2306 * Returns: > 1: aep1->arg_str > aep2->arg_str
2307 * < 1: aep1->arg_str < aep2->arg_str
2308 * 0: aep1->arg_str = aep->arg_str2
2310 static int
2311 arg_ent_compare(const void *aep1, const void *aep2)
2313 return (strcmp(((arg_entry_t *)aep1)->arg_str,
2314 ((arg_entry_t *)aep2)->arg_str));
2318 * tid_str is major,minor,host -- host is a name or an ip address
2320 static void
2321 str2tid(char *tid_str, au_tid_addr_t *tp)
2323 char *major_str;
2324 char *minor_str;
2325 char *host_str = NULL;
2326 major_t major = 0;
2327 major_t minor = 0;
2328 dev_t dev = 0;
2329 struct hostent *phe;
2330 int err;
2331 uint32_t ibuf;
2332 uint32_t ibuf6[4];
2334 tp->at_port = 0;
2335 tp->at_type = 0;
2336 bzero(tp->at_addr, 16);
2338 major_str = tid_str;
2339 if ((minor_str = strchr(tid_str, ',')) != NULL) {
2340 *minor_str = '\0';
2341 minor_str++;
2344 if (minor_str) {
2345 if ((host_str = strchr(minor_str, ',')) != NULL) {
2346 *host_str = '\0';
2347 host_str++;
2351 if (major_str)
2352 major = (major_t)atoi(major_str);
2354 if (minor_str)
2355 minor = (minor_t)atoi(minor_str);
2357 if ((dev = makedev(major, minor)) != NODEV)
2358 tp->at_port = dev;
2360 if (host_str) {
2361 if (strisipaddr(host_str)) {
2362 if (inet_pton(AF_INET, host_str, &ibuf)) {
2363 tp->at_addr[0] = ibuf;
2364 tp->at_type = AU_IPv4;
2365 } else if (inet_pton(AF_INET6, host_str, ibuf6)) {
2366 tp->at_addr[0] = ibuf6[0];
2367 tp->at_addr[1] = ibuf6[1];
2368 tp->at_addr[2] = ibuf6[2];
2369 tp->at_addr[3] = ibuf6[3];
2370 tp->at_type = AU_IPv6;
2372 } else {
2373 phe = getipnodebyname((const void *)host_str,
2374 AF_INET, 0, &err);
2375 if (phe == 0) {
2376 phe = getipnodebyname((const void *)host_str,
2377 AF_INET6, 0, &err);
2380 if (phe != NULL) {
2381 if (phe->h_addrtype == AF_INET6) {
2382 /* address is IPv6 (128 bits) */
2383 (void) memcpy(&tp->at_addr[0],
2384 phe->h_addr_list[0], 16);
2385 tp->at_type = AU_IPv6;
2386 } else {
2387 /* address is IPv4 (32 bits) */
2388 (void) memcpy(&tp->at_addr[0],
2389 phe->h_addr_list[0], 4);
2390 tp->at_type = AU_IPv4;
2392 freehostent(phe);
2398 static char *
2399 cond2str(void)
2401 uint_t cond;
2403 eauditon(A_GETCOND, (caddr_t)&cond, sizeof (cond));
2405 switch (cond) {
2407 case AUC_AUDITING:
2408 return ("auditing");
2410 case AUC_NOAUDIT:
2411 case AUC_INIT_AUDIT:
2412 return ("noaudit");
2414 case AUC_UNSET:
2415 return ("unset");
2417 case AUC_NOSPACE:
2418 return ("nospace");
2420 default:
2421 return ("");
2426 * exit = 0, success
2427 * 1, error
2428 * 2, bad zone
2430 static int
2431 str2policy(char *policy_str, uint32_t *policy_mask)
2433 char *buf;
2434 char *tok;
2435 char pfix;
2436 boolean_t is_all = B_FALSE;
2437 uint32_t pm = 0;
2438 uint32_t curp;
2440 pfix = *policy_str;
2442 if (pfix == '-' || pfix == '+' || pfix == '=')
2443 ++policy_str;
2445 if ((buf = strdup(policy_str)) == NULL)
2446 return (1);
2448 for (tok = strtok(buf, ","); tok != NULL; tok = strtok(NULL, ",")) {
2449 uint32_t tok_pm;
2450 if (((tok_pm = get_policy(tok)) == 0) &&
2451 ((strcasecmp(tok, "none") != 0))) {
2452 free(buf);
2453 return (1);
2454 } else {
2455 pm |= tok_pm;
2456 if (tok_pm == ALL_POLICIES) {
2457 is_all = B_TRUE;
2461 free(buf);
2463 /* reuse policy mask if already set to some value */
2464 if (*policy_mask != 0) {
2465 curp = *policy_mask;
2466 } else {
2467 (void) auditon(A_GETPOLICY, (caddr_t)&curp, 0);
2470 if (pfix == '-') {
2471 if (!is_all &&
2472 (getzoneid() != GLOBAL_ZONEID) &&
2473 (pm & ~AUDIT_LOCAL)) {
2474 return (2);
2477 if (getzoneid() != GLOBAL_ZONEID)
2478 curp &= AUDIT_LOCAL;
2479 *policy_mask = curp & ~pm;
2481 } else if (pfix == '+') {
2483 * In a local zone, accept specifying "all", but not
2484 * individually specifying global-zone only policies.
2485 * Limit to all locally allowed, so system call doesn't
2486 * fail.
2488 if (!is_all &&
2489 (getzoneid() != GLOBAL_ZONEID) &&
2490 (pm & ~AUDIT_LOCAL)) {
2491 return (2);
2494 if (getzoneid() != GLOBAL_ZONEID) {
2495 curp &= AUDIT_LOCAL;
2496 if (is_all) {
2497 pm &= AUDIT_LOCAL;
2500 *policy_mask = curp | pm;
2502 } else {
2504 * In a local zone, accept specifying "all", but not
2505 * individually specifying global-zone only policies.
2506 * Limit to all locally allowed, so system call doesn't
2507 * fail.
2509 if (!is_all &&
2510 (getzoneid() != GLOBAL_ZONEID) &&
2511 (pm & ~AUDIT_LOCAL)) {
2512 return (2);
2515 if (is_all && (getzoneid() != GLOBAL_ZONEID)) {
2516 pm &= AUDIT_LOCAL;
2518 *policy_mask = pm;
2520 return (0);
2523 static int
2524 policy2str(uint32_t policy, char *policy_str, size_t len)
2526 int i, j;
2528 if (policy == ALL_POLICIES) {
2529 (void) strcpy(policy_str, "all");
2530 return (1);
2533 if (policy == NO_POLICIES) {
2534 (void) strcpy(policy_str, "none");
2535 return (1);
2538 *policy_str = '\0';
2540 for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) {
2541 if (policy & policy_table[i].policy_mask &&
2542 policy_table[i].policy_mask != ALL_POLICIES) {
2543 if (j++) {
2544 (void) strcat(policy_str, ",");
2546 (void) strlcat(policy_str, policy_table[i].policy_str,
2547 len);
2551 if (*policy_str)
2552 return (0);
2554 return (1);
2558 static int
2559 strisnum(char *s)
2561 if (s == NULL || !*s)
2562 return (0);
2564 for (; *s == '-' || *s == '+'; s++)
2566 if (!*s)
2567 return (0);
2569 for (; *s; s++)
2570 if (!isdigit(*s))
2571 return (0);
2573 return (1);
2576 static int
2577 strisipaddr(char *s)
2579 int dot = 0;
2580 int colon = 0;
2582 /* no string */
2583 if ((s == NULL) || (!*s))
2584 return (0);
2586 for (; *s; s++) {
2587 if (!(isxdigit(*s) || *s != '.' || *s != ':'))
2588 return (0);
2589 if (*s == '.')
2590 dot++;
2591 if (*s == ':')
2592 colon++;
2595 if (dot && colon)
2596 return (0);
2598 if (!dot && !colon)
2599 return (0);
2601 return (1);
2604 static void
2605 chk_arg_len(char *argv, uint_t len)
2607 if ((strlen(argv) + 1) > len) {
2608 *(argv + len - 1) = '\0';
2609 exit_error(gettext("Argument too long (%s..)."), argv);
2613 static void
2614 chk_event_num(int etype, au_event_t event)
2616 au_stat_t as;
2618 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2620 if (etype == AC_KERN_EVENT) {
2621 if (event > as.as_numevent) {
2622 exit_error(gettext(
2623 "Invalid kernel audit event number specified.\n"
2624 "\t%hu is outside allowable range 0-%d."),
2625 event, as.as_numevent);
2627 } else {
2628 /* user event */
2629 if (event <= as.as_numevent) {
2630 exit_error(gettext("Invalid user level audit event "
2631 "number specified %hu."), event);
2636 static void
2637 chk_event_str(int etype, char *event_str)
2639 au_event_ent_t *evp;
2640 au_stat_t as;
2642 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2644 evp = egetauevnam(event_str);
2645 if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) {
2646 exit_error(gettext(
2647 "Invalid kernel audit event string specified.\n"
2648 "\t\"%s\" appears to be a user level event. "
2649 "Check configuration."), event_str);
2650 } else if (etype == AC_USER_EVENT &&
2651 (evp->ae_number < as.as_numevent)) {
2652 exit_error(gettext(
2653 "Invalid user audit event string specified.\n"
2654 "\t\"%s\" appears to be a kernel event. "
2655 "Check configuration."), event_str);
2659 static void
2660 chk_known_plugin(char *plugin_str)
2662 if ((strlen(plugin_str) + 1) > PLUGIN_MAXBUF) {
2663 exit_error(gettext("Plugin name too long.\n"));
2666 if (!plugin_avail_scf(plugin_str)) {
2667 exit_error(gettext("No such plugin configured: %s"),
2668 plugin_str);
2672 static void
2673 chk_sorf(char *sorf_str)
2675 if (!strisnum(sorf_str))
2676 exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
2679 static void
2680 chk_retval(char *retval_str)
2682 if (!strisnum(retval_str))
2683 exit_error(gettext("Invalid retval specified: %s"), retval_str);
2686 static void
2687 execit(char **argv)
2689 char *args, *args_pos;
2690 size_t len = 0;
2691 size_t n = 0;
2692 char **argv_pos;
2694 if (*argv) {
2695 /* concatenate argument array to be passed to sh -c "..." */
2696 for (argv_pos = argv; *argv_pos; argv_pos++)
2697 len += strlen(*argv_pos) + 1;
2699 if ((args = malloc(len + 1)) == NULL)
2700 exit_error(
2701 gettext("Allocation for command/arguments failed"));
2703 args_pos = args;
2704 for (argv_pos = argv; *argv_pos; argv_pos++) {
2705 n += snprintf(args_pos, len - n, "%s ", *argv_pos);
2706 args_pos = args + n;
2708 /* strip the last space */
2709 args[strlen(args)] = '\0';
2711 (void) execl("/bin/sh", "sh", "-c", args, NULL);
2712 } else {
2713 (void) execl("/bin/sh", "sh", NULL);
2716 exit_error(gettext("exec(2) failed"));
2719 static void
2720 exit_usage(int status)
2722 FILE *fp;
2723 int i;
2725 fp = (status ? stderr : stdout);
2726 (void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
2728 for (i = 0; i < ARG_TBL_SZ; i++) {
2729 /* skip the -t option; it's not a standalone option */
2730 if (arg_table[i].auditconfig_cmd == AC_ARG_SET_TEMPORARY) {
2731 continue;
2734 (void) fprintf(fp, " %s%s%s\n",
2735 arg_table[i].arg_str, arg_table[i].arg_opts,
2736 (arg_table[i].temporary_allowed ? " [-t]" : ""));
2739 exit(status);
2742 static void
2743 print_asid(au_asid_t asid)
2745 (void) printf(gettext("audit session id = %u\n"), asid);
2748 static void
2749 print_auid(au_id_t auid)
2751 struct passwd *pwd;
2752 char *username;
2754 if ((pwd = getpwuid((uid_t)auid)) != NULL)
2755 username = pwd->pw_name;
2756 else
2757 username = gettext("unknown");
2759 (void) printf(gettext("audit id = %s(%d)\n"), username, auid);
2762 static void
2763 print_mask(char *desc, au_mask_t *pmp)
2765 char auflags[512];
2767 if (getauditflagschar(auflags, pmp, 0) < 0)
2768 (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
2770 (void) printf("%s = %s(0x%x,0x%x)\n",
2771 desc, auflags, pmp->am_success, pmp->am_failure);
2774 static void
2775 print_plugin(char *plugin_name, kva_t *plugin_kva)
2777 char att_str[PLUGIN_MAXATT];
2778 boolean_t plugin_active;
2779 char *active_str;
2780 char *qsize_ptr;
2781 int qsize;
2783 if ((active_str = kva_match(plugin_kva, "active")) == NULL) {
2784 (void) printf(gettext("Audit service configuration error: "
2785 "\"active\" property not found\n"));
2786 return;
2789 plugin_active = (boolean_t)atoi(active_str);
2790 qsize_ptr = kva_match(plugin_kva, "qsize");
2791 qsize = atoi(qsize_ptr == NULL ? "-1" : qsize_ptr);
2793 (void) printf(gettext("Plugin: %s (%s)\n"), plugin_name,
2794 plugin_active ? "active" : "inactive");
2796 free_static_att_kva(plugin_kva);
2798 switch (_kva2str(plugin_kva, att_str, PLUGIN_MAXATT, "=", ";")) {
2799 case 0:
2800 (void) printf(gettext("\tAttributes: %s\n"), att_str);
2801 break;
2802 case 1:
2803 exit_error(gettext("Internal error - buffer size too small."));
2804 break;
2805 default:
2806 exit_error(gettext("Internal error."));
2807 break;
2810 if (qsize != 0) {
2811 (void) printf(gettext("\tQueue size: %d %s\n"), qsize,
2812 qsize == -1 ? "(internal error: value not available)" : "");
2816 static void
2817 print_tid_ex(au_tid_addr_t *tidp)
2819 struct hostent *phe;
2820 char *hostname;
2821 struct in_addr ia;
2822 uint32_t *addr;
2823 int err;
2824 char buf[INET6_ADDRSTRLEN];
2825 char *bufp;
2828 /* IPV6 or IPV4 address */
2829 if (tidp->at_type == AU_IPv4) {
2830 if ((phe = gethostbyaddr((char *)&tidp->at_addr[0],
2831 sizeof (tidp->at_addr[0]), AF_INET)) != NULL) {
2832 hostname = phe->h_name;
2833 } else {
2834 hostname = gettext("unknown");
2837 ia.s_addr = tidp->at_addr[0];
2839 (void) printf(gettext(
2840 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2841 major(tidp->at_port), minor(tidp->at_port),
2842 hostname, inet_ntoa(ia));
2843 } else {
2844 addr = &tidp->at_addr[0];
2845 phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
2847 bzero(buf, sizeof (buf));
2849 (void) inet_ntop(AF_INET6, (void *)addr, buf, sizeof (buf));
2850 if (phe == NULL) {
2851 bufp = gettext("unknown");
2852 } else {
2853 bufp = phe->h_name;
2856 (void) printf(gettext(
2857 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2858 major(tidp->at_port), minor(tidp->at_port),
2859 bufp, buf);
2860 if (phe) {
2861 freehostent(phe);
2866 static int
2867 str2ipaddr(char *s, uint32_t *addr, uint32_t type)
2869 int j, sl;
2870 char *ss;
2871 unsigned int v;
2873 bzero(addr, 16);
2874 if (strisipaddr(s)) {
2875 if (type == AU_IPv4) {
2876 if (inet_pton(AF_INET, s, addr)) {
2877 return (0);
2879 return (1);
2880 } else if (type == AU_IPv6) {
2881 if (inet_pton(AF_INET6, s, addr))
2882 return (0);
2883 return (1);
2885 return (1);
2886 } else {
2887 if (type == AU_IPv4) {
2888 (void) sscanf(s, "%x", &addr[0]);
2889 return (0);
2890 } else if (type == AU_IPv6) {
2891 sl = strlen(s);
2892 ss = s;
2893 for (j = 3; j >= 0; j--) {
2894 if ((sl - 8) <= 0) {
2895 (void) sscanf(s, "%x", &v);
2896 addr[j] = v;
2897 return (0);
2899 ss = &s[sl-8];
2900 (void) sscanf(ss, "%x", &v);
2901 addr[j] = v;
2902 sl -= 8;
2903 *ss = '\0';
2906 return (0);
2910 static int
2911 str2type(char *s, uint_t *type)
2913 if (strcmp(s, "ipv6") == 0) {
2914 *type = AU_IPv6;
2915 return (0);
2917 if (strcmp(s, "ipv4") == 0) {
2918 *type = AU_IPv4;
2919 return (0);
2922 return (1);
2926 * exit_error() - print an error message along with corresponding system error
2927 * number and error message, then exit. Inputs - program error format and
2928 * message.
2930 /*PRINTFLIKE1*/
2931 static void
2932 exit_error(char *fmt, ...)
2934 va_list args;
2936 va_start(args, fmt);
2937 prt_error_va(fmt, args);
2938 va_end(args);
2940 exit(1);