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