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