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