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 * auditconfig - set and display audit parameters
27 */
28
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>
56
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
107 };
108
109 #define AC_KERN_EVENT 0
110 #define AC_USER_EVENT 1
111
112 #define NONE(s) (!strlen(s) ? gettext("none") : s)
113
114 #define ONEK 1024
115
116 /*
117 * remove this after the audit.h is fixed
118 */
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 */
124 };
125 typedef struct arg_entry arg_entry_t;
126
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},
181 };
182
183 #define ARG_TBL_SZ (sizeof (arg_table) / sizeof (arg_entry_t))
184
185 char *progname = "auditconfig";
186
187 /*
188 * temporary_set true to get/set only kernel settings,
189 * false to get/set kernel settings and service properties
190 */
191 static boolean_t temporary_set = B_FALSE;
192
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);
262
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);
281
282 #if !defined(TEXT_DOMAIN)
283 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
284 #endif
285
286 int
main(int argc,char ** argv)287 main(int argc, char **argv)
288 {
289 au_mask_t mask; /* for options manipulating flags */
290
291 (void) setlocale(LC_ALL, "");
292 (void) textdomain(TEXT_DOMAIN);
293
294 if (argc == 1) {
295 exit_usage(0);
296 }
297
298 if (argc == 2 &&
299 (argv[1][0] == '?' ||
300 strcmp(argv[1], "-h") == 0 ||
301 strcmp(argv[1], "-?") == 0)) {
302 exit_usage(0);
303 }
304
305 parse_args(argc, argv, &mask);
306 do_args(argv, &mask);
307
308 return (0);
309 }
310
311 /*
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.
318 */
319 static void
parse_args(int argc,char ** argv,au_mask_t * mask)320 parse_args(int argc, char **argv, au_mask_t *mask)
321 {
322 arg_entry_t *ae;
323
324 uint_t type;
325 uint_t addr[4];
326
327 for (++argv; *argv; argv++) {
328 if ((ae = get_arg_ent(*argv)) == NULL) {
329 exit_usage(1);
330 }
331
332 switch (ae->auditconfig_cmd) {
333
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);
343 }
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;
356
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;
366
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);
377 }
378 break;
379
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;
387
388 case AC_ARG_GETPLUGIN:
389 if (*++argv == NULL) {
390 --argv;
391 break;
392 }
393 if (get_arg_ent(*argv) != NULL) {
394 --argv;
395 } else {
396 chk_arg_len(*argv, PLUGIN_MAXBUF);
397 chk_known_plugin(*argv);
398 }
399 break;
400
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;
412
413 case AC_ARG_SETASID:
414 case AC_ARG_SETAUID:
415 case AC_ARG_SETAUDIT:
416 ++argv;
417 if (!*argv)
418 exit_usage(1);
419
420 while (*argv)
421 ++argv;
422 --argv;
423
424 break;
425
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);
436
437 if (str2ipaddr(*argv, addr, type))
438 exit_error(
439 gettext("Invalid IP address specified."));
440 break;
441
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;
456
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;
464
465 case AC_ARG_SETKMASK:
466 ++argv;
467 if (!*argv)
468 exit_usage(1);
469 echkflags(*argv, mask);
470 break;
471
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;
479
480 case AC_ARG_SETPLUGIN:
481 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
482 exit_usage(1);
483 }
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);
489 }
490 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
491 --argv;
492 break;
493 }
494 chk_arg_len(*argv, PLUGIN_MAXATT);
495 if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
496 --argv;
497 break;
498 }
499 if (atoi(*argv) < 0) {
500 exit_error(gettext("Incorrect qsize specified "
501 "(%s)."), *argv);
502 }
503 break;
504
505 case AC_ARG_SETPOLICY:
506 ++argv;
507 if (!*argv)
508 exit_usage(1);
509 break;
510
511 case AC_ARG_SETSTAT:
512 break;
513
514 case AC_ARG_GETPINFO:
515 ++argv;
516 if (!*argv)
517 exit_usage(1);
518 break;
519
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;
529
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;
537
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;
562
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;
570
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."));
578 }
579 break;
580
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."));
588 }
589 break;
590
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;
601
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)."));
608 }
609 temporary_set = B_TRUE;
610 break;
611
612 default:
613 exit_error(gettext("Internal error #1."));
614 break;
615 }
616 }
617 }
618
619
620 /*
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.
625 */
626 static void
do_args(char ** argv,au_mask_t * mask)627 do_args(char **argv, au_mask_t *mask)
628 {
629 arg_entry_t *ae;
630
631 for (++argv; *argv; argv++) {
632 ae = get_arg_ent(*argv);
633
634 switch (ae->auditconfig_cmd) {
635
636 case AC_ARG_AUDIT:
637 {
638 char sorf;
639 int retval;
640 char *event_name;
641 char *audit_str;
642
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);
652 }
653 break;
654
655 case AC_ARG_CHKCONF:
656 do_chkconf();
657 break;
658
659 case AC_ARG_CONF:
660 do_conf();
661 break;
662
663 case AC_ARG_CHKACONF:
664 do_chkaconf();
665 break;
666
667 case AC_ARG_ACONF:
668 do_aconf();
669 break;
670
671 case AC_ARG_GETASID:
672 do_getasid();
673 break;
674
675 case AC_ARG_GETAUID:
676 do_getauid();
677 break;
678
679 case AC_ARG_GETAUDIT:
680 do_getaudit();
681 break;
682
683 case AC_ARG_GETKAUDIT:
684 do_getkaudit();
685 break;
686
687 case AC_ARG_GETCLASS:
688 case AC_ARG_GETESTATE:
689 ++argv;
690 do_getclass(*argv);
691 break;
692
693 case AC_ARG_GETCAR:
694 do_getcar();
695 break;
696
697 case AC_ARG_GETCOND:
698 do_getcond();
699 break;
700
701 case AC_ARG_GETCWD:
702 do_getcwd();
703 break;
704
705 case AC_ARG_GETFLAGS:
706 do_getflags();
707 break;
708
709 case AC_ARG_GETKMASK:
710 do_getkmask();
711 break;
712
713 case AC_ARG_GETNAFLAGS:
714 do_getnaflags();
715 break;
716
717 case AC_ARG_GETPLUGIN:
718 {
719 char *plugin_str = NULL;
720
721 ++argv;
722 if (*argv != NULL) {
723 if (get_arg_ent(*argv) != NULL) {
724 --argv;
725 } else {
726 plugin_str = *argv;
727 }
728 } else {
729 --argv;
730 }
731
732 do_getplugin(plugin_str);
733 }
734 break;
735
736 case AC_ARG_GETPOLICY:
737 do_getpolicy();
738 break;
739
740 case AC_ARG_GETQBUFSZ:
741 do_getqbufsz();
742 break;
743
744 case AC_ARG_GETQCTRL:
745 do_getqctrl();
746 break;
747
748 case AC_ARG_GETQDELAY:
749 do_getqdelay();
750 break;
751
752 case AC_ARG_GETQHIWATER:
753 do_getqhiwater();
754 break;
755
756 case AC_ARG_GETQLOWATER:
757 do_getqlowater();
758 break;
759
760 case AC_ARG_GETSTAT:
761 do_getstat();
762 break;
763
764 case AC_ARG_GETTERMID:
765 do_gettermid();
766 break;
767
768 case AC_ARG_LSEVENT:
769 do_lsevent();
770 break;
771
772 case AC_ARG_LSPOLICY:
773 do_lspolicy();
774 break;
775
776 case AC_ARG_SETASID:
777 {
778 char *sid_str;
779
780 ++argv;
781 sid_str = *argv;
782 ++argv;
783 do_setasid(sid_str, argv);
784 }
785 break;
786
787 case AC_ARG_SETAUID:
788 {
789 char *user;
790
791 ++argv;
792 user = *argv;
793 ++argv;
794 do_setauid(user, argv);
795 }
796 break;
797
798 case AC_ARG_SETAUDIT:
799 {
800 char *user_str;
801 char *mask_str;
802 char *tid_str;
803 char *sid_str;
804
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);
816 }
817 break;
818
819 case AC_ARG_SETKAUDIT:
820 {
821 char *address_type, *address;
822
823 ++argv; address_type = *argv;
824 ++argv; address = *argv;
825 do_setkaudit(address_type, address);
826 }
827 break;
828
829 case AC_ARG_SETCLASS:
830 {
831 char *event_str;
832
833 ++argv;
834 event_str = *argv;
835 do_setclass(event_str, mask);
836
837 ++argv;
838 }
839 break;
840
841 case AC_ARG_SETFLAGS:
842 ++argv;
843 do_setflags(*argv, mask);
844 break;
845
846 case AC_ARG_SETKMASK:
847 ++argv;
848 do_setkmask(mask);
849 break;
850
851 case AC_ARG_SETNAFLAGS:
852 ++argv;
853 do_setnaflags(*argv, mask);
854 break;
855
856 case AC_ARG_SETPLUGIN:
857 {
858 char *plugin_str = NULL;
859 boolean_t plugin_state = B_FALSE;
860 char *plugin_att = NULL;
861 int plugin_qsize = -1;
862
863 plugin_str = *++argv;
864 if (strcmp(*++argv, "active") == 0) {
865 plugin_state = B_TRUE;
866 }
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;
875 }
876 } else {
877 --argv;
878 }
879
880 do_setplugin(plugin_str, plugin_state,
881 plugin_att, plugin_qsize);
882 }
883 break;
884
885 case AC_ARG_SETPOLICY:
886 ++argv;
887 do_setpolicy(*argv);
888 break;
889
890 case AC_ARG_GETPINFO:
891 {
892 char *pid_str;
893
894 ++argv;
895 pid_str = *argv;
896 do_getpinfo(pid_str);
897 }
898 break;
899
900 case AC_ARG_SETPMASK:
901 {
902 char *pid_str;
903
904 ++argv;
905 pid_str = *argv;
906 do_setpmask(pid_str, mask);
907
908 ++argv;
909 }
910 break;
911
912 case AC_ARG_SETSTAT:
913 do_setstat();
914 break;
915
916 case AC_ARG_SETQBUFSZ:
917 ++argv;
918 do_setqbufsz(*argv);
919 break;
920
921 case AC_ARG_SETQCTRL:
922 {
923 char *hiwater, *lowater, *bufsz, *delay;
924
925 ++argv; hiwater = *argv;
926 ++argv; lowater = *argv;
927 ++argv; bufsz = *argv;
928 ++argv; delay = *argv;
929 do_setqctrl(hiwater, lowater, bufsz, delay);
930 }
931 break;
932 case AC_ARG_SETQDELAY:
933 ++argv;
934 do_setqdelay(*argv);
935 break;
936
937 case AC_ARG_SETQHIWATER:
938 ++argv;
939 do_setqhiwater(*argv);
940 break;
941
942 case AC_ARG_SETQLOWATER:
943 ++argv;
944 do_setqlowater(*argv);
945 break;
946
947 case AC_ARG_SETSMASK:
948 {
949 char *asid_str;
950
951 ++argv;
952 asid_str = *argv;
953 do_setsmask(asid_str, mask);
954
955 ++argv;
956 }
957 break;
958 case AC_ARG_SETUMASK:
959 {
960 char *auid_str;
961
962 ++argv;
963 auid_str = *argv;
964 do_setumask(auid_str, mask);
965
966 ++argv;
967 }
968 break;
969 case AC_ARG_SET_TEMPORARY:
970 break;
971
972 default:
973 exit_error(gettext("Internal error #2."));
974 break;
975 }
976 }
977 }
978
979 /*
980 * do_chkconf() - the returned value is for the global zone unless AUDIT_PERZONE
981 * is set.
982 */
983 static void
do_chkconf(void)984 do_chkconf(void)
985 {
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;
994
995 pmask.am_success = pmask.am_failure = 0;
996 eauditon(A_GETSTAT, (caddr_t)&as, 0);
997
998 setauevent();
999 if (getauevent() == NULL) {
1000 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1001 AUDITEVENTFILE);
1002 }
1003
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);
1027
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));
1035 }
1036 }
1037 }
1038 }
1039 endauevent();
1040 }
1041
1042 /*
1043 * do_conf() - configure the kernel events. The value returned to the user is
1044 * for the global zone unless AUDIT_PERZONE is set.
1045 */
1046 static void
do_conf(void)1047 do_conf(void)
1048 {
1049 register au_event_ent_t *evp;
1050 register int i;
1051 au_evclass_map_t ec;
1052 au_stat_t as;
1053
1054 eauditon(A_GETSTAT, (caddr_t)&as, 0);
1055
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));
1064 }
1065 }
1066 endauevent();
1067 (void) printf(gettext("Configured %d kernel events.\n"), i);
1068
1069 }
1070
1071 /*
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.
1075 */
1076 static void
do_chkaconf(void)1077 do_chkaconf(void)
1078 {
1079 char *namask_cfg;
1080 au_mask_t pmask, kmask;
1081
1082 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1083 exit_error(gettext("Could not get configured value."));
1084 }
1085 egetauditflagsbin(namask_cfg, &pmask);
1086
1087 eauditon(A_GETKMASK, (caddr_t)&kmask, sizeof (kmask));
1088
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);
1097 }
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);
1104 }
1105 free(namask_cfg);
1106 }
1107
1108 /*
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.
1111 */
1112 static void
do_aconf(void)1113 do_aconf(void)
1114 {
1115 au_mask_t namask;
1116 char *namask_cfg;
1117
1118 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1119 exit_error(gettext("Could not get configured value."));
1120 }
1121 egetauditflagsbin(namask_cfg, &namask);
1122 free(namask_cfg);
1123
1124 eauditon(A_SETKMASK, (caddr_t)&namask, sizeof (namask));
1125 (void) printf(gettext("Configured non-attributable event mask.\n"));
1126 }
1127
1128 /*
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.
1133 */
1134 static void
do_audit(char * event,char sorf,int retval,char * audit_str)1135 do_audit(char *event, char sorf, int retval, char *audit_str)
1136 {
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;
1143
1144 egetaudit(&ai, sizeof (ai));
1145
1146 if (strisnum(event)) {
1147 event_num = (au_event_t)atoi(event);
1148 evp = egetauevnum(event_num);
1149 } else {
1150 evp = egetauevnam(event);
1151 }
1152
1153 rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
1154 AU_PRS_USECACHE);
1155
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);
1161 }
1162
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"));
1168 }
1169 if ((tokp = au_to_me()) == NULL) {
1170 exit_error(
1171 gettext("Could not allocate subject token\n"));
1172 }
1173 if (au_write(rd, tokp) == -1) {
1174 exit_error(gettext("Could not construct subject token "
1175 "of audit record\n"));
1176 }
1177 if (is_system_labeled()) {
1178 if ((tokp = au_to_mylabel()) == NULL) {
1179 exit_error(gettext(
1180 "Could not allocate label token\n"));
1181 }
1182 if (au_write(rd, tokp) == -1) {
1183 exit_error(gettext("Could not "
1184 "construct label token of audit record\n"));
1185 }
1186 }
1187
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"));
1203 }
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));
1208 }
1209 }
1210 }
1211
1212 /*
1213 * do_getauid() - print the audit id of the current process.
1214 */
1215 static void
do_getauid(void)1216 do_getauid(void)
1217 {
1218 au_id_t auid;
1219
1220 egetauid(&auid);
1221 print_auid(auid);
1222 }
1223
1224 /*
1225 * do_getaudit() - print the audit characteristics of the current process.
1226 */
1227 static void
do_getaudit(void)1228 do_getaudit(void)
1229 {
1230 auditinfo_addr_t ai;
1231
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);
1237 }
1238
1239 /*
1240 * do_getkaudit() - print the audit characteristics of the current zone.
1241 */
1242 static void
do_getkaudit(void)1243 do_getkaudit(void)
1244 {
1245 auditinfo_addr_t ai;
1246
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);
1252 }
1253
1254 /*
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.
1257 */
1258 static void
do_setkaudit(char * t,char * s)1259 do_setkaudit(char *t, char *s)
1260 {
1261 uint_t type;
1262 auditinfo_addr_t ai;
1263
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));
1269 }
1270
1271 /*
1272 * do_getcar() - print the zone-relative root
1273 */
1274 static void
do_getcar(void)1275 do_getcar(void)
1276 {
1277 char path[MAXPATHLEN];
1278
1279 eauditon(A_GETCAR, (caddr_t)path, sizeof (path));
1280 (void) printf(gettext("current active root = %s\n"), path);
1281 }
1282
1283 /*
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.
1287 */
1288 static void
do_getclass(char * event_str)1289 do_getclass(char *event_str)
1290 {
1291 au_evclass_map_t ec;
1292 au_event_ent_t *evp;
1293 au_event_t event_number;
1294 char *event_name;
1295
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");
1303 }
1304 } else {
1305 event_name = event_str;
1306 if ((evp = egetauevnam(event_str)) != NULL) {
1307 event_number = evp->ae_number;
1308 }
1309 }
1310
1311 ec.ec_number = event_number;
1312 eauditon(A_GETCLASS, (caddr_t)&ec, 0);
1313
1314 (void) printf(gettext("audit class mask for event %s(%hu) = 0x%x\n"),
1315 event_name, event_number, ec.ec_class);
1316 }
1317
1318 /*
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)
1322 */
1323 static void
do_getcond(void)1324 do_getcond(void)
1325 {
1326 (void) printf(gettext("audit condition = %s\n"), cond2str());
1327 }
1328
1329 /*
1330 * do_getcwd() - the printed path is relative to the current zone root
1331 */
1332 static void
do_getcwd(void)1333 do_getcwd(void)
1334 {
1335 char path[MAXPATHLEN];
1336
1337 eauditon(A_GETCWD, (caddr_t)path, sizeof (path));
1338 (void) printf(gettext("current working directory = %s\n"), path);
1339 }
1340
1341 /*
1342 * do_getflags() - the printed value is for the global zone unless AUDIT_PERZONE
1343 * is set.
1344 */
1345 static void
do_getflags(void)1346 do_getflags(void)
1347 {
1348 au_mask_t amask;
1349 char *amask_cfg;
1350
1351 eauditon(A_GETAMASK, (caddr_t)&amask, sizeof (amask));
1352 print_mask(gettext("active user default audit flags"), &amask);
1353
1354 if (!do_getflags_scf(&amask_cfg) || amask_cfg == NULL) {
1355 exit_error(gettext("Could not get configured value."));
1356 }
1357 egetauditflagsbin(amask_cfg, &amask);
1358 print_mask(gettext("configured user default audit flags"), &amask);
1359 free(amask_cfg);
1360 }
1361
1362 /*
1363 * do_getkmask() - the printed value is for the global zone unless AUDIT_PERZONE
1364 * is set.
1365 */
1366 static void
do_getkmask(void)1367 do_getkmask(void)
1368 {
1369 au_mask_t pmask;
1370
1371 eauditon(A_GETKMASK, (caddr_t)&pmask, sizeof (pmask));
1372 print_mask(gettext("active non-attributable audit flags"), &pmask);
1373 }
1374
1375 /*
1376 * do_getnaflags() - the printed value is for the global zone unless
1377 * AUDIT_PERZONE is set.
1378 */
1379 static void
do_getnaflags(void)1380 do_getnaflags(void)
1381 {
1382 au_mask_t namask;
1383 char *namask_cfg;
1384
1385 eauditon(A_GETKMASK, (caddr_t)&namask, sizeof (namask));
1386 print_mask(gettext("active non-attributable audit flags"), &namask);
1387
1388 if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
1389 exit_error(gettext("Could not get configured value."));
1390 }
1391 egetauditflagsbin(namask_cfg, &namask);
1392 print_mask(gettext("configured non-attributable audit flags"), &namask);
1393 free(namask_cfg);
1394 }
1395
1396 /*
1397 * do_getpolicy() - print active and configured kernel audit policy relative to
1398 * the current zone.
1399 */
1400 static void
do_getpolicy(void)1401 do_getpolicy(void)
1402 {
1403 char policy_str[1024];
1404 uint32_t policy;
1405
1406 if (!temporary_set) {
1407 if (!do_getpolicy_scf(&policy)) {
1408 exit_error(gettext("Could not get configured values."));
1409 }
1410 (void) policy2str(policy, policy_str, sizeof (policy_str));
1411 (void) printf(gettext("configured audit policies = %s\n"),
1412 policy_str);
1413 }
1414
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);
1418 }
1419
1420
1421 /*
1422 * do_getpinfo() - print the audit ID, preselection mask, terminal ID, and
1423 * audit session ID for the specified process.
1424 */
1425 static void
do_getpinfo(char * pid_str)1426 do_getpinfo(char *pid_str)
1427 {
1428 struct auditpinfo_addr ap;
1429
1430 if (strisnum(pid_str))
1431 ap.ap_pid = (pid_t)atoi(pid_str);
1432 else
1433 exit_usage(1);
1434
1435 eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
1436
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);
1441 }
1442
1443 /*
1444 * do_getplugin() - print plugin configuration.
1445 */
1446 static void
do_getplugin(char * plugin_str)1447 do_getplugin(char *plugin_str)
1448 {
1449 scf_plugin_kva_node_t *plugin_kva_ll;
1450 scf_plugin_kva_node_t *plugin_kva_ll_head;
1451
1452 if (!do_getpluginconfig_scf(plugin_str, &plugin_kva_ll)) {
1453 exit_error(gettext("Could not get plugin configuration."));
1454 }
1455
1456 plugin_kva_ll_head = plugin_kva_ll;
1457
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");
1464 }
1465 }
1466 plugin_kva_ll_free(plugin_kva_ll_head);
1467 }
1468
1469 /*
1470 * do_getqbufsz() - print the active and configured audit queue write buffer
1471 * size relative to the current zone.
1472 */
1473 static void
do_getqbufsz(void)1474 do_getqbufsz(void)
1475 {
1476 struct au_qctrl qctrl;
1477
1478 if (!temporary_set) {
1479 if (!do_getqbufsz_scf(&qctrl.aq_bufsz)) {
1480 exit_error(gettext("Could not get configured value."));
1481 }
1482
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);
1489 }
1490 }
1491
1492 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1493 (void) printf(gettext("active audit queue buffer size (bytes) = %d\n"),
1494 qctrl.aq_bufsz);
1495 }
1496
1497 /*
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.
1501 */
1502 static void
do_getqctrl(void)1503 do_getqctrl(void)
1504 {
1505 struct au_qctrl qctrl;
1506
1507 if (!temporary_set) {
1508 if (!do_getqctrl_scf(&qctrl)) {
1509 exit_error(gettext("Could not get configured values."));
1510 }
1511
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);
1518 }
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);
1525 }
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);
1532 }
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);
1539 }
1540 }
1541
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);
1551 }
1552
1553 /*
1554 * do_getqdelay() - print, relative to the current zone, the configured and
1555 * active interval at which audit queue is prodded to start output.
1556 */
1557 static void
do_getqdelay(void)1558 do_getqdelay(void)
1559 {
1560 struct au_qctrl qctrl;
1561
1562 if (!temporary_set) {
1563 if (!do_getqdelay_scf(&qctrl.aq_delay)) {
1564 exit_error(gettext("Could not get configured value."));
1565 }
1566
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);
1573 }
1574 }
1575
1576 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1577 (void) printf(gettext("active audit queue delay (ticks) = %ld\n"),
1578 qctrl.aq_delay);
1579 }
1580
1581 /*
1582 * do_getqhiwater() - print, relative to the current zone, the high water
1583 * point in undelivered audit records when audit generation will block.
1584 */
1585 static void
do_getqhiwater(void)1586 do_getqhiwater(void)
1587 {
1588 struct au_qctrl qctrl;
1589
1590 if (!temporary_set) {
1591 if (!do_getqhiwater_scf(&qctrl.aq_hiwater)) {
1592 exit_error(gettext("Could not get configured value."));
1593 }
1594
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);
1601 }
1602 }
1603
1604 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1605 (void) printf(gettext("active audit queue hiwater mark "
1606 "(records) = %d\n"), qctrl.aq_hiwater);
1607 }
1608
1609 /*
1610 * do_getqlowater() - print, relative to the current zone, the low water point
1611 * in undelivered audit records where blocked processes will resume.
1612 */
1613 static void
do_getqlowater(void)1614 do_getqlowater(void)
1615 {
1616 struct au_qctrl qctrl;
1617
1618 if (!temporary_set) {
1619 if (!do_getqlowater_scf(&qctrl.aq_lowater)) {
1620 exit_error(gettext("Could not get configured value."));
1621 }
1622
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);
1629 }
1630 }
1631
1632 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
1633 (void) printf(gettext("active audit queue lowater mark "
1634 "(records) = %d\n"), qctrl.aq_lowater);
1635 }
1636
1637 /*
1638 * do_getasid() - print out the audit session-ID.
1639 */
1640 static void
do_getasid(void)1641 do_getasid(void)
1642 {
1643 auditinfo_addr_t ai;
1644
1645 if (getaudit_addr(&ai, sizeof (ai))) {
1646 exit_error(gettext("getaudit_addr(2) failed"));
1647 }
1648 print_asid(ai.ai_asid);
1649 }
1650
1651 /*
1652 * do_getstat() - the printed statistics are for the entire system unless
1653 * AUDIT_PERZONE is set.
1654 */
1655 static void
do_getstat(void)1656 do_getstat(void)
1657 {
1658 au_stat_t as;
1659 int offset[12]; /* used to line the header up correctly */
1660 char buf[512];
1661
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]));
1677
1678 /*
1679 * TRANSLATION_NOTE
1680 * Print a properly aligned header.
1681 */
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"));
1695
1696 (void) printf("%s\n", buf);
1697 }
1698
1699 /*
1700 * do_gettermid() - print audit terminal ID for current process.
1701 */
1702 static void
do_gettermid(void)1703 do_gettermid(void)
1704 {
1705 auditinfo_addr_t ai;
1706
1707 if (getaudit_addr(&ai, sizeof (ai))) {
1708 exit_error(gettext("getaudit_addr(2) failed"));
1709 }
1710 print_tid_ex(&ai.ai_termid);
1711 }
1712
1713 /*
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.
1717 */
1718 static void
do_lsevent(void)1719 do_lsevent(void)
1720 {
1721 register au_event_ent_t *evp;
1722 au_mask_t pmask;
1723 char auflags[256];
1724
1725 setauevent();
1726 if (getauevent() == NULL) {
1727 exit_error(gettext("NO AUDIT EVENTS: Could not read %s\n."),
1728 AUDITEVENTFILE);
1729 }
1730
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);
1738 }
1739 endauevent();
1740 }
1741
1742 /*
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.
1745 */
1746 static void
do_lspolicy(void)1747 do_lspolicy(void)
1748 {
1749 int i;
1750
1751 /*
1752 * TRANSLATION_NOTE
1753 * Print a properly aligned header.
1754 */
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));
1759 }
1760 }
1761
1762 /*
1763 * do_setasid() - execute shell or cmd with specified session-ID.
1764 */
1765 static void
do_setasid(char * sid_str,char ** argv)1766 do_setasid(char *sid_str, char **argv)
1767 {
1768 struct auditinfo_addr ai;
1769
1770 if (getaudit_addr(&ai, sizeof (ai))) {
1771 exit_error(gettext("getaudit_addr(2) failed"));
1772 }
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"));
1776 }
1777 execit(argv);
1778 }
1779
1780 /*
1781 * do_setaudit() - execute shell or cmd with specified audit characteristics.
1782 */
1783 static void
do_setaudit(char * user_str,char * mask_str,char * tid_str,char * sid_str,char ** argv)1784 do_setaudit(char *user_str, char *mask_str, char *tid_str, char *sid_str,
1785 char **argv)
1786 {
1787 auditinfo_addr_t ai;
1788
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);
1793
1794 esetaudit(&ai, sizeof (ai));
1795 execit(argv);
1796 }
1797
1798 /*
1799 * do_setauid() - execute shell or cmd with specified audit-ID.
1800 */
1801 static void
do_setauid(char * user,char ** argv)1802 do_setauid(char *user, char **argv)
1803 {
1804 au_id_t auid;
1805
1806 auid = get_user_id(user);
1807 esetauid(&auid);
1808 execit(argv);
1809 }
1810
1811 /*
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.
1814 */
1815 static void
do_setpmask(char * pid_str,au_mask_t * mask)1816 do_setpmask(char *pid_str, au_mask_t *mask)
1817 {
1818 struct auditpinfo ap;
1819
1820 if (strisnum(pid_str)) {
1821 ap.ap_pid = (pid_t)atoi(pid_str);
1822 } else {
1823 exit_usage(1);
1824 }
1825
1826 ap.ap_mask.am_success = mask->am_success;
1827 ap.ap_mask.am_failure = mask->am_failure;
1828
1829 eauditon(A_SETPMASK, (caddr_t)&ap, sizeof (ap));
1830 }
1831
1832 /*
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.
1836 */
1837 static void
do_setsmask(char * asid_str,au_mask_t * mask)1838 do_setsmask(char *asid_str, au_mask_t *mask)
1839 {
1840 struct auditinfo ainfo;
1841
1842 if (strisnum(asid_str)) {
1843 ainfo.ai_asid = (au_asid_t)atoi(asid_str);
1844 } else {
1845 exit_usage(1);
1846 }
1847
1848 ainfo.ai_mask.am_success = mask->am_success;
1849 ainfo.ai_mask.am_failure = mask->am_failure;
1850
1851 eauditon(A_SETSMASK, (caddr_t)&ainfo, sizeof (ainfo));
1852 }
1853
1854 /*
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.
1858 */
1859 static void
do_setumask(char * auid_str,au_mask_t * mask)1860 do_setumask(char *auid_str, au_mask_t *mask)
1861 {
1862 struct auditinfo ainfo;
1863
1864 if (strisnum(auid_str)) {
1865 ainfo.ai_auid = (au_id_t)atoi(auid_str);
1866 } else {
1867 exit_usage(1);
1868 }
1869
1870 ainfo.ai_mask.am_success = mask->am_success;
1871 ainfo.ai_mask.am_failure = mask->am_failure;
1872
1873 eauditon(A_SETUMASK, (caddr_t)&ainfo, sizeof (ainfo));
1874 }
1875
1876 /*
1877 * do_setstat() - reset audit statistics counters; local zone use is valid if
1878 * AUDIT_PERZONE is set, otherwise the syscall returns EPERM.
1879 */
1880 static void
do_setstat(void)1881 do_setstat(void)
1882 {
1883 au_stat_t as;
1884
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;
1896
1897 eauditon(A_SETSTAT, (caddr_t)&as, sizeof (as));
1898 (void) printf("%s\n", gettext("audit stats reset"));
1899 }
1900
1901 /*
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.
1905 */
1906 static void
do_setclass(char * event_str,au_mask_t * mask)1907 do_setclass(char *event_str, au_mask_t *mask)
1908 {
1909 au_event_t event;
1910 au_evclass_map_t ec;
1911 au_event_ent_t *evp;
1912
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;
1918 }
1919 }
1920
1921 ec.ec_number = event;
1922 ec.ec_class = (mask->am_success | mask->am_failure);
1923
1924 eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
1925 }
1926
1927 /*
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.
1930 */
1931 static void
do_setflags(char * audit_flags,au_mask_t * amask)1932 do_setflags(char *audit_flags, au_mask_t *amask)
1933 {
1934 eauditon(A_SETAMASK, (caddr_t)amask, sizeof (*amask));
1935
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."));
1939 }
1940 print_mask(gettext("user default audit flags"), amask);
1941 }
1942
1943 /*
1944 * do_setkmask() - set non-attributable audit flags of machine; valid per zone
1945 * if AUDIT_PERZONE is set, else only in global zone.
1946 */
1947 static void
do_setkmask(au_mask_t * pmask)1948 do_setkmask(au_mask_t *pmask)
1949 {
1950 eauditon(A_SETKMASK, (caddr_t)pmask, sizeof (*pmask));
1951 print_mask(gettext("active non-attributable audit flags"), pmask);
1952 }
1953
1954 /*
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.
1957 */
1958 static void
do_setnaflags(char * audit_naflags,au_mask_t * namask)1959 do_setnaflags(char *audit_naflags, au_mask_t *namask)
1960 {
1961 eauditon(A_SETKMASK, (caddr_t)namask, sizeof (*namask));
1962
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."));
1967 }
1968 print_mask(gettext("non-attributable audit flags"), namask);
1969 }
1970
1971 /*
1972 * do_setplugin() - set the given plugin plugin_str configuration values.
1973 */
1974 static void
do_setplugin(char * plugin_str,boolean_t plugin_state,char * plugin_attr,int plugin_qsize)1975 do_setplugin(char *plugin_str, boolean_t plugin_state, char *plugin_attr,
1976 int plugin_qsize)
1977 {
1978 if (!do_setpluginconfig_scf(plugin_str, plugin_state, plugin_attr,
1979 plugin_qsize)) {
1980 exit_error(gettext("Could not set plugin configuration."));
1981 }
1982 }
1983
1984 /*
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.
1988 *
1989 * ahlt and perzone are global zone only. The kernel ensures that a local zone
1990 * can't change ahlt and perzone (EINVAL).
1991 */
1992 static void
do_setpolicy(char * policy_str)1993 do_setpolicy(char *policy_str)
1994 {
1995 uint32_t policy = 0;
1996
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"));
2003 }
2004 (void) str2policy(policy_str, &policy);
2005
2006 if (!do_setpolicy_scf(policy)) {
2007 exit_error(gettext("Could not store "
2008 "configuration values."));
2009 }
2010 }
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;
2021 }
2022 }
2023
2024 /*
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.
2028 */
2029 static void
do_setqbufsz(char * bufsz)2030 do_setqbufsz(char *bufsz)
2031 {
2032 struct au_qctrl qctrl;
2033
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."));
2039 }
2040 if (qctrl.aq_bufsz == 0) {
2041 return;
2042 }
2043 }
2044
2045 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2046 qctrl.aq_bufsz = (size_t)atol(bufsz);
2047 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2048 }
2049
2050 /*
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.
2055 */
2056 static void
do_setqctrl(char * hiwater,char * lowater,char * bufsz,char * delay)2057 do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay)
2058 {
2059 struct au_qctrl qctrl;
2060
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);
2065
2066 if (!temporary_set) {
2067 struct au_qctrl qctrl_act;
2068
2069 if (!do_setqctrl_scf(&qctrl)) {
2070 exit_error(gettext(
2071 "Could not store configuration values."));
2072 }
2073
2074 eauditon(A_GETQCTRL, (caddr_t)&qctrl_act, 0);
2075 if (qctrl.aq_hiwater == 0) {
2076 qctrl.aq_hiwater = qctrl_act.aq_hiwater;
2077 }
2078 if (qctrl.aq_lowater == 0) {
2079 qctrl.aq_lowater = qctrl_act.aq_lowater;
2080 }
2081 if (qctrl.aq_bufsz == 0) {
2082 qctrl.aq_bufsz = qctrl_act.aq_bufsz;
2083 }
2084 if (qctrl.aq_delay == 0) {
2085 qctrl.aq_delay = qctrl_act.aq_delay;
2086 }
2087 }
2088
2089 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2090 }
2091
2092 /*
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.
2096 */
2097 static void
do_setqdelay(char * delay)2098 do_setqdelay(char *delay)
2099 {
2100 struct au_qctrl qctrl;
2101
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."));
2107 }
2108 if (qctrl.aq_delay == 0) {
2109 return;
2110 }
2111 }
2112
2113 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2114 qctrl.aq_delay = (clock_t)atol(delay);
2115 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2116 }
2117
2118 /*
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.
2123 */
2124 static void
do_setqhiwater(char * hiwater)2125 do_setqhiwater(char *hiwater)
2126 {
2127 struct au_qctrl qctrl;
2128
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."));
2134 }
2135 if (qctrl.aq_hiwater == 0) {
2136 return;
2137 }
2138 }
2139
2140 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2141 qctrl.aq_hiwater = (size_t)atol(hiwater);
2142 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2143 }
2144
2145 /*
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.
2150 */
2151 static void
do_setqlowater(char * lowater)2152 do_setqlowater(char *lowater)
2153 {
2154 struct au_qctrl qctrl;
2155
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."));
2161 }
2162 if (qctrl.aq_lowater == 0) {
2163 return;
2164 }
2165 }
2166
2167 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
2168 qctrl.aq_lowater = (size_t)atol(lowater);
2169 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
2170 }
2171
2172 static void
eauditon(int cmd,caddr_t data,int length)2173 eauditon(int cmd, caddr_t data, int length)
2174 {
2175 if (auditon(cmd, data, length) == -1)
2176 exit_error(gettext("auditon(2) failed."));
2177 }
2178
2179 static void
egetauid(au_id_t * auid)2180 egetauid(au_id_t *auid)
2181 {
2182 if (getauid(auid) == -1)
2183 exit_error(gettext("getauid(2) failed."));
2184 }
2185
2186 static void
egetaudit(auditinfo_addr_t * ai,int size)2187 egetaudit(auditinfo_addr_t *ai, int size)
2188 {
2189 if (getaudit_addr(ai, size) == -1)
2190 exit_error(gettext("getaudit_addr(2) failed."));
2191 }
2192
2193 static void
egetkaudit(auditinfo_addr_t * ai,int size)2194 egetkaudit(auditinfo_addr_t *ai, int size)
2195 {
2196 if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
2197 exit_error(gettext("auditon: A_GETKAUDIT failed."));
2198 }
2199
2200 static void
esetkaudit(auditinfo_addr_t * ai,int size)2201 esetkaudit(auditinfo_addr_t *ai, int size)
2202 {
2203 if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
2204 exit_error(gettext("auditon: A_SETKAUDIT failed."));
2205 }
2206
2207 static void
egetauditflagsbin(char * auditflags,au_mask_t * pmask)2208 egetauditflagsbin(char *auditflags, au_mask_t *pmask)
2209 {
2210 if (strcmp(auditflags, "none") == 0) {
2211 pmask->am_success = pmask->am_failure = 0;
2212 return;
2213 }
2214
2215 if (getauditflagsbin(auditflags, pmask) < 0) {
2216 exit_error(gettext("Could not get audit flags (%s)"),
2217 auditflags);
2218 }
2219 }
2220
2221 static void
echkflags(char * auditflags,au_mask_t * mask)2222 echkflags(char *auditflags, au_mask_t *mask)
2223 {
2224 char *err = "";
2225 char *err_ptr;
2226
2227 if (!__chkflags(auditflags, mask, B_FALSE, &err)) {
2228 err_ptr = err;
2229 while (*err_ptr != ',' && *err_ptr != '\0') {
2230 err_ptr++;
2231 }
2232 *err_ptr = '\0';
2233 exit_error(gettext("Unknown audit flags and/or prefixes "
2234 "encountered: %s"), err);
2235 }
2236 }
2237
2238 static au_event_ent_t *
egetauevnum(au_event_t event_number)2239 egetauevnum(au_event_t event_number)
2240 {
2241 au_event_ent_t *evp;
2242
2243 if ((evp = getauevnum(event_number)) == NULL) {
2244 exit_error(gettext("Could not get audit event %hu"),
2245 event_number);
2246 }
2247
2248 return (evp);
2249 }
2250
2251 static au_event_ent_t *
egetauevnam(char * event_name)2252 egetauevnam(char *event_name)
2253 {
2254 register au_event_ent_t *evp;
2255
2256 if ((evp = getauevnam(event_name)) == NULL)
2257 exit_error(gettext("Could not get audit event %s"), event_name);
2258
2259 return (evp);
2260 }
2261
2262 static void
esetauid(au_id_t * auid)2263 esetauid(au_id_t *auid)
2264 {
2265 if (setauid(auid) == -1)
2266 exit_error(gettext("setauid(2) failed."));
2267 }
2268
2269 static void
esetaudit(auditinfo_addr_t * ai,int size)2270 esetaudit(auditinfo_addr_t *ai, int size)
2271 {
2272 if (setaudit_addr(ai, size) == -1)
2273 exit_error(gettext("setaudit_addr(2) failed."));
2274 }
2275
2276 static uid_t
get_user_id(char * user)2277 get_user_id(char *user)
2278 {
2279 struct passwd *pwd;
2280 uid_t uid;
2281
2282 if (isdigit(*user)) {
2283 uid = atoi(user);
2284 if ((pwd = getpwuid(uid)) == NULL) {
2285 exit_error(gettext("Invalid user: %s"), user);
2286 }
2287 } else {
2288 if ((pwd = getpwnam(user)) == NULL) {
2289 exit_error(gettext("Invalid user: %s"), user);
2290 }
2291 }
2292
2293 return (pwd->pw_uid);
2294 }
2295
2296 /*
2297 * get_arg_ent()
2298 * Inputs: command line argument string
2299 * Returns ptr to struct arg_entry if found; null, if not found
2300 */
2301 static arg_entry_t *
get_arg_ent(char * arg_str)2302 get_arg_ent(char *arg_str)
2303 {
2304 arg_entry_t key;
2305
2306 key.arg_str = arg_str;
2307
2308 return ((arg_entry_t *)bsearch((char *)&key, (char *)arg_table,
2309 ARG_TBL_SZ, sizeof (arg_entry_t), arg_ent_compare));
2310 }
2311
2312 /*
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
2320 */
2321 static int
arg_ent_compare(const void * aep1,const void * aep2)2322 arg_ent_compare(const void *aep1, const void *aep2)
2323 {
2324 return (strcmp(((arg_entry_t *)aep1)->arg_str,
2325 ((arg_entry_t *)aep2)->arg_str));
2326 }
2327
2328 /*
2329 * tid_str is major,minor,host -- host is a name or an ip address
2330 */
2331 static void
str2tid(char * tid_str,au_tid_addr_t * tp)2332 str2tid(char *tid_str, au_tid_addr_t *tp)
2333 {
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];
2344
2345 tp->at_port = 0;
2346 tp->at_type = 0;
2347 bzero(tp->at_addr, 16);
2348
2349 major_str = tid_str;
2350 if ((minor_str = strchr(tid_str, ',')) != NULL) {
2351 *minor_str = '\0';
2352 minor_str++;
2353 }
2354
2355 if (minor_str) {
2356 if ((host_str = strchr(minor_str, ',')) != NULL) {
2357 *host_str = '\0';
2358 host_str++;
2359 }
2360 }
2361
2362 if (major_str)
2363 major = (major_t)atoi(major_str);
2364
2365 if (minor_str)
2366 minor = (minor_t)atoi(minor_str);
2367
2368 if ((dev = makedev(major, minor)) != NODEV)
2369 tp->at_port = dev;
2370
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;
2382 }
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);
2389 }
2390
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;
2402 }
2403 freehostent(phe);
2404 }
2405 }
2406 }
2407 }
2408
2409 static char *
cond2str(void)2410 cond2str(void)
2411 {
2412 uint_t cond;
2413
2414 eauditon(A_GETCOND, (caddr_t)&cond, sizeof (cond));
2415
2416 switch (cond) {
2417
2418 case AUC_AUDITING:
2419 return ("auditing");
2420
2421 case AUC_NOAUDIT:
2422 case AUC_INIT_AUDIT:
2423 return ("noaudit");
2424
2425 case AUC_UNSET:
2426 return ("unset");
2427
2428 case AUC_NOSPACE:
2429 return ("nospace");
2430
2431 default:
2432 return ("");
2433 }
2434 }
2435
2436 /*
2437 * exit = 0, success
2438 * 1, error
2439 * 2, bad zone
2440 */
2441 static int
str2policy(char * policy_str,uint32_t * policy_mask)2442 str2policy(char *policy_str, uint32_t *policy_mask)
2443 {
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;
2450
2451 pfix = *policy_str;
2452
2453 if (pfix == '-' || pfix == '+' || pfix == '=')
2454 ++policy_str;
2455
2456 if ((buf = strdup(policy_str)) == NULL)
2457 return (1);
2458
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;
2469 }
2470 }
2471 }
2472 free(buf);
2473
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);
2479 }
2480
2481 if (pfix == '-') {
2482 if (!is_all &&
2483 (getzoneid() != GLOBAL_ZONEID) &&
2484 (pm & ~AUDIT_LOCAL)) {
2485 return (2);
2486 }
2487
2488 if (getzoneid() != GLOBAL_ZONEID)
2489 curp &= AUDIT_LOCAL;
2490 *policy_mask = curp & ~pm;
2491
2492 } else if (pfix == '+') {
2493 /*
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.
2498 */
2499 if (!is_all &&
2500 (getzoneid() != GLOBAL_ZONEID) &&
2501 (pm & ~AUDIT_LOCAL)) {
2502 return (2);
2503 }
2504
2505 if (getzoneid() != GLOBAL_ZONEID) {
2506 curp &= AUDIT_LOCAL;
2507 if (is_all) {
2508 pm &= AUDIT_LOCAL;
2509 }
2510 }
2511 *policy_mask = curp | pm;
2512
2513 } else {
2514 /*
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.
2519 */
2520 if (!is_all &&
2521 (getzoneid() != GLOBAL_ZONEID) &&
2522 (pm & ~AUDIT_LOCAL)) {
2523 return (2);
2524 }
2525
2526 if (is_all && (getzoneid() != GLOBAL_ZONEID)) {
2527 pm &= AUDIT_LOCAL;
2528 }
2529 *policy_mask = pm;
2530 }
2531 return (0);
2532 }
2533
2534 static int
policy2str(uint32_t policy,char * policy_str,size_t len)2535 policy2str(uint32_t policy, char *policy_str, size_t len)
2536 {
2537 int i, j;
2538
2539 if (policy == ALL_POLICIES) {
2540 (void) strcpy(policy_str, "all");
2541 return (1);
2542 }
2543
2544 if (policy == NO_POLICIES) {
2545 (void) strcpy(policy_str, "none");
2546 return (1);
2547 }
2548
2549 *policy_str = '\0';
2550
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, ",");
2556 }
2557 (void) strlcat(policy_str, policy_table[i].policy_str,
2558 len);
2559 }
2560 }
2561
2562 if (*policy_str)
2563 return (0);
2564
2565 return (1);
2566 }
2567
2568
2569 static int
strisnum(char * s)2570 strisnum(char *s)
2571 {
2572 if (s == NULL || !*s)
2573 return (0);
2574
2575 for (; *s == '-' || *s == '+'; s++)
2576
2577 if (!*s)
2578 return (0);
2579
2580 for (; *s; s++)
2581 if (!isdigit(*s))
2582 return (0);
2583
2584 return (1);
2585 }
2586
2587 static int
strisipaddr(char * s)2588 strisipaddr(char *s)
2589 {
2590 int dot = 0;
2591 int colon = 0;
2592
2593 /* no string */
2594 if ((s == NULL) || (!*s))
2595 return (0);
2596
2597 for (; *s; s++) {
2598 if (!(isxdigit(*s) || *s != '.' || *s != ':'))
2599 return (0);
2600 if (*s == '.')
2601 dot++;
2602 if (*s == ':')
2603 colon++;
2604 }
2605
2606 if (dot && colon)
2607 return (0);
2608
2609 if (!dot && !colon)
2610 return (0);
2611
2612 return (1);
2613 }
2614
2615 static void
chk_arg_len(char * argv,uint_t len)2616 chk_arg_len(char *argv, uint_t len)
2617 {
2618 if ((strlen(argv) + 1) > len) {
2619 *(argv + len - 1) = '\0';
2620 exit_error(gettext("Argument too long (%s..)."), argv);
2621 }
2622 }
2623
2624 static void
chk_event_num(int etype,au_event_t event)2625 chk_event_num(int etype, au_event_t event)
2626 {
2627 au_stat_t as;
2628
2629 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2630
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);
2637 }
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);
2643 }
2644 }
2645 }
2646
2647 static void
chk_event_str(int etype,char * event_str)2648 chk_event_str(int etype, char *event_str)
2649 {
2650 au_event_ent_t *evp;
2651 au_stat_t as;
2652
2653 eauditon(A_GETSTAT, (caddr_t)&as, 0);
2654
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);
2667 }
2668 }
2669
2670 static void
chk_known_plugin(char * plugin_str)2671 chk_known_plugin(char *plugin_str)
2672 {
2673 if ((strlen(plugin_str) + 1) > PLUGIN_MAXBUF) {
2674 exit_error(gettext("Plugin name too long.\n"));
2675 }
2676
2677 if (!plugin_avail_scf(plugin_str)) {
2678 exit_error(gettext("No such plugin configured: %s"),
2679 plugin_str);
2680 }
2681 }
2682
2683 static void
chk_sorf(char * sorf_str)2684 chk_sorf(char *sorf_str)
2685 {
2686 if (!strisnum(sorf_str))
2687 exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
2688 }
2689
2690 static void
chk_retval(char * retval_str)2691 chk_retval(char *retval_str)
2692 {
2693 if (!strisnum(retval_str))
2694 exit_error(gettext("Invalid retval specified: %s"), retval_str);
2695 }
2696
2697 static void
execit(char ** argv)2698 execit(char **argv)
2699 {
2700 char *args, *args_pos;
2701 size_t len = 0;
2702 size_t n = 0;
2703 char **argv_pos;
2704
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;
2709
2710 if ((args = malloc(len + 1)) == NULL)
2711 exit_error(
2712 gettext("Allocation for command/arguments failed"));
2713
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;
2718 }
2719 /* strip the last space */
2720 args[strlen(args)] = '\0';
2721
2722 (void) execl("/bin/sh", "sh", "-c", args, NULL);
2723 } else {
2724 (void) execl("/bin/sh", "sh", NULL);
2725 }
2726
2727 exit_error(gettext("exec(2) failed"));
2728 }
2729
2730 static void
exit_usage(int status)2731 exit_usage(int status)
2732 {
2733 FILE *fp;
2734 int i;
2735
2736 fp = (status ? stderr : stdout);
2737 (void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
2738
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;
2743 }
2744
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]" : ""));
2748 }
2749
2750 exit(status);
2751 }
2752
2753 static void
print_asid(au_asid_t asid)2754 print_asid(au_asid_t asid)
2755 {
2756 (void) printf(gettext("audit session id = %u\n"), asid);
2757 }
2758
2759 static void
print_auid(au_id_t auid)2760 print_auid(au_id_t auid)
2761 {
2762 struct passwd *pwd;
2763 char *username;
2764
2765 if ((pwd = getpwuid((uid_t)auid)) != NULL)
2766 username = pwd->pw_name;
2767 else
2768 username = gettext("unknown");
2769
2770 (void) printf(gettext("audit id = %s(%d)\n"), username, auid);
2771 }
2772
2773 static void
print_mask(char * desc,au_mask_t * pmp)2774 print_mask(char *desc, au_mask_t *pmp)
2775 {
2776 char auflags[512];
2777
2778 if (getauditflagschar(auflags, pmp, NULL) < 0)
2779 (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
2780
2781 (void) printf("%s = %s(0x%x,0x%x)\n",
2782 desc, auflags, pmp->am_success, pmp->am_failure);
2783 }
2784
2785 static void
print_plugin(char * plugin_name,kva_t * plugin_kva)2786 print_plugin(char *plugin_name, kva_t *plugin_kva)
2787 {
2788 char att_str[PLUGIN_MAXATT];
2789 boolean_t plugin_active;
2790 char *active_str;
2791 char *qsize_ptr;
2792 int qsize;
2793
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;
2798 }
2799
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);
2803
2804 (void) printf(gettext("Plugin: %s (%s)\n"), plugin_name,
2805 plugin_active ? "active" : "inactive");
2806
2807 free_static_att_kva(plugin_kva);
2808
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;
2819 }
2820
2821 if (qsize != 0) {
2822 (void) printf(gettext("\tQueue size: %d %s\n"), qsize,
2823 qsize == -1 ? "(internal error: value not available)" : "");
2824 }
2825 }
2826
2827 static void
print_tid_ex(au_tid_addr_t * tidp)2828 print_tid_ex(au_tid_addr_t *tidp)
2829 {
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;
2837
2838
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");
2846 }
2847
2848 ia.s_addr = tidp->at_addr[0];
2849
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);
2857
2858 bzero(buf, sizeof (buf));
2859
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;
2865 }
2866
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);
2873 }
2874 }
2875 }
2876
2877 static int
str2ipaddr(char * s,uint32_t * addr,uint32_t type)2878 str2ipaddr(char *s, uint32_t *addr, uint32_t type)
2879 {
2880 int j, sl;
2881 char *ss;
2882 unsigned int v;
2883
2884 bzero(addr, 16);
2885 if (strisipaddr(s)) {
2886 if (type == AU_IPv4) {
2887 if (inet_pton(AF_INET, s, addr)) {
2888 return (0);
2889 }
2890 return (1);
2891 } else if (type == AU_IPv6) {
2892 if (inet_pton(AF_INET6, s, addr))
2893 return (0);
2894 return (1);
2895 }
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);
2909 }
2910 ss = &s[sl-8];
2911 (void) sscanf(ss, "%x", &v);
2912 addr[j] = v;
2913 sl -= 8;
2914 *ss = '\0';
2915 }
2916 }
2917 return (0);
2918 }
2919 }
2920
2921 static int
str2type(char * s,uint_t * type)2922 str2type(char *s, uint_t *type)
2923 {
2924 if (strcmp(s, "ipv6") == 0) {
2925 *type = AU_IPv6;
2926 return (0);
2927 }
2928 if (strcmp(s, "ipv4") == 0) {
2929 *type = AU_IPv4;
2930 return (0);
2931 }
2932
2933 return (1);
2934 }
2935
2936 /*
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.
2940 */
2941 /*PRINTFLIKE1*/
2942 static void
exit_error(char * fmt,...)2943 exit_error(char *fmt, ...)
2944 {
2945 va_list args;
2946
2947 va_start(args, fmt);
2948 prt_error_va(fmt, args);
2949 va_end(args);
2950
2951 exit(1);
2952 }
2953