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