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 2010 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 if (qctrl.aq_bufsz == 0) { 1795 return; 1796 } 1797 } 1798 1799 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0); 1800 qctrl.aq_bufsz = (size_t)atol(bufsz); 1801 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0); 1802 } 1803 1804 /* 1805 * do_setqctrl() - set the active and configured audit queue write buffer size 1806 * (bytes), hiwater audit record count, lowater audit record count, and wakeup 1807 * interval (ticks); active values can be changed per zone if AUDIT_PERZONE is 1808 * set, else only in global zone. 1809 */ 1810 static void 1811 do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay) 1812 { 1813 struct au_qctrl qctrl; 1814 1815 qctrl.aq_hiwater = (size_t)atol(hiwater); 1816 qctrl.aq_lowater = (size_t)atol(lowater); 1817 qctrl.aq_bufsz = (size_t)atol(bufsz); 1818 qctrl.aq_delay = (clock_t)atol(delay); 1819 1820 if (!temporary_set) { 1821 struct au_qctrl qctrl_act; 1822 1823 if (!do_setqctrl_scf(&qctrl)) { 1824 exit_error(gettext( 1825 "Could not store configuration values.")); 1826 } 1827 1828 eauditon(A_GETQCTRL, (caddr_t)&qctrl_act, 0); 1829 if (qctrl.aq_hiwater == 0) { 1830 qctrl.aq_hiwater = qctrl_act.aq_hiwater; 1831 } 1832 if (qctrl.aq_lowater == 0) { 1833 qctrl.aq_lowater = qctrl_act.aq_lowater; 1834 } 1835 if (qctrl.aq_bufsz == 0) { 1836 qctrl.aq_bufsz = qctrl_act.aq_bufsz; 1837 } 1838 if (qctrl.aq_delay == 0) { 1839 qctrl.aq_delay = qctrl_act.aq_delay; 1840 } 1841 } 1842 1843 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0); 1844 } 1845 1846 /* 1847 * do_setqdelay() - set the active and configured audit queue wakeup interval 1848 * (ticks); active values can be changed per zone if AUDIT_PERZONE is set, else 1849 * only in global zone. 1850 */ 1851 static void 1852 do_setqdelay(char *delay) 1853 { 1854 struct au_qctrl qctrl; 1855 1856 if (!temporary_set) { 1857 qctrl.aq_delay = (clock_t)atol(delay); 1858 if (!do_setqdelay_scf(&qctrl.aq_delay)) { 1859 exit_error(gettext( 1860 "Could not store configuration value.")); 1861 } 1862 if (qctrl.aq_delay == 0) { 1863 return; 1864 } 1865 } 1866 1867 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0); 1868 qctrl.aq_delay = (clock_t)atol(delay); 1869 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0); 1870 } 1871 1872 /* 1873 * do_setqhiwater() - sets the active and configured number of undelivered audit 1874 * records in the audit queue at which audit record generation blocks; active 1875 * values can be changed per zone if AUDIT_PERZONE is set, else only in global 1876 * zone. 1877 */ 1878 static void 1879 do_setqhiwater(char *hiwater) 1880 { 1881 struct au_qctrl qctrl; 1882 1883 if (!temporary_set) { 1884 qctrl.aq_hiwater = (size_t)atol(hiwater); 1885 if (!do_setqhiwater_scf(&qctrl.aq_hiwater)) { 1886 exit_error(gettext( 1887 "Could not store configuration value.")); 1888 } 1889 if (qctrl.aq_hiwater == 0) { 1890 return; 1891 } 1892 } 1893 1894 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0); 1895 qctrl.aq_hiwater = (size_t)atol(hiwater); 1896 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0); 1897 } 1898 1899 /* 1900 * do_setqlowater() - set the active and configured number of undelivered audit 1901 * records in the audit queue at which blocked auditing processes unblock; 1902 * active values can be changed per zone if AUDIT_PERZONE is set, else only in 1903 * global zone. 1904 */ 1905 static void 1906 do_setqlowater(char *lowater) 1907 { 1908 struct au_qctrl qctrl; 1909 1910 if (!temporary_set) { 1911 qctrl.aq_lowater = (size_t)atol(lowater); 1912 if (!do_setqlowater_scf(&qctrl.aq_lowater)) { 1913 exit_error(gettext( 1914 "Could not store configuration value.")); 1915 } 1916 if (qctrl.aq_lowater == 0) { 1917 return; 1918 } 1919 } 1920 1921 eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0); 1922 qctrl.aq_lowater = (size_t)atol(lowater); 1923 eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0); 1924 } 1925 1926 static void 1927 eauditon(int cmd, caddr_t data, int length) 1928 { 1929 if (auditon(cmd, data, length) == -1) 1930 exit_error(gettext("auditon(2) failed.")); 1931 } 1932 1933 static void 1934 egetauid(au_id_t *auid) 1935 { 1936 if (getauid(auid) == -1) 1937 exit_error(gettext("getauid(2) failed.")); 1938 } 1939 1940 static void 1941 egetaudit(auditinfo_addr_t *ai, int size) 1942 { 1943 if (getaudit_addr(ai, size) == -1) 1944 exit_error(gettext("getaudit_addr(2) failed.")); 1945 } 1946 1947 static void 1948 egetkaudit(auditinfo_addr_t *ai, int size) 1949 { 1950 if (auditon(A_GETKAUDIT, (char *)ai, size) < 0) 1951 exit_error(gettext("auditon: A_GETKAUDIT failed.")); 1952 } 1953 1954 static void 1955 esetkaudit(auditinfo_addr_t *ai, int size) 1956 { 1957 if (auditon(A_SETKAUDIT, (char *)ai, size) < 0) 1958 exit_error(gettext("auditon: A_SETKAUDIT failed.")); 1959 } 1960 1961 static void 1962 egetauditflagsbin(char *auditflags, au_mask_t *pmask) 1963 { 1964 pmask->am_success = pmask->am_failure = 0; 1965 1966 if (strcmp(auditflags, "none") == 0) 1967 return; 1968 1969 if (getauditflagsbin(auditflags, pmask) < 0) { 1970 exit_error(gettext("Could not get audit flags (%s)"), 1971 auditflags); 1972 } 1973 } 1974 1975 static au_event_ent_t * 1976 egetauevnum(au_event_t event_number) 1977 { 1978 au_event_ent_t *evp; 1979 1980 if ((evp = getauevnum(event_number)) == NULL) { 1981 exit_error(gettext("Could not get audit event %hu"), 1982 event_number); 1983 } 1984 1985 return (evp); 1986 } 1987 1988 static au_event_ent_t * 1989 egetauevnam(char *event_name) 1990 { 1991 register au_event_ent_t *evp; 1992 1993 if ((evp = getauevnam(event_name)) == NULL) 1994 exit_error(gettext("Could not get audit event %s"), event_name); 1995 1996 return (evp); 1997 } 1998 1999 static void 2000 esetauid(au_id_t *auid) 2001 { 2002 if (setauid(auid) == -1) 2003 exit_error(gettext("setauid(2) failed.")); 2004 } 2005 2006 static void 2007 esetaudit(auditinfo_addr_t *ai, int size) 2008 { 2009 if (setaudit_addr(ai, size) == -1) 2010 exit_error(gettext("setaudit_addr(2) failed.")); 2011 } 2012 2013 static uid_t 2014 get_user_id(char *user) 2015 { 2016 struct passwd *pwd; 2017 uid_t uid; 2018 2019 if (isdigit(*user)) { 2020 uid = atoi(user); 2021 if ((pwd = getpwuid(uid)) == NULL) { 2022 exit_error(gettext("Invalid user: %s"), user); 2023 } 2024 } else { 2025 if ((pwd = getpwnam(user)) == NULL) { 2026 exit_error(gettext("Invalid user: %s"), user); 2027 } 2028 } 2029 2030 return (pwd->pw_uid); 2031 } 2032 2033 /* 2034 * get_arg_ent() 2035 * Inputs: command line argument string 2036 * Returns ptr to struct arg_entry if found; null, if not found 2037 */ 2038 static arg_entry_t * 2039 get_arg_ent(char *arg_str) 2040 { 2041 arg_entry_t key; 2042 2043 key.arg_str = arg_str; 2044 2045 return ((arg_entry_t *)bsearch((char *)&key, (char *)arg_table, 2046 ARG_TBL_SZ, sizeof (arg_entry_t), arg_ent_compare)); 2047 } 2048 2049 /* 2050 * arg_ent_compare() 2051 * Compares two command line arguments to determine which is 2052 * lexicographically greater. 2053 * Inputs: two argument map table entry pointers 2054 * Returns: > 1: aep1->arg_str > aep2->arg_str 2055 * < 1: aep1->arg_str < aep2->arg_str 2056 * 0: aep1->arg_str = aep->arg_str2 2057 */ 2058 static int 2059 arg_ent_compare(const void *aep1, const void *aep2) 2060 { 2061 return (strcmp(((arg_entry_t *)aep1)->arg_str, 2062 ((arg_entry_t *)aep2)->arg_str)); 2063 } 2064 2065 /* 2066 * Convert mask of the following forms: 2067 * 2068 * audit_flags (ie. +lo,-ad,pc) 2069 * 0xffffffff,0xffffffff 2070 * ffffffff,ffffffff 2071 * 20,20 2072 */ 2073 static void 2074 str2mask(char *mask_str, au_mask_t *mp) 2075 { 2076 2077 char sp[256]; 2078 char fp[256]; 2079 2080 mp->am_success = 0; 2081 mp->am_failure = 0; 2082 2083 /* 2084 * a mask of the form +aa,bb,cc,-dd or 2085 * a mask of the form 0xffffffff,0xffffffff or 1,1 2086 */ 2087 if (strisflags(mask_str)) { 2088 egetauditflagsbin(mask_str, mp); 2089 } else { 2090 strsplit(mask_str, sp, fp, ','); 2091 2092 if (strlen(sp) > (size_t)2 && !strncasecmp(sp, "0x", 2)) { 2093 (void) sscanf(sp + 2, "%x", &mp->am_success); 2094 } else { 2095 (void) sscanf(sp, "%u", &mp->am_success); 2096 } 2097 2098 if (strlen(fp) > (size_t)2 && !strncasecmp(fp, "0x", 2)) { 2099 (void) sscanf(fp + 2, "%x", &mp->am_failure); 2100 } else { 2101 (void) sscanf(fp, "%u", &mp->am_failure); 2102 } 2103 } 2104 } 2105 2106 /* 2107 * tid_str is major,minor,host -- host is a name or an ip address 2108 */ 2109 static void 2110 str2tid(char *tid_str, au_tid_addr_t *tp) 2111 { 2112 char *major_str; 2113 char *minor_str; 2114 char *host_str = NULL; 2115 major_t major = 0; 2116 major_t minor = 0; 2117 dev_t dev = 0; 2118 struct hostent *phe; 2119 int err; 2120 uint32_t ibuf; 2121 uint32_t ibuf6[4]; 2122 2123 tp->at_port = 0; 2124 tp->at_type = 0; 2125 bzero(tp->at_addr, 16); 2126 2127 major_str = tid_str; 2128 if ((minor_str = strchr(tid_str, ',')) != NULL) { 2129 *minor_str = '\0'; 2130 minor_str++; 2131 } 2132 2133 if (minor_str) { 2134 if ((host_str = strchr(minor_str, ',')) != NULL) { 2135 *host_str = '\0'; 2136 host_str++; 2137 } 2138 } 2139 2140 if (major_str) 2141 major = (major_t)atoi(major_str); 2142 2143 if (minor_str) 2144 minor = (minor_t)atoi(minor_str); 2145 2146 if ((dev = makedev(major, minor)) != NODEV) 2147 tp->at_port = dev; 2148 2149 if (host_str) { 2150 if (strisipaddr(host_str)) { 2151 if (inet_pton(AF_INET, host_str, &ibuf)) { 2152 tp->at_addr[0] = ibuf; 2153 tp->at_type = AU_IPv4; 2154 } else if (inet_pton(AF_INET6, host_str, ibuf6)) { 2155 tp->at_addr[0] = ibuf6[0]; 2156 tp->at_addr[1] = ibuf6[1]; 2157 tp->at_addr[2] = ibuf6[2]; 2158 tp->at_addr[3] = ibuf6[3]; 2159 tp->at_type = AU_IPv6; 2160 } 2161 } else { 2162 phe = getipnodebyname((const void *)host_str, 2163 AF_INET, 0, &err); 2164 if (phe == 0) { 2165 phe = getipnodebyname((const void *)host_str, 2166 AF_INET6, 0, &err); 2167 } 2168 2169 if (phe != NULL) { 2170 if (phe->h_addrtype == AF_INET6) { 2171 /* address is IPv6 (128 bits) */ 2172 (void) memcpy(&tp->at_addr[0], 2173 phe->h_addr_list[0], 16); 2174 tp->at_type = AU_IPv6; 2175 } else { 2176 /* address is IPv4 (32 bits) */ 2177 (void) memcpy(&tp->at_addr[0], 2178 phe->h_addr_list[0], 4); 2179 tp->at_type = AU_IPv4; 2180 } 2181 freehostent(phe); 2182 } 2183 } 2184 } 2185 } 2186 2187 static char * 2188 cond2str(void) 2189 { 2190 uint_t cond; 2191 2192 eauditon(A_GETCOND, (caddr_t)&cond, (int)sizeof (cond)); 2193 2194 switch (cond) { 2195 2196 case AUC_AUDITING: 2197 return ("auditing"); 2198 2199 case AUC_NOAUDIT: 2200 case AUC_INIT_AUDIT: 2201 return ("noaudit"); 2202 2203 case AUC_UNSET: 2204 return ("unset"); 2205 2206 case AUC_NOSPACE: 2207 return ("nospace"); 2208 2209 default: 2210 return (""); 2211 } 2212 } 2213 2214 /* 2215 * exit = 0, success 2216 * 1, error 2217 * 2, bad zone 2218 */ 2219 static int 2220 str2policy(char *policy_str, uint32_t *policy_mask) 2221 { 2222 char *buf; 2223 char *tok; 2224 char pfix; 2225 boolean_t is_all = B_FALSE; 2226 uint32_t pm = 0; 2227 uint32_t curp; 2228 2229 pfix = *policy_str; 2230 2231 if (pfix == '-' || pfix == '+' || pfix == '=') 2232 ++policy_str; 2233 2234 if ((buf = strdup(policy_str)) == NULL) 2235 return (1); 2236 2237 for (tok = strtok(buf, ","); tok != NULL; tok = strtok(NULL, ",")) { 2238 uint32_t tok_pm; 2239 if (((tok_pm = get_policy(tok)) == 0) && 2240 ((strcasecmp(tok, "none") != 0))) { 2241 free(buf); 2242 return (1); 2243 } else { 2244 pm |= tok_pm; 2245 if (tok_pm == ALL_POLICIES) { 2246 is_all = B_TRUE; 2247 } 2248 } 2249 } 2250 free(buf); 2251 2252 /* reuse policy mask if already set to some value */ 2253 if (*policy_mask != 0) { 2254 curp = *policy_mask; 2255 } else { 2256 (void) auditon(A_GETPOLICY, (caddr_t)&curp, 0); 2257 } 2258 2259 if (pfix == '-') { 2260 if (!is_all && 2261 (getzoneid() != GLOBAL_ZONEID) && 2262 (pm & ~AUDIT_LOCAL)) { 2263 return (2); 2264 } 2265 2266 if (getzoneid() != GLOBAL_ZONEID) 2267 curp &= AUDIT_LOCAL; 2268 *policy_mask = curp & ~pm; 2269 2270 } else if (pfix == '+') { 2271 /* 2272 * In a local zone, accept specifying "all", but not 2273 * individually specifying global-zone only policies. 2274 * Limit to all locally allowed, so system call doesn't 2275 * fail. 2276 */ 2277 if (!is_all && 2278 (getzoneid() != GLOBAL_ZONEID) && 2279 (pm & ~AUDIT_LOCAL)) { 2280 return (2); 2281 } 2282 2283 if (getzoneid() != GLOBAL_ZONEID) { 2284 curp &= AUDIT_LOCAL; 2285 if (is_all) { 2286 pm &= AUDIT_LOCAL; 2287 } 2288 } 2289 *policy_mask = curp | pm; 2290 2291 } else { 2292 /* 2293 * In a local zone, accept specifying "all", but not 2294 * individually specifying global-zone only policies. 2295 * Limit to all locally allowed, so system call doesn't 2296 * fail. 2297 */ 2298 if (!is_all && 2299 (getzoneid() != GLOBAL_ZONEID) && 2300 (pm & ~AUDIT_LOCAL)) { 2301 return (2); 2302 } 2303 2304 if (is_all && (getzoneid() != GLOBAL_ZONEID)) { 2305 pm &= AUDIT_LOCAL; 2306 } 2307 *policy_mask = pm; 2308 } 2309 return (0); 2310 } 2311 2312 static int 2313 policy2str(uint32_t policy, char *policy_str, size_t len) 2314 { 2315 int i, j; 2316 2317 if (policy == ALL_POLICIES) { 2318 (void) strcpy(policy_str, "all"); 2319 return (1); 2320 } 2321 2322 if (policy == NO_POLICIES) { 2323 (void) strcpy(policy_str, "none"); 2324 return (1); 2325 } 2326 2327 *policy_str = '\0'; 2328 2329 for (i = 0, j = 0; i < POLICY_TBL_SZ; i++) { 2330 if (policy & policy_table[i].policy_mask && 2331 policy_table[i].policy_mask != ALL_POLICIES) { 2332 if (j++) { 2333 (void) strcat(policy_str, ","); 2334 } 2335 (void) strlcat(policy_str, policy_table[i].policy_str, 2336 len); 2337 } 2338 } 2339 2340 if (*policy_str) 2341 return (0); 2342 2343 return (1); 2344 } 2345 2346 2347 static int 2348 strisnum(char *s) 2349 { 2350 if (s == NULL || !*s) 2351 return (0); 2352 2353 for (; *s == '-' || *s == '+'; s++) 2354 2355 if (!*s) 2356 return (0); 2357 2358 for (; *s; s++) 2359 if (!isdigit(*s)) 2360 return (0); 2361 2362 return (1); 2363 } 2364 2365 static int 2366 strisflags(char *s) 2367 { 2368 if (s == NULL || !*s) 2369 return (0); 2370 2371 for (; *s; s++) { 2372 if (!isalpha(*s) && 2373 (*s != '+' && *s != '-' && *s != '^' && *s != ',')) 2374 return (0); 2375 } 2376 2377 return (1); 2378 } 2379 2380 static int 2381 strisipaddr(char *s) 2382 { 2383 int dot = 0; 2384 int colon = 0; 2385 2386 /* no string */ 2387 if ((s == NULL) || (!*s)) 2388 return (0); 2389 2390 for (; *s; s++) { 2391 if (!(isxdigit(*s) || *s != '.' || *s != ':')) 2392 return (0); 2393 if (*s == '.') 2394 dot++; 2395 if (*s == ':') 2396 colon++; 2397 } 2398 2399 if (dot && colon) 2400 return (0); 2401 2402 if (!dot && !colon) 2403 return (0); 2404 2405 return (1); 2406 } 2407 2408 static void 2409 strsplit(char *s, char *p1, char *p2, char c) 2410 { 2411 *p1 = *p2 = '\0'; 2412 2413 while (*s != '\0' && *s != c) 2414 *p1++ = *s++; 2415 *p1 = '\0'; 2416 s++; 2417 2418 while (*s != '\0') 2419 *p2++ = *s++; 2420 *p2 = '\0'; 2421 } 2422 2423 static void 2424 chk_event_num(int etype, au_event_t event) 2425 { 2426 au_stat_t as; 2427 2428 eauditon(A_GETSTAT, (caddr_t)&as, 0); 2429 2430 if (etype == AC_KERN_EVENT) { 2431 if (event > as.as_numevent) { 2432 exit_error(gettext( 2433 "Invalid kernel audit event number specified.\n" 2434 "\t%hu is outside allowable range 0-%d."), 2435 event, as.as_numevent); 2436 } 2437 } else { 2438 /* user event */ 2439 if (event <= as.as_numevent) { 2440 exit_error(gettext("Invalid user level audit event " 2441 "number specified %hu."), event); 2442 } 2443 } 2444 } 2445 2446 static void 2447 chk_event_str(int etype, char *event_str) 2448 { 2449 au_event_ent_t *evp; 2450 au_stat_t as; 2451 2452 eauditon(A_GETSTAT, (caddr_t)&as, 0); 2453 2454 evp = egetauevnam(event_str); 2455 if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) { 2456 exit_error(gettext( 2457 "Invalid kernel audit event string specified.\n" 2458 "\t\"%s\" appears to be a user level event. " 2459 "Check configuration."), event_str); 2460 } else if (etype == AC_USER_EVENT && 2461 (evp->ae_number < as.as_numevent)) { 2462 exit_error(gettext( 2463 "Invalid user audit event string specified.\n" 2464 "\t\"%s\" appears to be a kernel event. " 2465 "Check configuration."), event_str); 2466 } 2467 } 2468 2469 static void 2470 chk_sorf(char *sorf_str) 2471 { 2472 if (!strisnum(sorf_str)) 2473 exit_error(gettext("Invalid sorf specified: %s"), sorf_str); 2474 } 2475 2476 static void 2477 chk_retval(char *retval_str) 2478 { 2479 if (!strisnum(retval_str)) 2480 exit_error(gettext("Invalid retval specified: %s"), retval_str); 2481 } 2482 2483 static void 2484 execit(char **argv) 2485 { 2486 char *args, *args_pos; 2487 size_t len = 0; 2488 size_t n = 0; 2489 char **argv_pos; 2490 2491 if (*argv) { 2492 /* concatenate argument array to be passed to sh -c "..." */ 2493 for (argv_pos = argv; *argv_pos; argv_pos++) 2494 len += strlen(*argv_pos) + 1; 2495 2496 if ((args = malloc(len + 1)) == NULL) 2497 exit_error( 2498 gettext("Allocation for command/arguments failed")); 2499 2500 args_pos = args; 2501 for (argv_pos = argv; *argv_pos; argv_pos++) { 2502 n += snprintf(args_pos, len - n, "%s ", *argv_pos); 2503 args_pos = args + n; 2504 } 2505 /* strip the last space */ 2506 args[strlen(args)] = '\0'; 2507 2508 (void) execl("/bin/sh", "sh", "-c", args, NULL); 2509 } else { 2510 (void) execl("/bin/sh", "sh", NULL); 2511 } 2512 2513 exit_error(gettext("exec(2) failed")); 2514 } 2515 2516 static void 2517 exit_usage(int status) 2518 { 2519 FILE *fp; 2520 int i; 2521 2522 fp = (status ? stderr : stdout); 2523 (void) fprintf(fp, gettext("usage: %s option ...\n"), progname); 2524 2525 for (i = 0; i < ARG_TBL_SZ; i++) { 2526 /* skip the -t option; it's not a standalone option */ 2527 if (arg_table[i].auditconfig_cmd == AC_ARG_SET_TEMPORARY) { 2528 continue; 2529 } 2530 2531 (void) fprintf(fp, " %s%s%s\n", 2532 arg_table[i].arg_str, arg_table[i].arg_opts, 2533 (arg_table[i].temporary_allowed ? " [-t]" : "")); 2534 } 2535 2536 exit(status); 2537 } 2538 2539 static void 2540 print_asid(au_asid_t asid) 2541 { 2542 (void) printf(gettext("audit session id = %u\n"), asid); 2543 } 2544 2545 static void 2546 print_auid(au_id_t auid) 2547 { 2548 struct passwd *pwd; 2549 char *username; 2550 2551 if ((pwd = getpwuid((uid_t)auid)) != NULL) 2552 username = pwd->pw_name; 2553 else 2554 username = gettext("unknown"); 2555 2556 (void) printf(gettext("audit id = %s(%d)\n"), username, auid); 2557 } 2558 2559 static void 2560 print_mask(char *desc, au_mask_t *pmp) 2561 { 2562 char auflags[512]; 2563 2564 if (getauditflagschar(auflags, pmp, NULL) < 0) 2565 (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags)); 2566 2567 (void) printf("%s = %s(0x%x,0x%x)\n", 2568 desc, auflags, pmp->am_success, pmp->am_failure); 2569 } 2570 2571 static void 2572 print_tid_ex(au_tid_addr_t *tidp) 2573 { 2574 struct hostent *phe; 2575 char *hostname; 2576 struct in_addr ia; 2577 uint32_t *addr; 2578 int err; 2579 char buf[INET6_ADDRSTRLEN]; 2580 char *bufp; 2581 2582 2583 /* IPV6 or IPV4 address */ 2584 if (tidp->at_type == AU_IPv4) { 2585 if ((phe = gethostbyaddr((char *)&tidp->at_addr[0], 2586 sizeof (tidp->at_addr[0]), AF_INET)) != NULL) { 2587 hostname = phe->h_name; 2588 } else { 2589 hostname = gettext("unknown"); 2590 } 2591 2592 ia.s_addr = tidp->at_addr[0]; 2593 2594 (void) printf(gettext( 2595 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"), 2596 major(tidp->at_port), minor(tidp->at_port), 2597 hostname, inet_ntoa(ia)); 2598 } else { 2599 addr = &tidp->at_addr[0]; 2600 phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err); 2601 2602 bzero(buf, sizeof (buf)); 2603 2604 (void) inet_ntop(AF_INET6, (void *)addr, buf, sizeof (buf)); 2605 if (phe == NULL) { 2606 bufp = gettext("unknown"); 2607 } else { 2608 bufp = phe->h_name; 2609 } 2610 2611 (void) printf(gettext( 2612 "terminal id (maj,min,host) = %lu,%lu,%s(%s)\n"), 2613 major(tidp->at_port), minor(tidp->at_port), 2614 bufp, buf); 2615 if (phe) { 2616 freehostent(phe); 2617 } 2618 } 2619 } 2620 2621 static int 2622 str2ipaddr(char *s, uint32_t *addr, uint32_t type) 2623 { 2624 int j, sl; 2625 char *ss; 2626 unsigned int v; 2627 2628 bzero(addr, 16); 2629 if (strisipaddr(s)) { 2630 if (type == AU_IPv4) { 2631 if (inet_pton(AF_INET, s, addr)) { 2632 return (0); 2633 } 2634 return (1); 2635 } else if (type == AU_IPv6) { 2636 if (inet_pton(AF_INET6, s, addr)) 2637 return (0); 2638 return (1); 2639 } 2640 return (1); 2641 } else { 2642 if (type == AU_IPv4) { 2643 (void) sscanf(s, "%x", &addr[0]); 2644 return (0); 2645 } else if (type == AU_IPv6) { 2646 sl = strlen(s); 2647 ss = s; 2648 for (j = 3; j >= 0; j--) { 2649 if ((sl - 8) <= 0) { 2650 (void) sscanf(s, "%x", &v); 2651 addr[j] = v; 2652 return (0); 2653 } 2654 ss = &s[sl-8]; 2655 (void) sscanf(ss, "%x", &v); 2656 addr[j] = v; 2657 sl -= 8; 2658 *ss = '\0'; 2659 } 2660 } 2661 return (0); 2662 } 2663 } 2664 2665 static int 2666 str2type(char *s, uint_t *type) 2667 { 2668 if (strcmp(s, "ipv6") == 0) { 2669 *type = AU_IPv6; 2670 return (0); 2671 } 2672 if (strcmp(s, "ipv4") == 0) { 2673 *type = AU_IPv4; 2674 return (0); 2675 } 2676 2677 return (1); 2678 } 2679 2680 /* 2681 * exit_error() - print an error message along with corresponding system error 2682 * number and error message, then exit. Inputs - program error format and 2683 * message. 2684 */ 2685 /*PRINTFLIKE1*/ 2686 static void 2687 exit_error(char *fmt, ...) 2688 { 2689 va_list args; 2690 2691 va_start(args, fmt); 2692 prt_error_va(fmt, args); 2693 va_end(args); 2694 2695 exit(1); 2696 } 2697