6416 ptime -p could support multiple processes
[unleashed.git] / usr / src / cmd / auditconfig / auditconfig.c
blobf82a22d4d1b0e4b77ed0f0ea24cd208467531934
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 <tsol/label.h>
53 #include <bsm/libbsm.h>
54 #include <audit_policy.h>
55 #include <audit_scf.h>
57 enum commands {
58 AC_ARG_ACONF,
59 AC_ARG_AUDIT,
60 AC_ARG_CHKACONF,
61 AC_ARG_CHKCONF,
62 AC_ARG_CONF,
63 AC_ARG_GETASID,
64 AC_ARG_GETAUDIT,
65 AC_ARG_GETAUID,
66 AC_ARG_GETCAR,
67 AC_ARG_GETCLASS,
68 AC_ARG_GETCOND,
69 AC_ARG_GETCWD,
70 AC_ARG_GETESTATE,
71 AC_ARG_GETFLAGS,
72 AC_ARG_GETKAUDIT,
73 AC_ARG_GETKMASK,
74 AC_ARG_GETNAFLAGS,
75 AC_ARG_GETPINFO,
76 AC_ARG_GETPLUGIN,
77 AC_ARG_GETPOLICY,
78 AC_ARG_GETQBUFSZ,
79 AC_ARG_GETQCTRL,
80 AC_ARG_GETQDELAY,
81 AC_ARG_GETQHIWATER,
82 AC_ARG_GETQLOWATER,
83 AC_ARG_GETSTAT,
84 AC_ARG_GETTERMID,
85 AC_ARG_LSEVENT,
86 AC_ARG_LSPOLICY,
87 AC_ARG_SETASID,
88 AC_ARG_SETAUDIT,
89 AC_ARG_SETAUID,
90 AC_ARG_SETCLASS,
91 AC_ARG_SETFLAGS,
92 AC_ARG_SETKAUDIT,
93 AC_ARG_SETKMASK,
94 AC_ARG_SETNAFLAGS,
95 AC_ARG_SETPLUGIN,
96 AC_ARG_SETPMASK,
97 AC_ARG_SETPOLICY,
98 AC_ARG_SETQBUFSZ,
99 AC_ARG_SETQCTRL,
100 AC_ARG_SETQDELAY,
101 AC_ARG_SETQHIWATER,
102 AC_ARG_SETQLOWATER,
103 AC_ARG_SETSMASK,
104 AC_ARG_SETSTAT,
105 AC_ARG_SETUMASK,
106 AC_ARG_SET_TEMPORARY
109 #define AC_KERN_EVENT 0
110 #define AC_USER_EVENT 1
112 #define NONE(s) (!strlen(s) ? gettext("none") : s)
114 #define ONEK 1024
117 * remove this after the audit.h is fixed
119 struct arg_entry {
120 char *arg_str;
121 char *arg_opts;
122 enum commands auditconfig_cmd;
123 boolean_t temporary_allowed; /* -t allowed for the option */
125 typedef struct arg_entry arg_entry_t;
127 /* arg_table - command option and usage message table */
128 static arg_entry_t arg_table[] = {
129 { "-aconf", "", AC_ARG_ACONF, B_FALSE},
130 { "-audit", " event sorf retval string", AC_ARG_AUDIT, B_FALSE},
131 { "-chkaconf", "", AC_ARG_CHKACONF, B_FALSE},
132 { "-chkconf", "", AC_ARG_CHKCONF, B_FALSE},
133 { "-conf", "", AC_ARG_CONF, B_FALSE},
134 { "-getasid", "", AC_ARG_GETASID, B_FALSE},
135 { "-getaudit", "", AC_ARG_GETAUDIT, B_FALSE},
136 { "-getauid", "", AC_ARG_GETAUID, B_FALSE},
137 { "-getcar", "", AC_ARG_GETCAR, B_FALSE},
138 { "-getclass", " event", AC_ARG_GETCLASS, B_FALSE},
139 { "-getcond", "", AC_ARG_GETCOND, B_FALSE},
140 { "-getcwd", "", AC_ARG_GETCWD, B_FALSE},
141 { "-getestate", " event", AC_ARG_GETESTATE, B_FALSE},
142 { "-getflags", "", AC_ARG_GETFLAGS, B_FALSE},
143 { "-getkaudit", "", AC_ARG_GETKAUDIT, B_FALSE},
144 { "-getkmask", "", AC_ARG_GETKMASK, B_FALSE},
145 { "-getnaflags", "", AC_ARG_GETNAFLAGS, B_FALSE},
146 { "-getpinfo", " pid", AC_ARG_GETPINFO, B_FALSE},
147 { "-getplugin", " [plugin]", AC_ARG_GETPLUGIN, B_FALSE},
148 { "-getpolicy", "", AC_ARG_GETPOLICY, B_TRUE},
149 { "-getqbufsz", "", AC_ARG_GETQBUFSZ, B_TRUE},
150 { "-getqctrl", "", AC_ARG_GETQCTRL, B_TRUE},
151 { "-getqdelay", "", AC_ARG_GETQDELAY, B_TRUE},
152 { "-getqhiwater", "", AC_ARG_GETQHIWATER, B_TRUE},
153 { "-getqlowater", "", AC_ARG_GETQLOWATER, B_TRUE},
154 { "-getstat", "", AC_ARG_GETSTAT, B_FALSE},
155 { "-gettid", "", AC_ARG_GETTERMID, B_FALSE},
156 { "-lsevent", "", AC_ARG_LSEVENT, B_FALSE},
157 { "-lspolicy", "", AC_ARG_LSPOLICY, B_FALSE},
158 { "-setasid", " asid [cmd]", AC_ARG_SETASID, B_FALSE},
159 { "-setaudit", " auid audit_flags termid asid [cmd]",
160 AC_ARG_SETAUDIT, B_FALSE},
161 { "-setauid", " auid [cmd]", AC_ARG_SETAUID, B_FALSE},
162 { "-setclass", " event audit_flags", AC_ARG_SETCLASS, B_FALSE},
163 { "-setflags", " audit_flags", AC_ARG_SETFLAGS, B_FALSE},
164 { "-setkaudit", " type IP_address", AC_ARG_SETKAUDIT, B_FALSE},
165 { "-setkmask", " audit_flags", AC_ARG_SETKMASK, B_FALSE},
166 { "-setnaflags", " audit_naflags", AC_ARG_SETNAFLAGS, B_FALSE},
167 { "-setplugin", " name active|inactive [attributes [qsize]]",
168 AC_ARG_SETPLUGIN, B_FALSE},
169 { "-setpmask", " pid audit_flags", AC_ARG_SETPMASK, B_FALSE},
170 { "-setpolicy", " [+|-]policy_flags", AC_ARG_SETPOLICY, B_TRUE},
171 { "-setqbufsz", " bufsz", AC_ARG_SETQBUFSZ, B_TRUE},
172 { "-setqctrl", " hiwater lowater bufsz delay",
173 AC_ARG_SETQCTRL, B_TRUE},
174 { "-setqdelay", " delay", AC_ARG_SETQDELAY, B_TRUE},
175 { "-setqhiwater", " hiwater", AC_ARG_SETQHIWATER, B_TRUE},
176 { "-setqlowater", " lowater", AC_ARG_SETQLOWATER, B_TRUE},
177 { "-setsmask", " asid audit_flags", AC_ARG_SETSMASK, B_FALSE},
178 { "-setstat", "", AC_ARG_SETSTAT, B_FALSE},
179 { "-setumask", " user audit_flags", AC_ARG_SETUMASK, B_FALSE},
180 { "-t", "", AC_ARG_SET_TEMPORARY, B_FALSE},
183 #define ARG_TBL_SZ (sizeof (arg_table) / sizeof (arg_entry_t))
185 char *progname = "auditconfig";
188 * temporary_set true to get/set only kernel settings,
189 * false to get/set kernel settings and service properties
191 static boolean_t temporary_set = B_FALSE;
193 static au_event_ent_t *egetauevnam(char *event_name);
194 static au_event_ent_t *egetauevnum(au_event_t event_number);
195 static int arg_ent_compare(const void *aep1, const void *aep2);
196 static char *cond2str(void);
197 static int policy2str(uint32_t policy, char *policy_str, size_t len);
198 static int str2type(char *s, uint_t *type);
199 static int str2policy(char *policy_str, uint32_t *policy_mask);
200 static int str2ipaddr(char *s, uint32_t *addr, uint32_t type);
201 static int strisipaddr(char *s);
202 static int strisnum(char *s);
203 static arg_entry_t *get_arg_ent(char *arg_str);
204 static uid_t get_user_id(char *user);
205 static void chk_arg_len(char *argv, uint_t len);
206 static void chk_event_num(int etype, au_event_t event);
207 static void chk_event_str(int etype, char *event_str);
208 static void chk_known_plugin(char *plugin_str);
209 static void chk_retval(char *retval_str);
210 static void chk_sorf(char *sorf_str);
211 static void do_aconf(void);
212 static void do_args(char **argv, au_mask_t *mask);
213 static void do_audit(char *, char, int, char *);
214 static void do_chkaconf(void);
215 static void do_chkconf(void);
216 static void do_conf(void);
217 static void do_getasid(void);
218 static void do_getaudit(void);
219 static void do_getkaudit(void);
220 static void do_setkaudit(char *t, char *s);
221 static void do_getauid(void);
222 static void do_getcar(void);
223 static void do_getclass(char *event_str);
224 static void do_getcond(void);
225 static void do_getcwd(void);
226 static void do_getflags(void);
227 static void do_getkmask(void);
228 static void do_getnaflags(void);
229 static void do_getpinfo(char *pid_str);
230 static void do_getplugin(char *plugin_str);
231 static void do_getpolicy(void);
232 static void do_getqbufsz(void);
233 static void do_getqctrl(void);
234 static void do_getqdelay(void);
235 static void do_getqhiwater(void);
236 static void do_getqlowater(void);
237 static void do_getstat(void);
238 static void do_gettermid(void);
239 static void do_lsevent(void);
240 static void do_lspolicy(void);
241 static void do_setasid(char *sid_str, char **argv);
242 static void do_setaudit(char *user_str, char *mask_str, char *tid_str,
243 char *sid_str, char **argv);
244 static void do_setauid(char *user, char **argv);
245 static void do_setclass(char *event_str, au_mask_t *mask);
246 static void do_setflags(char *audit_flags, au_mask_t *amask);
247 static void do_setkmask(au_mask_t *pmask);
248 static void do_setnaflags(char *audit_naflags, au_mask_t *namask);
249 static void do_setpmask(char *pid_str, au_mask_t *mask);
250 static void do_setsmask(char *asid_str, au_mask_t *mask);
251 static void do_setumask(char *auid_str, au_mask_t *mask);
252 static void do_setplugin(char *plugin_str, boolean_t plugin_state,
253 char *plugin_attr, int plugin_qsize);
254 static void do_setpolicy(char *policy_str);
255 static void do_setqbufsz(char *bufsz);
256 static void do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay);
257 static void do_setqdelay(char *delay);
258 static void do_setqhiwater(char *hiwater);
259 static void do_setqlowater(char *lowater);
260 static void do_setstat(void);
261 static void str2tid(char *tid_str, au_tid_addr_t *tp);
263 static void eauditon(int cmd, caddr_t data, int length);
264 static void echkflags(char *auditflags, au_mask_t *mask);
265 static void egetaudit(auditinfo_addr_t *ai, int size);
266 static void egetauditflagsbin(char *auditflags, au_mask_t *pmask);
267 static void egetauid(au_id_t *auid);
268 static void egetkaudit(auditinfo_addr_t *ai, int size);
269 static void esetaudit(auditinfo_addr_t *ai, int size);
270 static void esetauid(au_id_t *auid);
271 static void esetkaudit(auditinfo_addr_t *ai, int size);
272 static void execit(char **argv);
273 static void exit_error(char *fmt, ...);
274 static void exit_usage(int status);
275 static void parse_args(int argc, char **argv, au_mask_t *mask);
276 static void print_asid(au_asid_t asid);
277 static void print_auid(au_id_t auid);
278 static void print_mask(char *desc, au_mask_t *pmp);
279 static void print_plugin(char *plugin_name, kva_t *plugin_kva);
280 static void print_tid_ex(au_tid_addr_t *tidp);
282 #if !defined(TEXT_DOMAIN)
283 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
284 #endif
287 main(int argc, char **argv)
289 au_mask_t mask; /* for options manipulating flags */
291 (void) setlocale(LC_ALL, "");
292 (void) textdomain(TEXT_DOMAIN);
294 if (argc == 1) {
295 exit_usage(0);
298 if (argc == 2 &&
299 (argv[1][0] == '?' ||
300 strcmp(argv[1], "-h") == 0 ||
301 strcmp(argv[1], "-?") == 0)) {
302 exit_usage(0);
305 parse_args(argc, argv, &mask);
306 do_args(argv, &mask);
308 return (0);
312 * parse_args()
313 * Desc: Checks command line argument syntax.
314 * Inputs: Command line argv;
315 * Returns: If a syntax error is detected, a usage message is printed
316 * and exit() is called. If a syntax error is not detected,
317 * parse_args() returns without a value.
319 static void
320 parse_args(int argc, char **argv, au_mask_t *mask)
322 arg_entry_t *ae;
324 uint_t type;
325 uint_t addr[4];
327 for (++argv; *argv; argv++) {
328 if ((ae = get_arg_ent(*argv)) == NULL) {
329 exit_usage(1);
332 switch (ae->auditconfig_cmd) {
334 case AC_ARG_AUDIT:
335 ++argv;
336 if (!*argv)
337 exit_usage(1);
338 if (strisnum(*argv)) {
339 chk_event_num(AC_USER_EVENT,
340 (au_event_t)atol(*argv));
341 } else {
342 chk_event_str(AC_USER_EVENT, *argv);
344 ++argv;
345 if (!*argv)
346 exit_usage(1);
347 chk_sorf(*argv);
348 ++argv;
349 if (!*argv)
350 exit_usage(1);
351 chk_retval(*argv);
352 ++argv;
353 if (!*argv)
354 exit_usage(1);
355 break;
357 case AC_ARG_CHKCONF:
358 case AC_ARG_CONF:
359 case AC_ARG_ACONF:
360 case AC_ARG_CHKACONF:
361 case AC_ARG_GETASID:
362 case AC_ARG_GETAUID:
363 case AC_ARG_GETAUDIT:
364 case AC_ARG_GETKAUDIT:
365 break;
367 case AC_ARG_GETCLASS:
368 case AC_ARG_GETESTATE:
369 ++argv;
370 if (!*argv)
371 exit_usage(1);
372 if (strisnum(*argv)) {
373 chk_event_num(AC_KERN_EVENT,
374 (au_event_t)atol(*argv));
375 } else {
376 chk_event_str(AC_KERN_EVENT, *argv);
378 break;
380 case AC_ARG_GETCAR:
381 case AC_ARG_GETCOND:
382 case AC_ARG_GETCWD:
383 case AC_ARG_GETFLAGS:
384 case AC_ARG_GETKMASK:
385 case AC_ARG_GETNAFLAGS:
386 break;
388 case AC_ARG_GETPLUGIN:
389 if (*++argv == NULL) {
390 --argv;
391 break;
393 if (get_arg_ent(*argv) != NULL) {
394 --argv;
395 } else {
396 chk_arg_len(*argv, PLUGIN_MAXBUF);
397 chk_known_plugin(*argv);
399 break;
401 case AC_ARG_GETPOLICY:
402 case AC_ARG_GETQBUFSZ:
403 case AC_ARG_GETQCTRL:
404 case AC_ARG_GETQDELAY:
405 case AC_ARG_GETQHIWATER:
406 case AC_ARG_GETQLOWATER:
407 case AC_ARG_GETSTAT:
408 case AC_ARG_GETTERMID:
409 case AC_ARG_LSEVENT:
410 case AC_ARG_LSPOLICY:
411 break;
413 case AC_ARG_SETASID:
414 case AC_ARG_SETAUID:
415 case AC_ARG_SETAUDIT:
416 ++argv;
417 if (!*argv)
418 exit_usage(1);
420 while (*argv)
421 ++argv;
422 --argv;
424 break;
426 case AC_ARG_SETKAUDIT:
427 ++argv;
428 if (!*argv)
429 exit_usage(1);
430 if (str2type (*argv, &type))
431 exit_error(gettext(
432 "Invalid IP address type specified."));
433 ++argv;
434 if (!*argv)
435 exit_usage(1);
437 if (str2ipaddr(*argv, addr, type))
438 exit_error(
439 gettext("Invalid IP address specified."));
440 break;
442 case AC_ARG_SETCLASS:
443 ++argv;
444 if (!*argv)
445 exit_usage(1);
446 if (strisnum(*argv))
447 chk_event_num(AC_KERN_EVENT,
448 (au_event_t)atol(*argv));
449 else
450 chk_event_str(AC_KERN_EVENT, *argv);
451 ++argv;
452 if (!*argv)
453 exit_usage(1);
454 echkflags(*argv, mask);
455 break;
457 case AC_ARG_SETFLAGS:
458 ++argv;
459 if (!*argv)
460 exit_usage(1);
461 chk_arg_len(*argv, PRESELECTION_MAXBUF);
462 echkflags(*argv, mask);
463 break;
465 case AC_ARG_SETKMASK:
466 ++argv;
467 if (!*argv)
468 exit_usage(1);
469 echkflags(*argv, mask);
470 break;
472 case AC_ARG_SETNAFLAGS:
473 ++argv;
474 if (!*argv)
475 exit_usage(1);
476 chk_arg_len(*argv, PRESELECTION_MAXBUF);
477 echkflags(*argv, mask);
478 break;
480 case AC_ARG_SETPLUGIN:
481 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
482 exit_usage(1);
484 chk_known_plugin(*argv);
485 chk_arg_len(*argv, PLUGIN_MAXBUF);
486 if (*++argv == NULL || strcmp(*argv, "active") != 0 &&
487 strcmp(*argv, "inactive") != 0) {
488 exit_usage(1);
490 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
491 --argv;
492 break;
494 chk_arg_len(*argv, PLUGIN_MAXATT);
495 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
496 --argv;
497 break;
499 if (atoi(*argv) < 0) {
500 exit_error(gettext("Incorrect qsize specified "
501 "(%s)."), *argv);
503 break;
505 case AC_ARG_SETPOLICY:
506 ++argv;
507 if (!*argv)
508 exit_usage(1);
509 break;
511 case AC_ARG_SETSTAT:
512 break;
514 case AC_ARG_GETPINFO:
515 ++argv;
516 if (!*argv)
517 exit_usage(1);
518 break;
520 case AC_ARG_SETPMASK:
521 ++argv;
522 if (!*argv)
523 exit_usage(1);
524 ++argv;
525 if (!*argv)
526 exit_usage(1);
527 echkflags(*argv, mask);
528 break;
530 case AC_ARG_SETQBUFSZ:
531 ++argv;
532 if (!*argv)
533 exit_usage(1);
534 if (!strisnum(*argv))
535 exit_error(gettext("Invalid bufsz specified."));
536 break;
538 case AC_ARG_SETQCTRL:
539 ++argv;
540 if (!*argv)
541 exit_usage(1);
542 if (!strisnum(*argv))
543 exit_error(
544 gettext("Invalid hiwater specified."));
545 ++argv;
546 if (!*argv)
547 exit_usage(1);
548 if (!strisnum(*argv))
549 exit_error(
550 gettext("Invalid lowater specified."));
551 ++argv;
552 if (!*argv)
553 exit_usage(1);
554 if (!strisnum(*argv))
555 exit_error(gettext("Invalid bufsz specified."));
556 ++argv;
557 if (!*argv)
558 exit_usage(1);
559 if (!strisnum(*argv))
560 exit_error(gettext("Invalid delay specified."));
561 break;
563 case AC_ARG_SETQDELAY:
564 ++argv;
565 if (!*argv)
566 exit_usage(1);
567 if (!strisnum(*argv))
568 exit_error(gettext("Invalid delay specified."));
569 break;
571 case AC_ARG_SETQHIWATER:
572 ++argv;
573 if (!*argv)
574 exit_usage(1);
575 if (!strisnum(*argv)) {
576 exit_error(
577 gettext("Invalid hiwater specified."));
579 break;
581 case AC_ARG_SETQLOWATER:
582 ++argv;
583 if (!*argv)
584 exit_usage(1);
585 if (!strisnum(*argv)) {
586 exit_error(
587 gettext("Invalid lowater specified."));
589 break;
591 case AC_ARG_SETSMASK:
592 case AC_ARG_SETUMASK:
593 ++argv;
594 if (!*argv)
595 exit_usage(1);
596 ++argv;
597 if (!*argv)
598 exit_usage(1);
599 echkflags(*argv, mask);
600 break;
602 case AC_ARG_SET_TEMPORARY:
603 /* Do not accept single -t option. */
604 if (argc == 2) {
605 exit_error(
606 gettext("Only the -t option specified "
607 "(it is not a standalone option)."));
609 temporary_set = B_TRUE;
610 break;
612 default:
613 exit_error(gettext("Internal error #1."));
614 break;
621 * do_args() - do command line arguments in the order in which they appear.
622 * Function return values returned by the underlying functions; the semantics
623 * they should follow is to return B_TRUE on successful execution, B_FALSE
624 * otherwise.
626 static void
627 do_args(char **argv, au_mask_t *mask)
629 arg_entry_t *ae;
631 for (++argv; *argv; argv++) {
632 ae = get_arg_ent(*argv);
634 switch (ae->auditconfig_cmd) {
636 case AC_ARG_AUDIT:
638 char sorf;
639 int retval;
640 char *event_name;
641 char *audit_str;
643 ++argv;
644 event_name = *argv;
645 ++argv;
646 sorf = (char)atoi(*argv);
647 ++argv;
648 retval = atoi(*argv);
649 ++argv;
650 audit_str = *argv;
651 do_audit(event_name, sorf, retval, audit_str);
653 break;
655 case AC_ARG_CHKCONF:
656 do_chkconf();
657 break;
659 case AC_ARG_CONF:
660 do_conf();
661 break;
663 case AC_ARG_CHKACONF:
664 do_chkaconf();
665 break;
667 case AC_ARG_ACONF:
668 do_aconf();
669 break;
671 case AC_ARG_GETASID:
672 do_getasid();
673 break;
675 case AC_ARG_GETAUID:
676 do_getauid();
677 break;
679 case AC_ARG_GETAUDIT:
680 do_getaudit();
681 break;
683 case AC_ARG_GETKAUDIT:
684 do_getkaudit();
685 break;
687 case AC_ARG_GETCLASS:
688 case AC_ARG_GETESTATE:
689 ++argv;
690 do_getclass(*argv);
691 break;
693 case AC_ARG_GETCAR:
694 do_getcar();
695 break;
697 case AC_ARG_GETCOND:
698 do_getcond();
699 break;
701 case AC_ARG_GETCWD:
702 do_getcwd();
703 break;
705 case AC_ARG_GETFLAGS:
706 do_getflags();
707 break;
709 case AC_ARG_GETKMASK:
710 do_getkmask();
711 break;
713 case AC_ARG_GETNAFLAGS:
714 do_getnaflags();
715 break;
717 case AC_ARG_GETPLUGIN:
719 char *plugin_str = NULL;
721 ++argv;
722 if (*argv != NULL) {
723 if (get_arg_ent(*argv) != NULL) {
724 --argv;
725 } else {
726 plugin_str = *argv;
728 } else {
729 --argv;
732 do_getplugin(plugin_str);
734 break;
736 case AC_ARG_GETPOLICY:
737 do_getpolicy();
738 break;
740 case AC_ARG_GETQBUFSZ:
741 do_getqbufsz();
742 break;
744 case AC_ARG_GETQCTRL:
745 do_getqctrl();
746 break;
748 case AC_ARG_GETQDELAY:
749 do_getqdelay();
750 break;
752 case AC_ARG_GETQHIWATER:
753 do_getqhiwater();
754 break;
756 case AC_ARG_GETQLOWATER:
757 do_getqlowater();
758 break;
760 case AC_ARG_GETSTAT:
761 do_getstat();
762 break;
764 case AC_ARG_GETTERMID:
765 do_gettermid();
766 break;
768 case AC_ARG_LSEVENT:
769 do_lsevent();
770 break;
772 case AC_ARG_LSPOLICY:
773 do_lspolicy();
774 break;
776 case AC_ARG_SETASID:
778 char *sid_str;
780 ++argv;
781 sid_str = *argv;
782 ++argv;
783 do_setasid(sid_str, argv);
785 break;
787 case AC_ARG_SETAUID:
789 char *user;
791 ++argv;
792 user = *argv;
793 ++argv;
794 do_setauid(user, argv);
796 break;
798 case AC_ARG_SETAUDIT:
800 char *user_str;
801 char *mask_str;
802 char *tid_str;
803 char *sid_str;
805 ++argv;
806 user_str = *argv;
807 ++argv;
808 mask_str = *argv;
809 ++argv;
810 tid_str = *argv;
811 ++argv;
812 sid_str = *argv;
813 ++argv;
814 do_setaudit(user_str, mask_str, tid_str,
815 sid_str, argv);
817 break;
819 case AC_ARG_SETKAUDIT:
821 char *address_type, *address;
823 ++argv; address_type = *argv;
824 ++argv; address = *argv;
825 do_setkaudit(address_type, address);
827 break;
829 case AC_ARG_SETCLASS:
831 char *event_str;
833 ++argv;
834 event_str = *argv;
835 do_setclass(event_str, mask);
837 ++argv;
839 break;
841 case AC_ARG_SETFLAGS:
842 ++argv;
843 do_setflags(*argv, mask);
844 break;
846 case AC_ARG_SETKMASK:
847 ++argv;
848 do_setkmask(mask);
849 break;
851 case AC_ARG_SETNAFLAGS:
852 ++argv;
853 do_setnaflags(*argv, mask);
854 break;
856 case AC_ARG_SETPLUGIN:
858 char *plugin_str = NULL;
859 boolean_t plugin_state = B_FALSE;
860 char *plugin_att = NULL;
861 int plugin_qsize = -1;
863 plugin_str = *++argv;
864 if (strcmp(*++argv, "active") == 0) {
865 plugin_state = B_TRUE;
867 if (*++argv != NULL &&
868 get_arg_ent(*argv) == NULL) {
869 plugin_att = *argv;
870 if (*++argv != NULL &&
871 get_arg_ent(*argv) == NULL) {
872 plugin_qsize = atoi(*argv);
873 } else {
874 --argv;
876 } else {
877 --argv;
880 do_setplugin(plugin_str, plugin_state,
881 plugin_att, plugin_qsize);
883 break;
885 case AC_ARG_SETPOLICY:
886 ++argv;
887 do_setpolicy(*argv);
888 break;
890 case AC_ARG_GETPINFO:
892 char *pid_str;
894 ++argv;
895 pid_str = *argv;
896 do_getpinfo(pid_str);
898 break;
900 case AC_ARG_SETPMASK:
902 char *pid_str;
904 ++argv;
905 pid_str = *argv;
906 do_setpmask(pid_str, mask);
908 ++argv;
910 break;
912 case AC_ARG_SETSTAT:
913 do_setstat();
914 break;
916 case AC_ARG_SETQBUFSZ:
917 ++argv;
918 do_setqbufsz(*argv);
919 break;
921 case AC_ARG_SETQCTRL:
923 char *hiwater, *lowater, *bufsz, *delay;
925 ++argv; hiwater = *argv;
926 ++argv; lowater = *argv;
927 ++argv; bufsz = *argv;
928 ++argv; delay = *argv;
929 do_setqctrl(hiwater, lowater, bufsz, delay);
931 break;
932 case AC_ARG_SETQDELAY:
933 ++argv;
934 do_setqdelay(*argv);
935 break;
937 case AC_ARG_SETQHIWATER:
938 ++argv;
939 do_setqhiwater(*argv);
940 break;
942 case AC_ARG_SETQLOWATER:
943 ++argv;
944 do_setqlowater(*argv);
945 break;
947 case AC_ARG_SETSMASK:
949 char *asid_str;
951 ++argv;
952 asid_str = *argv;
953 do_setsmask(asid_str, mask);
955 ++argv;
957 break;
958 case AC_ARG_SETUMASK:
960 char *auid_str;
962 ++argv;
963 auid_str = *argv;
964 do_setumask(auid_str, mask);
966 ++argv;
968 break;
969 case AC_ARG_SET_TEMPORARY:
970 break;
972 default:
973 exit_error(gettext("Internal error #2."));
974 break;
980 * do_chkconf() - the returned value is for the global zone unless AUDIT_PERZONE
981 * is set.
983 static void
984 do_chkconf(void)
986 register au_event_ent_t *evp;
987 au_mask_t pmask;
988 char conf_aflags[256];
989 char run_aflags[256];
990 au_stat_t as;
991 int class;
992 int len;
993 struct au_evclass_map cmap;
995 pmask.am_success = pmask.am_failure = 0;
996 eauditon(A_GETSTAT, (caddr_t)&as, 0);
998 setauevent();
999 if (getauevent() == NULL) {
1000 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1001 AUDITEVENTFILE);
1004 setauevent();
1005 while ((evp = getauevent()) != NULL) {
1006 cmap.ec_number = evp->ae_number;
1007 len = sizeof (struct au_evclass_map);
1008 if (evp->ae_number <= as.as_numevent) {
1009 if (auditon(A_GETCLASS, (caddr_t)&cmap, len) == -1) {
1010 (void) printf("%s(%hu):%s",
1011 evp->ae_name, evp->ae_number,
1012 gettext("UNKNOWN EVENT: Could not get "
1013 "class for event. Configuration may "
1014 "be bad.\n"));
1015 } else {
1016 class = cmap.ec_class;
1017 if (class != evp->ae_class) {
1018 conf_aflags[0] = run_aflags[0] = '\0';
1019 pmask.am_success = class;
1020 pmask.am_failure = class;
1021 (void) getauditflagschar(run_aflags,
1022 &pmask, 0);
1023 pmask.am_success = evp->ae_class;
1024 pmask.am_failure = evp->ae_class;
1025 (void) getauditflagschar(conf_aflags,
1026 &pmask, 0);
1028 (void) printf(gettext(
1029 "%s(%hu): CLASS MISMATCH: "
1030 "runtime class (%s) != "
1031 "configured class (%s)\n"),
1032 evp->ae_name, evp->ae_number,
1033 NONE(run_aflags),
1034 NONE(conf_aflags));
1039 endauevent();
1043 * do_conf() - configure the kernel events. The value returned to the user is
1044 * for the global zone unless AUDIT_PERZONE is set.
1046 static void
1047 do_conf(void)
1049 register au_event_ent_t *evp;
1050 register int i;
1051 au_evclass_map_t ec;
1052 au_stat_t as;
1054 eauditon(A_GETSTAT, (caddr_t)&as, 0);
1056 i = 0;
1057 setauevent();
1058 while ((evp = getauevent()) != NULL) {
1059 if (evp->ae_number <= as.as_numevent) {
1060 ++i;
1061 ec.ec_number = evp->ae_number;
1062 ec.ec_class = evp->ae_class;
1063 eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1066 endauevent();
1067 (void) printf(gettext("Configured %d kernel events.\n"), i);
1072 * do_chkaconf() - report a mismatch if the runtime class mask of a kernel audit
1073 * event does not match the configured class mask. The value returned to the
1074 * user is for the global zone unless AUDIT_PERZONE is set.
1076 static void
1077 do_chkaconf(void)
1079 char *namask_cfg;
1080 au_mask_t pmask, kmask;
1082 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1083 exit_error(gettext("Could not get configured value."));
1085 egetauditflagsbin(namask_cfg, &pmask);
1087 eauditon(A_GETKMASK, (caddr_t)&kmask, sizeof (kmask));
1089 if ((pmask.am_success != kmask.am_success) ||
1090 (pmask.am_failure != kmask.am_failure)) {
1091 char kbuf[2048];
1092 if (getauditflagschar(kbuf, &kmask, 0) < 0) {
1093 free(namask_cfg);
1094 (void) fprintf(stderr,
1095 gettext("bad kernel non-attributable mask\n"));
1096 exit(1);
1098 (void) printf(
1099 gettext("non-attributable event flags mismatch:\n"));
1100 (void) printf(gettext("active non-attributable audit flags "
1101 "= %s\n"), kbuf);
1102 (void) printf(gettext("configured non-attributable audit flags "
1103 "= %s\n"), namask_cfg);
1105 free(namask_cfg);
1109 * do_aconf - configures the non-attributable events. The value returned to the
1110 * user is for the global zone unless AUDIT_PERZONE is set.
1112 static void
1113 do_aconf(void)
1115 au_mask_t namask;
1116 char *namask_cfg;
1118 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1119 exit_error(gettext("Could not get configured value."));
1121 egetauditflagsbin(namask_cfg, &namask);
1122 free(namask_cfg);
1124 eauditon(A_SETKMASK, (caddr_t)&namask, sizeof (namask));
1125 (void) printf(gettext("Configured non-attributable event mask.\n"));
1129 * do_audit() - construct an audit record for audit event event using the
1130 * process's audit characteristics containing a text token string audit_str. The
1131 * return token is constructed from the success/failure flag sort. Returned
1132 * value retval is an errno value.
1134 static void
1135 do_audit(char *event, char sorf, int retval, char *audit_str)
1137 int rtn;
1138 int rd;
1139 au_event_t event_num;
1140 au_event_ent_t *evp;
1141 auditinfo_addr_t ai;
1142 token_t *tokp;
1144 egetaudit(&ai, sizeof (ai));
1146 if (strisnum(event)) {
1147 event_num = (au_event_t)atoi(event);
1148 evp = egetauevnum(event_num);
1149 } else {
1150 evp = egetauevnam(event);
1153 rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
1154 AU_PRS_USECACHE);
1156 if (rtn == -1) {
1157 exit_error("%s\n%s %hu\n",
1158 gettext("Check audit event configuration."),
1159 gettext("Could not get audit class for event number"),
1160 evp->ae_number);
1163 /* record is preselected */
1164 if (rtn == 1) {
1165 if ((rd = au_open()) == -1) {
1166 exit_error(gettext(
1167 "Could not get and audit record descriptor\n"));
1169 if ((tokp = au_to_me()) == NULL) {
1170 exit_error(
1171 gettext("Could not allocate subject token\n"));
1173 if (au_write(rd, tokp) == -1) {
1174 exit_error(gettext("Could not construct subject token "
1175 "of audit record\n"));
1177 if (is_system_labeled()) {
1178 if ((tokp = au_to_mylabel()) == NULL) {
1179 exit_error(gettext(
1180 "Could not allocate label token\n"));
1182 if (au_write(rd, tokp) == -1) {
1183 exit_error(gettext("Could not "
1184 "construct label token of audit record\n"));
1188 if ((tokp = au_to_text(audit_str)) == NULL)
1189 exit_error(gettext("Could not allocate text token\n"));
1190 if (au_write(rd, tokp) == -1)
1191 exit_error(gettext("Could not construct text token of "
1192 "audit record\n"));
1193 #ifdef _LP64
1194 if ((tokp = au_to_return64(sorf, retval)) == NULL)
1195 #else
1196 if ((tokp = au_to_return32(sorf, retval)) == NULL)
1197 #endif
1198 exit_error(
1199 gettext("Could not allocate return token\n"));
1200 if (au_write(rd, tokp) == -1) {
1201 exit_error(gettext("Could not construct return token "
1202 "of audit record\n"));
1204 if (au_close(rd, 1, evp->ae_number) == -1) {
1205 exit_error(
1206 gettext("Could not write audit record: %s\n"),
1207 strerror(errno));
1213 * do_getauid() - print the audit id of the current process.
1215 static void
1216 do_getauid(void)
1218 au_id_t auid;
1220 egetauid(&auid);
1221 print_auid(auid);
1225 * do_getaudit() - print the audit characteristics of the current process.
1227 static void
1228 do_getaudit(void)
1230 auditinfo_addr_t ai;
1232 egetaudit(&ai, sizeof (ai));
1233 print_auid(ai.ai_auid);
1234 print_mask(gettext("process preselection mask"), &ai.ai_mask);
1235 print_tid_ex(&ai.ai_termid);
1236 print_asid(ai.ai_asid);
1240 * do_getkaudit() - print the audit characteristics of the current zone.
1242 static void
1243 do_getkaudit(void)
1245 auditinfo_addr_t ai;
1247 egetkaudit(&ai, sizeof (ai));
1248 print_auid(ai.ai_auid);
1249 print_mask(gettext("process preselection mask"), &ai.ai_mask);
1250 print_tid_ex(&ai.ai_termid);
1251 print_asid(ai.ai_asid);
1255 * do_setkaudit() - set IP address_type/address of machine to specified values;
1256 * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1258 static void
1259 do_setkaudit(char *t, char *s)
1261 uint_t type;
1262 auditinfo_addr_t ai;
1264 egetkaudit(&ai, sizeof (ai));
1265 (void) str2type(t, &type);
1266 (void) str2ipaddr(s, &ai.ai_termid.at_addr[0], type);
1267 ai.ai_termid.at_type = type;
1268 esetkaudit(&ai, sizeof (ai));
1272 * do_getcar() - print the zone-relative root
1274 static void
1275 do_getcar(void)
1277 char path[MAXPATHLEN];
1279 eauditon(A_GETCAR, (caddr_t)path, sizeof (path));
1280 (void) printf(gettext("current active root = %s\n"), path);
1284 * do_getclass() - print the preselection mask associated with the specified
1285 * kernel audit event. The displayed value is for the global zone unless
1286 * AUDIT_PERZONE is set.
1288 static void
1289 do_getclass(char *event_str)
1291 au_evclass_map_t ec;
1292 au_event_ent_t *evp;
1293 au_event_t event_number;
1294 char *event_name;
1296 if (strisnum(event_str)) {
1297 event_number = atol(event_str);
1298 if ((evp = egetauevnum(event_number)) != NULL) {
1299 event_number = evp->ae_number;
1300 event_name = evp->ae_name;
1301 } else {
1302 event_name = gettext("unknown");
1304 } else {
1305 event_name = event_str;
1306 if ((evp = egetauevnam(event_str)) != NULL) {
1307 event_number = evp->ae_number;
1311 ec.ec_number = event_number;
1312 eauditon(A_GETCLASS, (caddr_t)&ec, 0);
1314 (void) printf(gettext("audit class mask for event %s(%hu) = 0x%x\n"),
1315 event_name, event_number, ec.ec_class);
1319 * do_getcond() - the printed value is for the global zone unless
1320 * AUDIT_PERZONE is set. (AUC_DISABLED is always global, the other states are
1321 * per zone if AUDIT_PERZONE is set)
1323 static void
1324 do_getcond(void)
1326 (void) printf(gettext("audit condition = %s\n"), cond2str());
1330 * do_getcwd() - the printed path is relative to the current zone root
1332 static void
1333 do_getcwd(void)
1335 char path[MAXPATHLEN];
1337 eauditon(A_GETCWD, (caddr_t)path, sizeof (path));
1338 (void) printf(gettext("current working directory = %s\n"), path);
1342 * do_getflags() - the printed value is for the global zone unless AUDIT_PERZONE
1343 * is set.
1345 static void
1346 do_getflags(void)
1348 au_mask_t amask;
1349 char *amask_cfg;
1351 eauditon(A_GETAMASK, (caddr_t)&amask, sizeof (amask));
1352 print_mask(gettext("active user default audit flags"), &amask);
1354 if (!do_getflags_scf(&amask_cfg) || amask_cfg == NULL) {
1355 exit_error(gettext("Could not get configured value."));
1357 egetauditflagsbin(amask_cfg, &amask);
1358 print_mask(gettext("configured user default audit flags"), &amask);
1359 free(amask_cfg);
1363 * do_getkmask() - the printed value is for the global zone unless AUDIT_PERZONE
1364 * is set.
1366 static void
1367 do_getkmask(void)
1369 au_mask_t pmask;
1371 eauditon(A_GETKMASK, (caddr_t)&pmask, sizeof (pmask));
1372 print_mask(gettext("active non-attributable audit flags"), &pmask);
1376 * do_getnaflags() - the printed value is for the global zone unless
1377 * AUDIT_PERZONE is set.
1379 static void
1380 do_getnaflags(void)
1382 au_mask_t namask;
1383 char *namask_cfg;
1385 eauditon(A_GETKMASK, (caddr_t)&namask, sizeof (namask));
1386 print_mask(gettext("active non-attributable audit flags"), &namask);
1388 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1389 exit_error(gettext("Could not get configured value."));
1391 egetauditflagsbin(namask_cfg, &namask);
1392 print_mask(gettext("configured non-attributable audit flags"), &namask);
1393 free(namask_cfg);
1397 * do_getpolicy() - print active and configured kernel audit policy relative to
1398 * the current zone.
1400 static void
1401 do_getpolicy(void)
1403 char policy_str[1024];
1404 uint32_t policy;
1406 if (!temporary_set) {
1407 if (!do_getpolicy_scf(&policy)) {
1408 exit_error(gettext("Could not get configured values."));
1410 (void) policy2str(policy, policy_str, sizeof (policy_str));
1411 (void) printf(gettext("configured audit policies = %s\n"),
1412 policy_str);
1415 eauditon(A_GETPOLICY, (caddr_t)&policy, 0);
1416 (void) policy2str(policy, policy_str, sizeof (policy_str));
1417 (void) printf(gettext("active audit policies = %s\n"), policy_str);
1422 * do_getpinfo() - print the audit ID, preselection mask, terminal ID, and
1423 * audit session ID for the specified process.
1425 static void
1426 do_getpinfo(char *pid_str)
1428 struct auditpinfo_addr ap;
1430 if (strisnum(pid_str))
1431 ap.ap_pid = (pid_t)atoi(pid_str);
1432 else
1433 exit_usage(1);
1435 eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
1437 print_auid(ap.ap_auid);
1438 print_mask(gettext("process preselection mask"), &(ap.ap_mask));
1439 print_tid_ex(&(ap.ap_termid));
1440 print_asid(ap.ap_asid);
1444 * do_getplugin() - print plugin configuration.
1446 static void
1447 do_getplugin(char *plugin_str)
1449 scf_plugin_kva_node_t *plugin_kva_ll;
1450 scf_plugin_kva_node_t *plugin_kva_ll_head;
1452 if (!do_getpluginconfig_scf(plugin_str, &plugin_kva_ll)) {
1453 exit_error(gettext("Could not get plugin configuration."));
1456 plugin_kva_ll_head = plugin_kva_ll;
1458 while (plugin_kva_ll != NULL) {
1459 print_plugin(plugin_kva_ll->plugin_name,
1460 plugin_kva_ll->plugin_kva);
1461 plugin_kva_ll = plugin_kva_ll->next;
1462 if (plugin_kva_ll != NULL) {
1463 (void) printf("\n");
1466 plugin_kva_ll_free(plugin_kva_ll_head);
1470 * do_getqbufsz() - print the active and configured audit queue write buffer
1471 * size relative to the current zone.
1473 static void
1474 do_getqbufsz(void)
1476 struct au_qctrl qctrl;
1478 if (!temporary_set) {
1479 if (!do_getqbufsz_scf(&qctrl.aq_bufsz)) {
1480 exit_error(gettext("Could not get configured value."));
1483 if (qctrl.aq_bufsz == 0) {
1484 (void) printf(gettext(
1485 "no configured audit queue buffer size\n"));
1486 } else {
1487 (void) printf(gettext("configured audit queue "
1488 "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1492 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1493 (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1494 qctrl.aq_bufsz);
1498 * do_getqctrl() - print the configured and active audit queue write buffer
1499 * size, audit queue hiwater mark, audit queue lowater mark, audit queue prod
1500 * interval (ticks) relative to the current zone.
1502 static void
1503 do_getqctrl(void)
1505 struct au_qctrl qctrl;
1507 if (!temporary_set) {
1508 if (!do_getqctrl_scf(&qctrl)) {
1509 exit_error(gettext("Could not get configured values."));
1512 if (qctrl.aq_hiwater == 0) {
1513 (void) printf(gettext(
1514 "no configured audit queue hiwater mark\n"));
1515 } else {
1516 (void) printf(gettext("configured audit queue "
1517 "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1519 if (qctrl.aq_lowater == 0) {
1520 (void) printf(gettext(
1521 "no configured audit queue lowater mark\n"));
1522 } else {
1523 (void) printf(gettext("configured audit queue "
1524 "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1526 if (qctrl.aq_bufsz == 0) {
1527 (void) printf(gettext(
1528 "no configured audit queue buffer size\n"));
1529 } else {
1530 (void) printf(gettext("configured audit queue "
1531 "buffer size (bytes) = %d\n"), qctrl.aq_bufsz);
1533 if (qctrl.aq_delay == 0) {
1534 (void) printf(gettext(
1535 "no configured audit queue delay\n"));
1536 } else {
1537 (void) printf(gettext("configured audit queue "
1538 "delay (ticks) = %ld\n"), qctrl.aq_delay);
1542 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1543 (void) printf(gettext("active audit queue hiwater mark "
1544 "(records) = %d\n"), qctrl.aq_hiwater);
1545 (void) printf(gettext("active audit queue lowater mark "
1546 "(records) = %d\n"), qctrl.aq_lowater);
1547 (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1548 qctrl.aq_bufsz);
1549 (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1550 qctrl.aq_delay);
1554 * do_getqdelay() - print, relative to the current zone, the configured and
1555 * active interval at which audit queue is prodded to start output.
1557 static void
1558 do_getqdelay(void)
1560 struct au_qctrl qctrl;
1562 if (!temporary_set) {
1563 if (!do_getqdelay_scf(&qctrl.aq_delay)) {
1564 exit_error(gettext("Could not get configured value."));
1567 if (qctrl.aq_delay == 0) {
1568 (void) printf(gettext(
1569 "no configured audit queue delay\n"));
1570 } else {
1571 (void) printf(gettext("configured audit queue "
1572 "delay (ticks) = %ld\n"), qctrl.aq_delay);
1576 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1577 (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1578 qctrl.aq_delay);
1582 * do_getqhiwater() - print, relative to the current zone, the high water
1583 * point in undelivered audit records when audit generation will block.
1585 static void
1586 do_getqhiwater(void)
1588 struct au_qctrl qctrl;
1590 if (!temporary_set) {
1591 if (!do_getqhiwater_scf(&qctrl.aq_hiwater)) {
1592 exit_error(gettext("Could not get configured value."));
1595 if (qctrl.aq_hiwater == 0) {
1596 (void) printf(gettext(
1597 "no configured audit queue hiwater mark\n"));
1598 } else {
1599 (void) printf(gettext("configured audit queue "
1600 "hiwater mark (records) = %d\n"), qctrl.aq_hiwater);
1604 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1605 (void) printf(gettext("active audit queue hiwater mark "
1606 "(records) = %d\n"), qctrl.aq_hiwater);
1610 * do_getqlowater() - print, relative to the current zone, the low water point
1611 * in undelivered audit records where blocked processes will resume.
1613 static void
1614 do_getqlowater(void)
1616 struct au_qctrl qctrl;
1618 if (!temporary_set) {
1619 if (!do_getqlowater_scf(&qctrl.aq_lowater)) {
1620 exit_error(gettext("Could not get configured value."));
1623 if (qctrl.aq_lowater == 0) {
1624 (void) printf(gettext(
1625 "no configured audit queue lowater mark\n"));
1626 } else {
1627 (void) printf(gettext("configured audit queue "
1628 "lowater mark (records) = %d\n"), qctrl.aq_lowater);
1632 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1633 (void) printf(gettext("active audit queue lowater mark "
1634 "(records) = %d\n"), qctrl.aq_lowater);
1638 * do_getasid() - print out the audit session-ID.
1640 static void
1641 do_getasid(void)
1643 auditinfo_addr_t ai;
1645 if (getaudit_addr(&ai, sizeof (ai))) {
1646 exit_error(gettext("getaudit_addr(2) failed"));
1648 print_asid(ai.ai_asid);
1652 * do_getstat() - the printed statistics are for the entire system unless
1653 * AUDIT_PERZONE is set.
1655 static void
1656 do_getstat(void)
1658 au_stat_t as;
1659 int offset[12]; /* used to line the header up correctly */
1660 char buf[512];
1662 eauditon(A_GETSTAT, (caddr_t)&as, 0);
1663 (void) sprintf(buf, "%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu "
1664 "%n%4lu %n%4lu %n%4lu %n%4lu %n%4lu%n",
1665 (ulong_t)as.as_generated, &(offset[0]),
1666 (ulong_t)as.as_nonattrib, &(offset[1]),
1667 (ulong_t)as.as_kernel, &(offset[2]),
1668 (ulong_t)as.as_audit, &(offset[3]),
1669 (ulong_t)as.as_auditctl, &(offset[4]),
1670 (ulong_t)as.as_enqueue, &(offset[5]),
1671 (ulong_t)as.as_written, &(offset[6]),
1672 (ulong_t)as.as_wblocked, &(offset[7]),
1673 (ulong_t)as.as_rblocked, &(offset[8]),
1674 (ulong_t)as.as_dropped, &(offset[9]),
1675 (ulong_t)as.as_totalsize / ONEK, &(offset[10]),
1676 (ulong_t)as.as_memused / ONEK, &(offset[11]));
1679 * TRANSLATION_NOTE
1680 * Print a properly aligned header.
1682 (void) printf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n",
1683 offset[0] - 1, gettext("gen"),
1684 offset[1] - offset[0] -1, gettext("nona"),
1685 offset[2] - offset[1] -1, gettext("kern"),
1686 offset[3] - offset[2] -1, gettext("aud"),
1687 offset[4] - offset[3] -1, gettext("ctl"),
1688 offset[5] - offset[4] -1, gettext("enq"),
1689 offset[6] - offset[5] -1, gettext("wrtn"),
1690 offset[7] - offset[6] -1, gettext("wblk"),
1691 offset[8] - offset[7] -1, gettext("rblk"),
1692 offset[9] - offset[8] -1, gettext("drop"),
1693 offset[10] - offset[9] -1, gettext("tot"),
1694 offset[11] - offset[10], gettext("mem"));
1696 (void) printf("%s\n", buf);
1700 * do_gettermid() - print audit terminal ID for current process.
1702 static void
1703 do_gettermid(void)
1705 auditinfo_addr_t ai;
1707 if (getaudit_addr(&ai, sizeof (ai))) {
1708 exit_error(gettext("getaudit_addr(2) failed"));
1710 print_tid_ex(&ai.ai_termid);
1714 * do_lsevent() - display the active kernel and user level audit event
1715 * information. The printed events are for the global zone unless AUDIT_PERZONE
1716 * is set.
1718 static void
1719 do_lsevent(void)
1721 register au_event_ent_t *evp;
1722 au_mask_t pmask;
1723 char auflags[256];
1725 setauevent();
1726 if (getauevent() == NULL) {
1727 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1728 AUDITEVENTFILE);
1731 setauevent();
1732 while ((evp = getauevent()) != NULL) {
1733 pmask.am_success = pmask.am_failure = evp->ae_class;
1734 if (getauditflagschar(auflags, &pmask, 0) == -1)
1735 (void) strcpy(auflags, "unknown");
1736 (void) printf("%-30s %5hu %s %s\n",
1737 evp->ae_name, evp->ae_number, auflags, evp->ae_desc);
1739 endauevent();
1743 * do_lspolicy() - display the kernel audit policies with a description of each
1744 * policy. The printed value is for the global zone unless AUDIT_PERZONE is set.
1746 static void
1747 do_lspolicy(void)
1749 int i;
1752 * TRANSLATION_NOTE
1753 * Print a properly aligned header.
1755 (void) printf(gettext("policy string description:\n"));
1756 for (i = 0; i < POLICY_TBL_SZ; i++) {
1757 (void) printf("%-17s%s\n", policy_table[i].policy_str,
1758 gettext(policy_table[i].policy_desc));
1763 * do_setasid() - execute shell or cmd with specified session-ID.
1765 static void
1766 do_setasid(char *sid_str, char **argv)
1768 struct auditinfo_addr ai;
1770 if (getaudit_addr(&ai, sizeof (ai))) {
1771 exit_error(gettext("getaudit_addr(2) failed"));
1773 ai.ai_asid = (au_asid_t)atol(sid_str);
1774 if (setaudit_addr(&ai, sizeof (ai))) {
1775 exit_error(gettext("setaudit_addr(2) failed"));
1777 execit(argv);
1781 * do_setaudit() - execute shell or cmd with specified audit characteristics.
1783 static void
1784 do_setaudit(char *user_str, char *mask_str, char *tid_str, char *sid_str,
1785 char **argv)
1787 auditinfo_addr_t ai;
1789 ai.ai_auid = (au_id_t)get_user_id(user_str);
1790 egetauditflagsbin(mask_str, &ai.ai_mask),
1791 str2tid(tid_str, &ai.ai_termid);
1792 ai.ai_asid = (au_asid_t)atol(sid_str);
1794 esetaudit(&ai, sizeof (ai));
1795 execit(argv);
1799 * do_setauid() - execute shell or cmd with specified audit-ID.
1801 static void
1802 do_setauid(char *user, char **argv)
1804 au_id_t auid;
1806 auid = get_user_id(user);
1807 esetauid(&auid);
1808 execit(argv);
1812 * do_setpmask() - set the preselection mask of the specified process; valid
1813 * per zone if AUDIT_PERZONE is set, else only in global zone.
1815 static void
1816 do_setpmask(char *pid_str, au_mask_t *mask)
1818 struct auditpinfo ap;
1820 if (strisnum(pid_str)) {
1821 ap.ap_pid = (pid_t)atoi(pid_str);
1822 } else {
1823 exit_usage(1);
1826 ap.ap_mask.am_success = mask->am_success;
1827 ap.ap_mask.am_failure = mask->am_failure;
1829 eauditon(A_SETPMASK, (caddr_t)&ap, sizeof (ap));
1833 * do_setsmask() - set the preselection mask of all processes with the specified
1834 * audit session-ID; valid per zone if AUDIT_PERZONE is set, else only in global
1835 * zone.
1837 static void
1838 do_setsmask(char *asid_str, au_mask_t *mask)
1840 struct auditinfo ainfo;
1842 if (strisnum(asid_str)) {
1843 ainfo.ai_asid = (au_asid_t)atoi(asid_str);
1844 } else {
1845 exit_usage(1);
1848 ainfo.ai_mask.am_success = mask->am_success;
1849 ainfo.ai_mask.am_failure = mask->am_failure;
1851 eauditon(A_SETSMASK, (caddr_t)&ainfo, sizeof (ainfo));
1855 * do_setumask() - set the preselection mask of all processes with the
1856 * specified audit-ID; valid per zone if AUDIT_PERZONE is set, else only in
1857 * global zone.
1859 static void
1860 do_setumask(char *auid_str, au_mask_t *mask)
1862 struct auditinfo ainfo;
1864 if (strisnum(auid_str)) {
1865 ainfo.ai_auid = (au_id_t)atoi(auid_str);
1866 } else {
1867 exit_usage(1);
1870 ainfo.ai_mask.am_success = mask->am_success;
1871 ainfo.ai_mask.am_failure = mask->am_failure;
1873 eauditon(A_SETUMASK, (caddr_t)&ainfo, sizeof (ainfo));
1877 * do_setstat() - reset audit statistics counters; local zone use is valid if
1878 * AUDIT_PERZONE is set, otherwise the syscall returns EPERM.
1880 static void
1881 do_setstat(void)
1883 au_stat_t as;
1885 as.as_audit = (uint_t)-1;
1886 as.as_auditctl = (uint_t)-1;
1887 as.as_dropped = (uint_t)-1;
1888 as.as_enqueue = (uint_t)-1;
1889 as.as_generated = (uint_t)-1;
1890 as.as_kernel = (uint_t)-1;
1891 as.as_nonattrib = (uint_t)-1;
1892 as.as_rblocked = (uint_t)-1;
1893 as.as_totalsize = (uint_t)-1;
1894 as.as_wblocked = (uint_t)-1;
1895 as.as_written = (uint_t)-1;
1897 eauditon(A_SETSTAT, (caddr_t)&as, sizeof (as));
1898 (void) printf("%s\n", gettext("audit stats reset"));
1902 * do_setclass() - map the kernel event event_str to the classes specified by
1903 * audit flags (mask); valid per zone if AUDIT_PERZONE is set, else only in
1904 * global zone.
1906 static void
1907 do_setclass(char *event_str, au_mask_t *mask)
1909 au_event_t event;
1910 au_evclass_map_t ec;
1911 au_event_ent_t *evp;
1913 if (strisnum(event_str)) {
1914 event = (uint_t)atol(event_str);
1915 } else {
1916 if ((evp = egetauevnam(event_str)) != NULL) {
1917 event = evp->ae_number;
1921 ec.ec_number = event;
1922 ec.ec_class = (mask->am_success | mask->am_failure);
1924 eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1928 * do_setflags() - set configured and active default user preselection masks;
1929 * valid per zone if AUDIT_PERZONE is set, else only in global zone.
1931 static void
1932 do_setflags(char *audit_flags, au_mask_t *amask)
1934 eauditon(A_SETAMASK, (caddr_t)amask, sizeof (*amask));
1936 if (!do_setflags_scf(audit_flags)) {
1937 print_mask(gettext("active user default audit flags"), amask);
1938 exit_error(gettext("Could not store configuration value."));
1940 print_mask(gettext("user default audit flags"), amask);
1944 * do_setkmask() - set non-attributable audit flags of machine; valid per zone
1945 * if AUDIT_PERZONE is set, else only in global zone.
1947 static void
1948 do_setkmask(au_mask_t *pmask)
1950 eauditon(A_SETKMASK, (caddr_t)pmask, sizeof (*pmask));
1951 print_mask(gettext("active non-attributable audit flags"), pmask);
1955 * do_setnaflags() - set configured and active non-attributable selection flags
1956 * of machine; valid per zone if AUDIT_PERZONE is set, else only in global zone.
1958 static void
1959 do_setnaflags(char *audit_naflags, au_mask_t *namask)
1961 eauditon(A_SETKMASK, (caddr_t)namask, sizeof (*namask));
1963 if (!do_setnaflags_scf(audit_naflags)) {
1964 print_mask(
1965 gettext("active non-attributable audit flags"), namask);
1966 exit_error(gettext("Could not store configuration value."));
1968 print_mask(gettext("non-attributable audit flags"), namask);
1972 * do_setplugin() - set the given plugin plugin_str configuration values.
1974 static void
1975 do_setplugin(char *plugin_str, boolean_t plugin_state, char *plugin_attr,
1976 int plugin_qsize)
1978 if (!do_setpluginconfig_scf(plugin_str, plugin_state, plugin_attr,
1979 plugin_qsize)) {
1980 exit_error(gettext("Could not set plugin configuration."));
1985 * do_setpolicy() - set the active and configured kernel audit policy; active
1986 * values can be changed per zone if AUDIT_PERZONE is set, else only in global
1987 * zone.
1989 * ahlt and perzone are global zone only. The kernel ensures that a local zone
1990 * can't change ahlt and perzone (EINVAL).
1992 static void
1993 do_setpolicy(char *policy_str)
1995 uint32_t policy = 0;
1997 switch (str2policy(policy_str, &policy)) {
1998 case 0:
1999 if (!temporary_set) {
2000 if (!do_getpolicy_scf(&policy)) {
2001 exit_error(gettext("Unable to get current "
2002 "policy values from the SMF repository"));
2004 (void) str2policy(policy_str, &policy);
2006 if (!do_setpolicy_scf(policy)) {
2007 exit_error(gettext("Could not store "
2008 "configuration values."));
2011 eauditon(A_SETPOLICY, (caddr_t)&policy, 0);
2012 break;
2013 case 2:
2014 exit_error(gettext("policy (%s) invalid in a local zone."),
2015 policy_str);
2016 break;
2017 default:
2018 exit_error(gettext("Invalid policy (%s) specified."),
2019 policy_str);
2020 break;
2025 * do_setqbufsz() - set the active and configured audit queue write buffer size
2026 * (bytes); active values can be changed per zone if AUDIT_PERZONE is set, else
2027 * only in global zone.
2029 static void
2030 do_setqbufsz(char *bufsz)
2032 struct au_qctrl qctrl;
2034 if (!temporary_set) {
2035 qctrl.aq_bufsz = (size_t)atol(bufsz);
2036 if (!do_setqbufsz_scf(&qctrl.aq_bufsz)) {
2037 exit_error(gettext(
2038 "Could not store configuration value."));
2040 if (qctrl.aq_bufsz == 0) {
2041 return;
2045 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2046 qctrl.aq_bufsz = (size_t)atol(bufsz);
2047 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2051 * do_setqctrl() - set the active and configured audit queue write buffer size
2052 * (bytes), hiwater audit record count, lowater audit record count, and wakeup
2053 * interval (ticks); active values can be changed per zone if AUDIT_PERZONE is
2054 * set, else only in global zone.
2056 static void
2057 do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay)
2059 struct au_qctrl qctrl;
2061 qctrl.aq_hiwater = (size_t)atol(hiwater);
2062 qctrl.aq_lowater = (size_t)atol(lowater);
2063 qctrl.aq_bufsz = (size_t)atol(bufsz);
2064 qctrl.aq_delay = (clock_t)atol(delay);
2066 if (!temporary_set) {
2067 struct au_qctrl qctrl_act;
2069 if (!do_setqctrl_scf(&qctrl)) {
2070 exit_error(gettext(
2071 "Could not store configuration values."));
2074 eauditon(A_GETQCTRL, (caddr_t)&qctrl_act, 0);
2075 if (qctrl.aq_hiwater == 0) {
2076 qctrl.aq_hiwater = qctrl_act.aq_hiwater;
2078 if (qctrl.aq_lowater == 0) {
2079 qctrl.aq_lowater = qctrl_act.aq_lowater;
2081 if (qctrl.aq_bufsz == 0) {
2082 qctrl.aq_bufsz = qctrl_act.aq_bufsz;
2084 if (qctrl.aq_delay == 0) {
2085 qctrl.aq_delay = qctrl_act.aq_delay;
2089 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2093 * do_setqdelay() - set the active and configured audit queue wakeup interval
2094 * (ticks); active values can be changed per zone if AUDIT_PERZONE is set, else
2095 * only in global zone.
2097 static void
2098 do_setqdelay(char *delay)
2100 struct au_qctrl qctrl;
2102 if (!temporary_set) {
2103 qctrl.aq_delay = (clock_t)atol(delay);
2104 if (!do_setqdelay_scf(&qctrl.aq_delay)) {
2105 exit_error(gettext(
2106 "Could not store configuration value."));
2108 if (qctrl.aq_delay == 0) {
2109 return;
2113 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2114 qctrl.aq_delay = (clock_t)atol(delay);
2115 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2119 * do_setqhiwater() - sets the active and configured number of undelivered audit
2120 * records in the audit queue at which audit record generation blocks; active
2121 * values can be changed per zone if AUDIT_PERZONE is set, else only in global
2122 * zone.
2124 static void
2125 do_setqhiwater(char *hiwater)
2127 struct au_qctrl qctrl;
2129 if (!temporary_set) {
2130 qctrl.aq_hiwater = (size_t)atol(hiwater);
2131 if (!do_setqhiwater_scf(&qctrl.aq_hiwater)) {
2132 exit_error(gettext(
2133 "Could not store configuration value."));
2135 if (qctrl.aq_hiwater == 0) {
2136 return;
2140 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2141 qctrl.aq_hiwater = (size_t)atol(hiwater);
2142 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2146 * do_setqlowater() - set the active and configured number of undelivered audit
2147 * records in the audit queue at which blocked auditing processes unblock;
2148 * active values can be changed per zone if AUDIT_PERZONE is set, else only in
2149 * global zone.
2151 static void
2152 do_setqlowater(char *lowater)
2154 struct au_qctrl qctrl;
2156 if (!temporary_set) {
2157 qctrl.aq_lowater = (size_t)atol(lowater);
2158 if (!do_setqlowater_scf(&qctrl.aq_lowater)) {
2159 exit_error(gettext(
2160 "Could not store configuration value."));
2162 if (qctrl.aq_lowater == 0) {
2163 return;
2167 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2168 qctrl.aq_lowater = (size_t)atol(lowater);
2169 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2172 static void
2173 eauditon(int cmd, caddr_t data, int length)
2175 if (auditon(cmd, data, length) == -1)
2176 exit_error(gettext("auditon(2) failed."));
2179 static void
2180 egetauid(au_id_t *auid)
2182 if (getauid(auid) == -1)
2183 exit_error(gettext("getauid(2) failed."));
2186 static void
2187 egetaudit(auditinfo_addr_t *ai, int size)
2189 if (getaudit_addr(ai, size) == -1)
2190 exit_error(gettext("getaudit_addr(2) failed."));
2193 static void
2194 egetkaudit(auditinfo_addr_t *ai, int size)
2196 if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
2197 exit_error(gettext("auditon: A_GETKAUDIT failed."));
2200 static void
2201 esetkaudit(auditinfo_addr_t *ai, int size)
2203 if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
2204 exit_error(gettext("auditon: A_SETKAUDIT failed."));
2207 static void
2208 egetauditflagsbin(char *auditflags, au_mask_t *pmask)
2210 if (strcmp(auditflags, "none") == 0) {
2211 pmask->am_success = pmask->am_failure = 0;
2212 return;
2215 if (getauditflagsbin(auditflags, pmask) < 0) {
2216 exit_error(gettext("Could not get audit flags (%s)"),
2217 auditflags);
2221 static void
2222 echkflags(char *auditflags, au_mask_t *mask)
2224 char *err = "";
2225 char *err_ptr;
2227 if (!__chkflags(auditflags, mask, B_FALSE, &err)) {
2228 err_ptr = err;
2229 while (*err_ptr != ',' && *err_ptr != '\0') {
2230 err_ptr++;
2232 *err_ptr = '\0';
2233 exit_error(gettext("Unknown audit flags and/or prefixes "
2234 "encountered: %s"), err);
2238 static au_event_ent_t *
2239 egetauevnum(au_event_t event_number)
2241 au_event_ent_t *evp;
2243 if ((evp = getauevnum(event_number)) == NULL) {
2244 exit_error(gettext("Could not get audit event %hu"),
2245 event_number);
2248 return (evp);
2251 static au_event_ent_t *
2252 egetauevnam(char *event_name)
2254 register au_event_ent_t *evp;
2256 if ((evp = getauevnam(event_name)) == NULL)
2257 exit_error(gettext("Could not get audit event %s"), event_name);
2259 return (evp);
2262 static void
2263 esetauid(au_id_t *auid)
2265 if (setauid(auid) == -1)
2266 exit_error(gettext("setauid(2) failed."));
2269 static void
2270 esetaudit(auditinfo_addr_t *ai, int size)
2272 if (setaudit_addr(ai, size) == -1)
2273 exit_error(gettext("setaudit_addr(2) failed."));
2276 static uid_t
2277 get_user_id(char *user)
2279 struct passwd *pwd;
2280 uid_t uid;
2282 if (isdigit(*user)) {
2283 uid = atoi(user);
2284 if ((pwd = getpwuid(uid)) == NULL) {
2285 exit_error(gettext("Invalid user: %s"), user);
2287 } else {
2288 if ((pwd = getpwnam(user)) == NULL) {
2289 exit_error(gettext("Invalid user: %s"), user);
2293 return (pwd->pw_uid);
2297 * get_arg_ent()
2298 * Inputs: command line argument string
2299 * Returns ptr to struct arg_entry if found; null, if not found
2301 static arg_entry_t *
2302 get_arg_ent(char *arg_str)
2304 arg_entry_t key;
2306 key.arg_str = arg_str;
2308 return ((arg_entry_t *)bsearch((char *)&key, (char *)arg_table,
2309 ARG_TBL_SZ, sizeof (arg_entry_t), arg_ent_compare));
2313 * arg_ent_compare()
2314 * Compares two command line arguments to determine which is
2315 * lexicographically greater.
2316 * Inputs: two argument map table entry pointers
2317 * Returns: > 1: aep1->arg_str > aep2->arg_str
2318 * < 1: aep1->arg_str < aep2->arg_str
2319 * 0: aep1->arg_str = aep->arg_str2
2321 static int
2322 arg_ent_compare(const void *aep1, const void *aep2)
2324 return (strcmp(((arg_entry_t *)aep1)->arg_str,
2325 ((arg_entry_t *)aep2)->arg_str));
2329 * tid_str is major,minor,host -- host is a name or an ip address
2331 static void
2332 str2tid(char *tid_str, au_tid_addr_t *tp)
2334 char *major_str;
2335 char *minor_str;
2336 char *host_str = NULL;
2337 major_t major = 0;
2338 major_t minor = 0;
2339 dev_t dev = 0;
2340 struct hostent *phe;
2341 int err;
2342 uint32_t ibuf;
2343 uint32_t ibuf6[4];
2345 tp->at_port = 0;
2346 tp->at_type = 0;
2347 bzero(tp->at_addr, 16);
2349 major_str = tid_str;
2350 if ((minor_str = strchr(tid_str, ',')) != NULL) {
2351 *minor_str = '\0';
2352 minor_str++;
2355 if (minor_str) {
2356 if ((host_str = strchr(minor_str, ',')) != NULL) {
2357 *host_str = '\0';
2358 host_str++;
2362 if (major_str)
2363 major = (major_t)atoi(major_str);
2365 if (minor_str)
2366 minor = (minor_t)atoi(minor_str);
2368 if ((dev = makedev(major, minor)) != NODEV)
2369 tp->at_port = dev;
2371 if (host_str) {
2372 if (strisipaddr(host_str)) {
2373 if (inet_pton(AF_INET, host_str, &ibuf)) {
2374 tp->at_addr[0] = ibuf;
2375 tp->at_type = AU_IPv4;
2376 } else if (inet_pton(AF_INET6, host_str, ibuf6)) {
2377 tp->at_addr[0] = ibuf6[0];
2378 tp->at_addr[1] = ibuf6[1];
2379 tp->at_addr[2] = ibuf6[2];
2380 tp->at_addr[3] = ibuf6[3];
2381 tp->at_type = AU_IPv6;
2383 } else {
2384 phe = getipnodebyname((const void *)host_str,
2385 AF_INET, 0, &err);
2386 if (phe == 0) {
2387 phe = getipnodebyname((const void *)host_str,
2388 AF_INET6, 0, &err);
2391 if (phe != NULL) {
2392 if (phe->h_addrtype == AF_INET6) {
2393 /* address is IPv6 (128 bits) */
2394 (void) memcpy(&tp->at_addr[0],
2395 phe->h_addr_list[0], 16);
2396 tp->at_type = AU_IPv6;
2397 } else {
2398 /* address is IPv4 (32 bits) */
2399 (void) memcpy(&tp->at_addr[0],
2400 phe->h_addr_list[0], 4);
2401 tp->at_type = AU_IPv4;
2403 freehostent(phe);
2409 static char *
2410 cond2str(void)
2412 uint_t cond;
2414 eauditon(A_GETCOND, (caddr_t)&cond, sizeof (cond));
2416 switch (cond) {
2418 case AUC_AUDITING:
2419 return ("auditing");
2421 case AUC_NOAUDIT:
2422 case AUC_INIT_AUDIT:
2423 return ("noaudit");
2425 case AUC_UNSET:
2426 return ("unset");
2428 case AUC_NOSPACE:
2429 return ("nospace");
2431 default:
2432 return ("");
2437 * exit = 0, success
2438 * 1, error
2439 * 2, bad zone
2441 static int
2442 str2policy(char *policy_str, uint32_t *policy_mask)
2444 char *buf;
2445 char *tok;
2446 char pfix;
2447 boolean_t is_all = B_FALSE;
2448 uint32_t pm = 0;
2449 uint32_t curp;
2451 pfix = *policy_str;
2453 if (pfix == '-' || pfix == '+' || pfix == '=')
2454 ++policy_str;
2456 if ((buf = strdup(policy_str)) == NULL)
2457 return (1);
2459 for (tok = strtok(buf, ","); tok != NULL; tok = strtok(NULL, ",")) {
2460 uint32_t tok_pm;
2461 if (((tok_pm = get_policy(tok)) == 0) &&
2462 ((strcasecmp(tok, "none") != 0))) {
2463 free(buf);
2464 return (1);
2465 } else {
2466 pm |= tok_pm;
2467 if (tok_pm == ALL_POLICIES) {
2468 is_all = B_TRUE;
2472 free(buf);
2474 /* reuse policy mask if already set to some value */
2475 if (*policy_mask != 0) {
2476 curp = *policy_mask;
2477 } else {
2478 (void) auditon(A_GETPOLICY, (caddr_t)&curp, 0);
2481 if (pfix == '-') {
2482 if (!is_all &&
2483 (getzoneid() != GLOBAL_ZONEID) &&
2484 (pm & ~AUDIT_LOCAL)) {
2485 return (2);
2488 if (getzoneid() != GLOBAL_ZONEID)
2489 curp &= AUDIT_LOCAL;
2490 *policy_mask = curp & ~pm;
2492 } else if (pfix == '+') {
2494 * In a local zone, accept specifying "all", but not
2495 * individually specifying global-zone only policies.
2496 * Limit to all locally allowed, so system call doesn't
2497 * fail.
2499 if (!is_all &&
2500 (getzoneid() != GLOBAL_ZONEID) &&
2501 (pm & ~AUDIT_LOCAL)) {
2502 return (2);
2505 if (getzoneid() != GLOBAL_ZONEID) {
2506 curp &= AUDIT_LOCAL;
2507 if (is_all) {
2508 pm &= AUDIT_LOCAL;
2511 *policy_mask = curp | pm;
2513 } else {
2515 * In a local zone, accept specifying "all", but not
2516 * individually specifying global-zone only policies.
2517 * Limit to all locally allowed, so system call doesn't
2518 * fail.
2520 if (!is_all &&
2521 (getzoneid() != GLOBAL_ZONEID) &&
2522 (pm & ~AUDIT_LOCAL)) {
2523 return (2);
2526 if (is_all && (getzoneid() != GLOBAL_ZONEID)) {
2527 pm &= AUDIT_LOCAL;
2529 *policy_mask = pm;
2531 return (0);
2534 static int
2535 policy2str(uint32_t policy, char *policy_str, size_t len)
2537 int i, j;
2539 if (policy == ALL_POLICIES) {
2540 (void) strcpy(policy_str, "all");
2541 return (1);
2544 if (policy == NO_POLICIES) {
2545 (void) strcpy(policy_str, "none");
2546 return (1);
2549 *policy_str = '\0';
2551 for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) {
2552 if (policy & policy_table[i].policy_mask &&
2553 policy_table[i].policy_mask != ALL_POLICIES) {
2554 if (j++) {
2555 (void) strcat(policy_str, ",");
2557 (void) strlcat(policy_str, policy_table[i].policy_str,
2558 len);
2562 if (*policy_str)
2563 return (0);
2565 return (1);
2569 static int
2570 strisnum(char *s)
2572 if (s == NULL || !*s)
2573 return (0);
2575 for (; *s == '-' || *s == '+'; s++)
2577 if (!*s)
2578 return (0);
2580 for (; *s; s++)
2581 if (!isdigit(*s))
2582 return (0);
2584 return (1);
2587 static int
2588 strisipaddr(char *s)
2590 int dot = 0;
2591 int colon = 0;
2593 /* no string */
2594 if ((s == NULL) || (!*s))
2595 return (0);
2597 for (; *s; s++) {
2598 if (!(isxdigit(*s) || *s != '.' || *s != ':'))
2599 return (0);
2600 if (*s == '.')
2601 dot++;
2602 if (*s == ':')
2603 colon++;
2606 if (dot && colon)
2607 return (0);
2609 if (!dot && !colon)
2610 return (0);
2612 return (1);
2615 static void
2616 chk_arg_len(char *argv, uint_t len)
2618 if ((strlen(argv) + 1) > len) {
2619 *(argv + len - 1) = '\0';
2620 exit_error(gettext("Argument too long (%s..)."), argv);
2624 static void
2625 chk_event_num(int etype, au_event_t event)
2627 au_stat_t as;
2629 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2631 if (etype == AC_KERN_EVENT) {
2632 if (event > as.as_numevent) {
2633 exit_error(gettext(
2634 "Invalid kernel audit event number specified.\n"
2635 "\t%hu is outside allowable range 0-%d."),
2636 event, as.as_numevent);
2638 } else {
2639 /* user event */
2640 if (event <= as.as_numevent) {
2641 exit_error(gettext("Invalid user level audit event "
2642 "number specified %hu."), event);
2647 static void
2648 chk_event_str(int etype, char *event_str)
2650 au_event_ent_t *evp;
2651 au_stat_t as;
2653 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2655 evp = egetauevnam(event_str);
2656 if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) {
2657 exit_error(gettext(
2658 "Invalid kernel audit event string specified.\n"
2659 "\t\"%s\" appears to be a user level event. "
2660 "Check configuration."), event_str);
2661 } else if (etype == AC_USER_EVENT &&
2662 (evp->ae_number < as.as_numevent)) {
2663 exit_error(gettext(
2664 "Invalid user audit event string specified.\n"
2665 "\t\"%s\" appears to be a kernel event. "
2666 "Check configuration."), event_str);
2670 static void
2671 chk_known_plugin(char *plugin_str)
2673 if ((strlen(plugin_str) + 1) > PLUGIN_MAXBUF) {
2674 exit_error(gettext("Plugin name too long.\n"));
2677 if (!plugin_avail_scf(plugin_str)) {
2678 exit_error(gettext("No such plugin configured: %s"),
2679 plugin_str);
2683 static void
2684 chk_sorf(char *sorf_str)
2686 if (!strisnum(sorf_str))
2687 exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
2690 static void
2691 chk_retval(char *retval_str)
2693 if (!strisnum(retval_str))
2694 exit_error(gettext("Invalid retval specified: %s"), retval_str);
2697 static void
2698 execit(char **argv)
2700 char *args, *args_pos;
2701 size_t len = 0;
2702 size_t n = 0;
2703 char **argv_pos;
2705 if (*argv) {
2706 /* concatenate argument array to be passed to sh -c "..." */
2707 for (argv_pos = argv; *argv_pos; argv_pos++)
2708 len += strlen(*argv_pos) + 1;
2710 if ((args = malloc(len + 1)) == NULL)
2711 exit_error(
2712 gettext("Allocation for command/arguments failed"));
2714 args_pos = args;
2715 for (argv_pos = argv; *argv_pos; argv_pos++) {
2716 n += snprintf(args_pos, len - n, "%s ", *argv_pos);
2717 args_pos = args + n;
2719 /* strip the last space */
2720 args[strlen(args)] = '\0';
2722 (void) execl("/bin/sh", "sh", "-c", args, NULL);
2723 } else {
2724 (void) execl("/bin/sh", "sh", NULL);
2727 exit_error(gettext("exec(2) failed"));
2730 static void
2731 exit_usage(int status)
2733 FILE *fp;
2734 int i;
2736 fp = (status ? stderr : stdout);
2737 (void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
2739 for (i = 0; i < ARG_TBL_SZ; i++) {
2740 /* skip the -t option; it's not a standalone option */
2741 if (arg_table[i].auditconfig_cmd == AC_ARG_SET_TEMPORARY) {
2742 continue;
2745 (void) fprintf(fp, " %s%s%s\n",
2746 arg_table[i].arg_str, arg_table[i].arg_opts,
2747 (arg_table[i].temporary_allowed ? " [-t]" : ""));
2750 exit(status);
2753 static void
2754 print_asid(au_asid_t asid)
2756 (void) printf(gettext("audit session id = %u\n"), asid);
2759 static void
2760 print_auid(au_id_t auid)
2762 struct passwd *pwd;
2763 char *username;
2765 if ((pwd = getpwuid((uid_t)auid)) != NULL)
2766 username = pwd->pw_name;
2767 else
2768 username = gettext("unknown");
2770 (void) printf(gettext("audit id = %s(%d)\n"), username, auid);
2773 static void
2774 print_mask(char *desc, au_mask_t *pmp)
2776 char auflags[512];
2778 if (getauditflagschar(auflags, pmp, NULL) < 0)
2779 (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
2781 (void) printf("%s = %s(0x%x,0x%x)\n",
2782 desc, auflags, pmp->am_success, pmp->am_failure);
2785 static void
2786 print_plugin(char *plugin_name, kva_t *plugin_kva)
2788 char att_str[PLUGIN_MAXATT];
2789 boolean_t plugin_active;
2790 char *active_str;
2791 char *qsize_ptr;
2792 int qsize;
2794 if ((active_str = kva_match(plugin_kva, "active")) == NULL) {
2795 (void) printf(gettext("Audit service configuration error: "
2796 "\"active\" property not found\n"));
2797 return;
2800 plugin_active = (boolean_t)atoi(active_str);
2801 qsize_ptr = kva_match(plugin_kva, "qsize");
2802 qsize = atoi(qsize_ptr == NULL ? "-1" : qsize_ptr);
2804 (void) printf(gettext("Plugin: %s (%s)\n"), plugin_name,
2805 plugin_active ? "active" : "inactive");
2807 free_static_att_kva(plugin_kva);
2809 switch (_kva2str(plugin_kva, att_str, PLUGIN_MAXATT, "=", ";")) {
2810 case 0:
2811 (void) printf(gettext("\tAttributes: %s\n"), att_str);
2812 break;
2813 case 1:
2814 exit_error(gettext("Internal error - buffer size too small."));
2815 break;
2816 default:
2817 exit_error(gettext("Internal error."));
2818 break;
2821 if (qsize != 0) {
2822 (void) printf(gettext("\tQueue size: %d %s\n"), qsize,
2823 qsize == -1 ? "(internal error: value not available)" : "");
2827 static void
2828 print_tid_ex(au_tid_addr_t *tidp)
2830 struct hostent *phe;
2831 char *hostname;
2832 struct in_addr ia;
2833 uint32_t *addr;
2834 int err;
2835 char buf[INET6_ADDRSTRLEN];
2836 char *bufp;
2839 /* IPV6 or IPV4 address */
2840 if (tidp->at_type == AU_IPv4) {
2841 if ((phe = gethostbyaddr((char *)&tidp->at_addr[0],
2842 sizeof (tidp->at_addr[0]), AF_INET)) != NULL) {
2843 hostname = phe->h_name;
2844 } else {
2845 hostname = gettext("unknown");
2848 ia.s_addr = tidp->at_addr[0];
2850 (void) printf(gettext(
2851 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2852 major(tidp->at_port), minor(tidp->at_port),
2853 hostname, inet_ntoa(ia));
2854 } else {
2855 addr = &tidp->at_addr[0];
2856 phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
2858 bzero(buf, sizeof (buf));
2860 (void) inet_ntop(AF_INET6, (void *)addr, buf, sizeof (buf));
2861 if (phe == NULL) {
2862 bufp = gettext("unknown");
2863 } else {
2864 bufp = phe->h_name;
2867 (void) printf(gettext(
2868 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"),
2869 major(tidp->at_port), minor(tidp->at_port),
2870 bufp, buf);
2871 if (phe) {
2872 freehostent(phe);
2877 static int
2878 str2ipaddr(char *s, uint32_t *addr, uint32_t type)
2880 int j, sl;
2881 char *ss;
2882 unsigned int v;
2884 bzero(addr, 16);
2885 if (strisipaddr(s)) {
2886 if (type == AU_IPv4) {
2887 if (inet_pton(AF_INET, s, addr)) {
2888 return (0);
2890 return (1);
2891 } else if (type == AU_IPv6) {
2892 if (inet_pton(AF_INET6, s, addr))
2893 return (0);
2894 return (1);
2896 return (1);
2897 } else {
2898 if (type == AU_IPv4) {
2899 (void) sscanf(s, "%x", &addr[0]);
2900 return (0);
2901 } else if (type == AU_IPv6) {
2902 sl = strlen(s);
2903 ss = s;
2904 for (j = 3; j >= 0; j--) {
2905 if ((sl - 8) <= 0) {
2906 (void) sscanf(s, "%x", &v);
2907 addr[j] = v;
2908 return (0);
2910 ss = &s[sl-8];
2911 (void) sscanf(ss, "%x", &v);
2912 addr[j] = v;
2913 sl -= 8;
2914 *ss = '\0';
2917 return (0);
2921 static int
2922 str2type(char *s, uint_t *type)
2924 if (strcmp(s, "ipv6") == 0) {
2925 *type = AU_IPv6;
2926 return (0);
2928 if (strcmp(s, "ipv4") == 0) {
2929 *type = AU_IPv4;
2930 return (0);
2933 return (1);
2937 * exit_error() - print an error message along with corresponding system error
2938 * number and error message, then exit. Inputs - program error format and
2939 * message.
2941 /*PRINTFLIKE1*/
2942 static void
2943 exit_error(char *fmt, ...)
2945 va_list args;
2947 va_start(args, fmt);
2948 prt_error_va(fmt, args);
2949 va_end(args);
2951 exit(1);