1 /*- 2 * Copyright (c) 2004-2009 Apple Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/types.h> 31 32 #include <config/config.h> 33 34 #include <sys/dirent.h> 35 #ifdef HAVE_FULL_QUEUE_H 36 #include <sys/queue.h> 37 #else /* !HAVE_FULL_QUEUE_H */ 38 #include <compat/queue.h> 39 #endif /* !HAVE_FULL_QUEUE_H */ 40 #include <sys/mman.h> 41 #include <sys/param.h> 42 #include <sys/stat.h> 43 #include <sys/wait.h> 44 45 #include <bsm/audit.h> 46 #include <bsm/audit_uevents.h> 47 #include <bsm/auditd_lib.h> 48 #include <bsm/libbsm.h> 49 50 #include <err.h> 51 #include <errno.h> 52 #include <fcntl.h> 53 #include <grp.h> 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include <time.h> 57 #include <unistd.h> 58 #include <signal.h> 59 #include <string.h> 60 61 #include "auditd.h" 62 63 #ifndef HAVE_STRLCPY 64 #include <compat/strlcpy.h> 65 #endif 66 67 /* 68 * XXX The following are temporary until these can be added to the kernel 69 * audit.h header. 70 */ 71 #ifndef AUDIT_TRIGGER_INITIALIZE 72 #define AUDIT_TRIGGER_INITIALIZE 7 73 #endif 74 #ifndef AUDIT_TRIGGER_EXPIRE_TRAILS 75 #define AUDIT_TRIGGER_EXPIRE_TRAILS 8 76 #endif 77 78 79 /* 80 * LaunchD flag (Mac OS X and, maybe, FreeBSD only.) See launchd(8) and 81 * http://wiki.freebsd.org/launchd for more information. 82 * 83 * In order for auditd to work "on demand" with launchd(8) it can't: 84 * call daemon(3) 85 * call fork and having the parent process exit 86 * change uids or gids. 87 * set up the current working directory or chroot. 88 * set the session id 89 * change stdio to /dev/null. 90 * call setrusage(2) 91 * call setpriority(2) 92 * Ignore SIGTERM. 93 * auditd (in 'launchd mode') is launched on demand so it must catch 94 * SIGTERM to exit cleanly. 95 */ 96 static int launchd_flag = 0; 97 98 /* 99 * The GID of the audit review group (if used). The audit trail files and 100 * system logs (Mac OS X only) can only be reviewed by members of this group 101 * or the audit administrator (aka. "root"). 102 */ 103 static gid_t audit_review_gid = -1; 104 105 /* 106 * The path and file name of the last audit trail file. 107 */ 108 static char *lastfile = NULL; 109 110 /* 111 * Error starting auditd. Run warn script and exit. 112 */ 113 static void 114 fail_exit(void) 115 { 116 117 audit_warn_nostart(); 118 exit(1); 119 } 120 121 /* 122 * Follow the 'current' symlink to get the active trail file name. 123 */ 124 static char * 125 get_curfile(void) 126 { 127 char *cf; 128 int len; 129 130 cf = malloc(MAXPATHLEN); 131 if (cf == NULL) { 132 auditd_log_err("malloc failed: %m"); 133 return (NULL); 134 } 135 136 len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1); 137 if (len < 0) { 138 free(cf); 139 return (NULL); 140 } 141 142 /* readlink() doesn't terminate string. */ 143 cf[len] = '\0'; 144 145 return (cf); 146 } 147 148 /* 149 * Close the previous audit trail file. 150 */ 151 static int 152 close_lastfile(char *TS) 153 { 154 char *ptr; 155 char *oldname; 156 157 /* If lastfile is NULL try to get it from the 'current' link. */ 158 if (lastfile == NULL) 159 lastfile = get_curfile(); 160 161 if (lastfile != NULL) { 162 oldname = strdup(lastfile); 163 if (oldname == NULL) 164 return (-1); 165 166 /* Rename the last file -- append timestamp. */ 167 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) { 168 memcpy(ptr, TS, POSTFIX_LEN); 169 if (auditd_rename(oldname, lastfile) != 0) 170 auditd_log_err( 171 "Could not rename %s to %s: %m", oldname, 172 lastfile); 173 else { 174 /* 175 * Remove the 'current' symlink since the link 176 * is now invalid. 177 */ 178 (void) unlink(AUDIT_CURRENT_LINK); 179 auditd_log_notice("renamed %s to %s", 180 oldname, lastfile); 181 audit_warn_closefile(lastfile); 182 } 183 } else 184 auditd_log_err("Could not rename %s to %s", oldname, 185 lastfile); 186 free(lastfile); 187 free(oldname); 188 lastfile = NULL; 189 } 190 return (0); 191 } 192 193 /* 194 * Create the new file name, swap with existing audit file. 195 */ 196 static int 197 swap_audit_file(void) 198 { 199 int err; 200 char *newfile, *name; 201 char TS[TIMESTAMP_LEN + 1]; 202 time_t tt; 203 204 if (getTSstr(tt, TS, sizeof(TS)) != 0) 205 return (-1); 206 /* 207 * If prefix and suffix are the same, it means that records are 208 * being produced too fast. We don't want to rename now, because 209 * next trail file can get the same name and once that one is 210 * terminated also within one second it will overwrite the current 211 * one. Just keep writing to the same trail and wait for the next 212 * trigger from the kernel. 213 * FREEBSD KERNEL WAS UPDATED TO KEEP SENDING TRIGGERS, WHICH MIGHT 214 * NOT BE THE CASE FOR OTHER OSES. 215 * If the kernel will not keep sending triggers, trail file will not 216 * be terminated. 217 */ 218 if (lastfile == NULL) { 219 name = NULL; 220 } else { 221 name = strrchr(lastfile, '/'); 222 if (name != NULL) 223 name++; 224 } 225 if (name != NULL && strncmp(name, TS, TIMESTAMP_LEN) == 0) { 226 auditd_log_debug("Not ready to terminate trail file yet."); 227 return (0); 228 } 229 err = auditd_swap_trail(TS, &newfile, audit_review_gid, 230 audit_warn_getacdir); 231 if (err != ADE_NOERR) { 232 auditd_log_err("%s: %m", auditd_strerror(err)); 233 if (err != ADE_ACTL) 234 return (-1); 235 } 236 237 /* 238 * Only close the last file if were in an auditing state before 239 * calling swap_audit_file(). We may need to recover from a crash. 240 */ 241 if (auditd_get_state() == AUD_STATE_ENABLED) 242 close_lastfile(TS); 243 244 245 /* 246 * auditd_swap_trail() potentially enables auditing (if not already 247 * enabled) so updated the cached state as well. 248 */ 249 auditd_set_state(AUD_STATE_ENABLED); 250 251 /* 252 * Create 'current' symlink. Recover from crash, if needed. 253 */ 254 if (auditd_new_curlink(newfile) != 0) 255 auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m", 256 newfile, auditd_strerror(err)); 257 258 lastfile = newfile; 259 auditd_log_notice("New audit file is %s", newfile); 260 261 return (0); 262 } 263 264 /* 265 * Create a new audit log trail file and swap with the current one, if any. 266 */ 267 static int 268 do_trail_file(void) 269 { 270 int err; 271 272 /* 273 * First, refresh the list of audit log directories. 274 */ 275 err = auditd_read_dirs(audit_warn_soft, audit_warn_hard); 276 if (err) { 277 auditd_log_err("auditd_read_dirs(): %s", 278 auditd_strerror(err)); 279 if (err == ADE_HARDLIM) 280 audit_warn_allhard(); 281 if (err != ADE_SOFTLIM) 282 return (-1); 283 else 284 audit_warn_allsoft(); 285 /* continue on with soft limit error */ 286 } 287 288 /* 289 * Create a new file and swap with the one being used in kernel. 290 */ 291 if (swap_audit_file() == -1) { 292 /* 293 * XXX Faulty directory listing? - user should be given 294 * XXX an opportunity to change the audit_control file 295 * XXX switch to a reduced mode of auditing? 296 */ 297 return (-1); 298 } 299 300 /* 301 * Finally, see if there are any trail files to expire. 302 */ 303 err = auditd_expire_trails(audit_warn_expired); 304 if (err) 305 auditd_log_err("auditd_expire_trails(): %s", 306 auditd_strerror(err)); 307 308 return (0); 309 } 310 311 /* 312 * Start up auditing. 313 */ 314 static void 315 audit_setup(void) 316 { 317 int err; 318 319 /* Configure trail files distribution. */ 320 err = auditd_set_dist(); 321 if (err) { 322 auditd_log_err("auditd_set_dist() %s: %m", 323 auditd_strerror(err)); 324 } else 325 auditd_log_debug("Configured trail files distribution."); 326 327 if (do_trail_file() == -1) { 328 auditd_log_err("Error creating audit trail file"); 329 fail_exit(); 330 } 331 332 /* Generate an audit record. */ 333 err = auditd_gen_record(AUE_audit_startup, NULL); 334 if (err) 335 auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m", 336 auditd_strerror(err)); 337 338 if (auditd_config_controls() == 0) 339 auditd_log_info("Audit controls init successful"); 340 else 341 auditd_log_err("Audit controls init failed"); 342 } 343 344 345 /* 346 * Close auditd pid file and trigger mechanism. 347 */ 348 static int 349 close_misc(void) 350 { 351 352 auditd_close_dirs(); 353 if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) { 354 auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE); 355 return (1); 356 } 357 endac(); 358 359 if (auditd_close_trigger() != 0) { 360 auditd_log_err("Error closing trigger messaging mechanism"); 361 return (1); 362 } 363 return (0); 364 } 365 366 /* 367 * Close all log files, control files, and tell the audit system. 368 */ 369 static int 370 close_all(void) 371 { 372 int err_ret = 0; 373 char TS[TIMESTAMP_LEN + 1]; 374 int err; 375 int cond; 376 time_t tt; 377 378 err = auditd_gen_record(AUE_audit_shutdown, NULL); 379 if (err) 380 auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m", 381 auditd_strerror(err)); 382 383 /* Flush contents. */ 384 cond = AUC_DISABLED; 385 err_ret = audit_set_cond(&cond); 386 if (err_ret != 0) { 387 auditd_log_err("Disabling audit failed! : %s", strerror(errno)); 388 err_ret = 1; 389 } 390 391 /* 392 * Updated the cached state that auditing has been disabled. 393 */ 394 auditd_set_state(AUD_STATE_DISABLED); 395 396 if (getTSstr(tt, TS, sizeof(TS)) == 0) 397 close_lastfile(TS); 398 if (lastfile != NULL) 399 free(lastfile); 400 401 err_ret += close_misc(); 402 403 if (err_ret) { 404 auditd_log_err("Could not unregister"); 405 audit_warn_postsigterm(); 406 } 407 408 auditd_log_info("Finished"); 409 return (err_ret); 410 } 411 412 /* 413 * Register the daemon with the signal handler and the auditd pid file. 414 */ 415 static int 416 register_daemon(void) 417 { 418 struct sigaction action; 419 FILE * pidfile; 420 int fd; 421 pid_t pid; 422 423 /* Set up the signal hander. */ 424 action.sa_handler = auditd_relay_signal; 425 /* 426 * sa_flags must not include SA_RESTART, so that read(2) will be 427 * interruptible in auditd_wait_for_events 428 */ 429 action.sa_flags = 0; 430 sigemptyset(&action.sa_mask); 431 if (sigaction(SIGTERM, &action, NULL) != 0) { 432 auditd_log_err( 433 "Could not set signal handler for SIGTERM"); 434 fail_exit(); 435 } 436 if (sigaction(SIGCHLD, &action, NULL) != 0) { 437 auditd_log_err( 438 "Could not set signal handler for SIGCHLD"); 439 fail_exit(); 440 } 441 if (sigaction(SIGHUP, &action, NULL) != 0) { 442 auditd_log_err( 443 "Could not set signal handler for SIGHUP"); 444 fail_exit(); 445 } 446 if (sigaction(SIGALRM, &action, NULL) != 0) { 447 auditd_log_err( 448 "Could not set signal handler for SIGALRM"); 449 fail_exit(); 450 } 451 452 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) { 453 auditd_log_err("Could not open PID file"); 454 audit_warn_tmpfile(); 455 return (-1); 456 } 457 458 /* Attempt to lock the pid file; if a lock is present, exit. */ 459 fd = fileno(pidfile); 460 if (flock(fd, LOCK_EX | LOCK_NB) < 0) { 461 auditd_log_err( 462 "PID file is locked (is another auditd running?)."); 463 audit_warn_ebusy(); 464 return (-1); 465 } 466 467 pid = getpid(); 468 ftruncate(fd, 0); 469 if (fprintf(pidfile, "%u\n", pid) < 0) { 470 /* Should not start the daemon. */ 471 fail_exit(); 472 } 473 474 fflush(pidfile); 475 return (0); 476 } 477 478 /* 479 * Handle the audit trigger event. 480 * 481 * We suppress (ignore) duplicated triggers in close succession in order to 482 * try to avoid thrashing-like behavior. However, not all triggers can be 483 * ignored, as triggers generally represent edge triggers, not level 484 * triggers, and won't be retransmitted if the condition persists. Of 485 * specific concern is the rotate trigger -- if one is dropped, then it will 486 * not be retransmitted, and the log file will grow in an unbounded fashion. 487 */ 488 #define DUPLICATE_INTERVAL 30 489 void 490 auditd_handle_trigger(int trigger) 491 { 492 static int last_trigger, last_warning; 493 static time_t last_time; 494 struct timeval ts; 495 struct timezone tzp; 496 time_t tt; 497 int au_state; 498 int err = 0; 499 500 /* 501 * Suppress duplicate messages from the kernel within the specified 502 * interval. 503 */ 504 if (gettimeofday(&ts, &tzp) == 0) { 505 tt = (time_t)ts.tv_sec; 506 switch (trigger) { 507 case AUDIT_TRIGGER_LOW_SPACE: 508 case AUDIT_TRIGGER_NO_SPACE: 509 /* 510 * Triggers we can suppress. Of course, we also need 511 * to rate limit the warnings, so apply the same 512 * interval limit on syslog messages. 513 */ 514 if ((trigger == last_trigger) && 515 (tt < (last_time + DUPLICATE_INTERVAL))) { 516 if (tt >= (last_warning + DUPLICATE_INTERVAL)) 517 auditd_log_info( 518 "Suppressing duplicate trigger %d", 519 trigger); 520 return; 521 } 522 last_warning = tt; 523 break; 524 525 case AUDIT_TRIGGER_ROTATE_KERNEL: 526 case AUDIT_TRIGGER_ROTATE_USER: 527 case AUDIT_TRIGGER_READ_FILE: 528 case AUDIT_TRIGGER_CLOSE_AND_DIE: 529 case AUDIT_TRIGGER_INITIALIZE: 530 /* 531 * Triggers that we cannot suppress. 532 */ 533 break; 534 } 535 536 /* 537 * Only update last_trigger after aborting due to a duplicate 538 * trigger, not before, or we will never allow that trigger 539 * again. 540 */ 541 last_trigger = trigger; 542 last_time = tt; 543 } 544 545 au_state = auditd_get_state(); 546 547 /* 548 * Message processing is done here. 549 */ 550 switch(trigger) { 551 case AUDIT_TRIGGER_LOW_SPACE: 552 auditd_log_notice("Got low space trigger"); 553 if (do_trail_file() == -1) 554 auditd_log_err("Error swapping audit file"); 555 break; 556 557 case AUDIT_TRIGGER_NO_SPACE: 558 auditd_log_notice("Got no space trigger"); 559 if (do_trail_file() == -1) 560 auditd_log_err("Error swapping audit file"); 561 break; 562 563 case AUDIT_TRIGGER_ROTATE_KERNEL: 564 case AUDIT_TRIGGER_ROTATE_USER: 565 auditd_log_info("Got open new trigger from %s", trigger == 566 AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user"); 567 if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1) 568 auditd_log_err("Error swapping audit file"); 569 break; 570 571 case AUDIT_TRIGGER_READ_FILE: 572 auditd_log_info("Got read file trigger"); 573 if (au_state == AUD_STATE_ENABLED) { 574 if (auditd_config_controls() == -1) 575 auditd_log_err("Error setting audit controls"); 576 else if (do_trail_file() == -1) 577 auditd_log_err("Error swapping audit file"); 578 } 579 break; 580 581 case AUDIT_TRIGGER_CLOSE_AND_DIE: 582 auditd_log_info("Got close and die trigger"); 583 if (au_state == AUD_STATE_ENABLED) 584 err = close_all(); 585 /* 586 * Running under launchd don't exit. Wait for launchd to 587 * send SIGTERM. 588 */ 589 if (!launchd_flag) { 590 auditd_log_info("auditd exiting."); 591 exit (err); 592 } 593 break; 594 595 case AUDIT_TRIGGER_INITIALIZE: 596 auditd_log_info("Got audit initialize trigger"); 597 if (au_state == AUD_STATE_DISABLED) 598 audit_setup(); 599 break; 600 601 case AUDIT_TRIGGER_EXPIRE_TRAILS: 602 auditd_log_info("Got audit expire trails trigger"); 603 err = auditd_expire_trails(audit_warn_expired); 604 if (err) 605 auditd_log_err("auditd_expire_trails(): %s", 606 auditd_strerror(err)); 607 break; 608 609 default: 610 auditd_log_err("Got unknown trigger %d", trigger); 611 break; 612 } 613 } 614 615 /* 616 * Reap our children. 617 */ 618 void 619 auditd_reap_children(void) 620 { 621 pid_t child; 622 int wstatus; 623 624 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) { 625 if (!wstatus) 626 continue; 627 auditd_log_info("warn process [pid=%d] %s %d.", child, 628 ((WIFEXITED(wstatus)) ? "exited with non-zero status" : 629 "exited as a result of signal"), 630 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : 631 WTERMSIG(wstatus))); 632 } 633 } 634 635 /* 636 * Reap any children and terminate. If under launchd don't shutdown auditing 637 * but just the other stuff. 638 */ 639 void 640 auditd_terminate(void) 641 { 642 int ret; 643 644 auditd_reap_children(); 645 646 if (launchd_flag) 647 ret = close_misc(); 648 else 649 ret = close_all(); 650 651 exit(ret); 652 } 653 654 /* 655 * Configure the audit controls in the kernel: the event to class mapping, 656 * kernel preselection mask, etc. 657 */ 658 int 659 auditd_config_controls(void) 660 { 661 int cnt, err; 662 int ret = 0; 663 664 /* 665 * Configure event to class mappings in kernel. 666 */ 667 cnt = auditd_set_evcmap(); 668 if (cnt < 0) { 669 auditd_log_err("auditd_set_evcmap() failed: %m"); 670 ret = -1; 671 } else if (cnt == 0) { 672 auditd_log_err("No events to class mappings registered."); 673 ret = -1; 674 } else 675 auditd_log_debug("Registered %d event to class mappings.", cnt); 676 677 /* 678 * Configure non-attributable event mask in kernel. 679 */ 680 err = auditd_set_namask(); 681 if (err) { 682 auditd_log_err("auditd_set_namask() %s: %m", 683 auditd_strerror(err)); 684 ret = -1; 685 } else 686 auditd_log_debug("Registered non-attributable event mask."); 687 688 /* 689 * Configure audit policy in kernel. 690 */ 691 err = auditd_set_policy(); 692 if (err) { 693 auditd_log_err("auditd_set_policy() %s: %m", 694 auditd_strerror(err)); 695 ret = -1; 696 } else 697 auditd_log_debug("Set audit policy in kernel."); 698 699 /* 700 * Configure audit trail log size in kernel. 701 */ 702 err = auditd_set_fsize(); 703 if (err) { 704 auditd_log_err("audit_set_fsize() %s: %m", 705 auditd_strerror(err)); 706 ret = -1; 707 } else 708 auditd_log_debug("Set audit trail size in kernel."); 709 710 /* 711 * Configure audit trail queue size in kernel. 712 */ 713 err = auditd_set_qsize(); 714 if (err) { 715 auditd_log_err("auditd_set_qsize() %s: %m", 716 auditd_strerror(err)); 717 ret = -1; 718 } else 719 auditd_log_debug("Set audit trail queue in kernel."); 720 721 /* 722 * Configure audit trail volume minimum free percentage of blocks in 723 * kernel. 724 */ 725 err = auditd_set_minfree(); 726 if (err) { 727 auditd_log_err("auditd_set_minfree() %s: %m", 728 auditd_strerror(err)); 729 ret = -1; 730 } else 731 auditd_log_debug( 732 "Set audit trail min free percent in kernel."); 733 734 /* 735 * Configure host address in the audit kernel information. 736 */ 737 err = auditd_set_host(); 738 if (err) { 739 if (err == ADE_PARSE) { 740 auditd_log_notice( 741 "audit_control(5) may be missing 'host:' field"); 742 } else { 743 auditd_log_err("auditd_set_host() %s: %m", 744 auditd_strerror(err)); 745 ret = -1; 746 } 747 } else 748 auditd_log_debug( 749 "Set audit host address information in kernel."); 750 751 return (ret); 752 } 753 754 /* 755 * Setup and initialize auditd. 756 */ 757 static void 758 setup(void) 759 { 760 int err; 761 762 if (auditd_open_trigger(launchd_flag) < 0) { 763 auditd_log_err("Error opening trigger messaging mechanism"); 764 fail_exit(); 765 } 766 767 /* 768 * To prevent event feedback cycles and avoid auditd becoming 769 * stalled if auditing is suspended, auditd and its children run 770 * without their events being audited. We allow the uid, tid, and 771 * mask fields to be implicitly set to zero, but do set the pid. We 772 * run this after opening the trigger device to avoid configuring 773 * audit state without audit present in the system. 774 */ 775 err = auditd_prevent_audit(); 776 if (err) { 777 auditd_log_err("auditd_prevent_audit() %s: %m", 778 auditd_strerror(err)); 779 fail_exit(); 780 } 781 782 /* 783 * Make sure auditd auditing state is correct. 784 */ 785 auditd_set_state(AUD_STATE_INIT); 786 787 /* 788 * If under launchd, don't start auditing. Wait for a trigger to 789 * do so. 790 */ 791 if (!launchd_flag) 792 audit_setup(); 793 } 794 795 int 796 main(int argc, char **argv) 797 { 798 int ch; 799 int debug = 0; 800 #ifdef AUDIT_REVIEW_GROUP 801 struct group *grp; 802 #endif 803 804 while ((ch = getopt(argc, argv, "dl")) != -1) { 805 switch(ch) { 806 case 'd': 807 /* Debug option. */ 808 debug = 1; 809 break; 810 811 case 'l': 812 /* Be launchd friendly. */ 813 launchd_flag = 1; 814 break; 815 816 case '?': 817 default: 818 (void)fprintf(stderr, 819 "usage: auditd [-d] [-l]\n"); 820 exit(1); 821 } 822 } 823 824 audit_review_gid = getgid(); 825 826 #ifdef AUDIT_REVIEW_GROUP 827 /* 828 * XXXRW: Currently, this code falls back to the daemon gid, which is 829 * likely the wheel group. Is there a better way to deal with this? 830 */ 831 grp = getgrnam(AUDIT_REVIEW_GROUP); 832 if (grp != NULL) 833 audit_review_gid = grp->gr_gid; 834 #endif 835 836 auditd_openlog(debug, audit_review_gid); 837 838 if (launchd_flag) 839 auditd_log_info("started by launchd..."); 840 else 841 auditd_log_info("starting..."); 842 843 #ifdef AUDIT_REVIEW_GROUP 844 if (grp == NULL) 845 auditd_log_info( 846 "Audit review group '%s' not available, using daemon gid (%d)", 847 AUDIT_REVIEW_GROUP, audit_review_gid); 848 #endif 849 if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) { 850 auditd_log_err("Failed to daemonize"); 851 exit(1); 852 } 853 854 if (register_daemon() == -1) { 855 auditd_log_err("Could not register as daemon"); 856 exit(1); 857 } 858 859 setup(); 860 861 /* 862 * auditd_wait_for_events() shouldn't return unless something is wrong. 863 */ 864 auditd_wait_for_events(); 865 866 auditd_log_err("abnormal exit."); 867 close_all(); 868 exit(-1); 869 } 870