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