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