1 /* 2 * Copyright (c) 2004 Apple Computer, Inc. 3 * All rights reserved. 4 * 5 * @APPLE_BSD_LICENSE_HEADER_START@ 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * @APPLE_BSD_LICENSE_HEADER_END@ 32 * 33 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#16 $ 34 */ 35 36 #include <sys/types.h> 37 #include <sys/dirent.h> 38 #include <sys/mman.h> 39 #include <sys/queue.h> 40 #include <sys/stat.h> 41 #include <sys/wait.h> 42 43 #include <bsm/audit.h> 44 #include <bsm/audit_uevents.h> 45 #include <bsm/libbsm.h> 46 47 #include <err.h> 48 #include <errno.h> 49 #include <fcntl.h> 50 #include <grp.h> 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <time.h> 54 #include <unistd.h> 55 #include <signal.h> 56 #include <string.h> 57 #include <syslog.h> 58 59 #include "auditd.h" 60 61 #define NA_EVENT_STR_SIZE 25 62 63 static int ret, minval; 64 static char *lastfile = NULL; 65 static int allhardcount = 0; 66 static int triggerfd = 0; 67 static int sigchlds, sigchlds_handled; 68 static int sighups, sighups_handled; 69 static int sigterms, sigterms_handled; 70 static long global_flags; 71 72 static TAILQ_HEAD(, dir_ent) dir_q; 73 74 static int config_audit_controls(void); 75 76 /* 77 * Error starting auditd 78 */ 79 static void 80 fail_exit(void) 81 { 82 83 audit_warn_nostart(); 84 exit(1); 85 } 86 87 /* 88 * Free our local list of directory names. 89 */ 90 static void 91 free_dir_q() 92 { 93 struct dir_ent *dirent; 94 95 while ((dirent = TAILQ_FIRST(&dir_q))) { 96 TAILQ_REMOVE(&dir_q, dirent, dirs); 97 free(dirent->dirname); 98 free(dirent); 99 } 100 } 101 102 /* 103 * Generate the timestamp string. 104 */ 105 static int 106 getTSstr(char *buf, int len) 107 { 108 struct timeval ts; 109 struct timezone tzp; 110 time_t tt; 111 112 if (gettimeofday(&ts, &tzp) != 0) 113 return (-1); 114 tt = (time_t)ts.tv_sec; 115 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt))) 116 return (-1); 117 return (0); 118 } 119 120 /* 121 * Concat the directory name to the given file name. 122 * XXX We should affix the hostname also 123 */ 124 static char * 125 affixdir(char *name, struct dir_ent *dirent) 126 { 127 char *fn; 128 char *curdir; 129 const char *sep = "/"; 130 131 curdir = dirent->dirname; 132 syslog(LOG_DEBUG, "dir = %s", dirent->dirname); 133 134 fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1); 135 if (fn == NULL) 136 return (NULL); 137 strcpy(fn, curdir); 138 strcat(fn, sep); 139 strcat(fn, name); 140 return (fn); 141 } 142 143 /* 144 * Close the previous audit trail file. 145 */ 146 static int 147 close_lastfile(char *TS) 148 { 149 char *ptr; 150 char *oldname; 151 152 if (lastfile != NULL) { 153 oldname = (char *)malloc(strlen(lastfile) + 1); 154 if (oldname == NULL) 155 return (-1); 156 strcpy(oldname, lastfile); 157 158 /* Rename the last file -- append timestamp. */ 159 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) { 160 *ptr = '.'; 161 strcpy(ptr+1, TS); 162 if (rename(oldname, lastfile) != 0) 163 syslog(LOG_ERR, "Could not rename %s to %s", 164 oldname, lastfile); 165 else 166 syslog(LOG_INFO, "renamed %s to %s", 167 oldname, lastfile); 168 } 169 free(lastfile); 170 free(oldname); 171 lastfile = NULL; 172 } 173 return (0); 174 } 175 176 /* 177 * Create the new audit file with appropriate permissions and ownership. Try 178 * to clean up if something goes wrong. 179 */ 180 static int 181 #ifdef AUDIT_REVIEW_GROUP 182 open_trail(const char *fname, uid_t uid, gid_t gid) 183 #else 184 open_trail(const char *fname) 185 #endif 186 { 187 int error, fd; 188 189 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP); 190 if (fd < 0) 191 return (-1); 192 #ifdef AUDIT_REVIEW_GROUP 193 if (fchown(fd, uid, gid) < 0) { 194 error = errno; 195 close(fd); 196 (void)unlink(fname); 197 errno = error; 198 return (-1); 199 } 200 #endif 201 return (fd); 202 } 203 204 /* 205 * Create the new file name, swap with existing audit file. 206 */ 207 static int 208 swap_audit_file(void) 209 { 210 char timestr[2 * POSTFIX_LEN]; 211 char *fn; 212 char TS[POSTFIX_LEN]; 213 struct dir_ent *dirent; 214 #ifdef AUDIT_REVIEW_GROUP 215 struct group *grp; 216 gid_t gid; 217 uid_t uid; 218 #endif 219 int error, fd; 220 221 if (getTSstr(TS, POSTFIX_LEN) != 0) 222 return (-1); 223 224 strcpy(timestr, TS); 225 strcat(timestr, NOT_TERMINATED); 226 227 #ifdef AUDIT_REVIEW_GROUP 228 /* 229 * XXXRW: Currently, this code falls back to the daemon gid, which is 230 * likely the wheel group. Is there a better way to deal with this? 231 */ 232 grp = getgrnam(AUDIT_REVIEW_GROUP); 233 if (grp == NULL) { 234 syslog(LOG_INFO, 235 "Audit review group '%s' not available, using daemon gid", 236 AUDIT_REVIEW_GROUP); 237 gid = -1; 238 } else 239 gid = grp->gr_gid; 240 uid = getuid(); 241 #endif 242 243 /* Try until we succeed. */ 244 while ((dirent = TAILQ_FIRST(&dir_q))) { 245 if ((fn = affixdir(timestr, dirent)) == NULL) { 246 syslog(LOG_INFO, "Failed to swap log at time %s", 247 timestr); 248 return (-1); 249 } 250 251 /* 252 * Create and open the file; then close and pass to the 253 * kernel if all went well. 254 */ 255 syslog(LOG_INFO, "New audit file is %s", fn); 256 #ifdef AUDIT_REVIEW_GROUP 257 fd = open_trail(fn, uid, gid); 258 #else 259 fd = open_trail(fn); 260 #endif 261 if (fd < 0) 262 warn("open(%s)", fn); 263 if (fd >= 0) { 264 error = auditctl(fn); 265 if (error) { 266 syslog(LOG_ERR, 267 "auditctl failed setting log file! : %s", 268 strerror(errno)); 269 close(fd); 270 } else { 271 /* Success. */ 272 close_lastfile(TS); 273 lastfile = fn; 274 close(fd); 275 return (0); 276 } 277 } 278 279 /* 280 * Tell the administrator about lack of permissions for dir. 281 */ 282 audit_warn_getacdir(dirent->dirname); 283 284 /* Try again with a different directory. */ 285 TAILQ_REMOVE(&dir_q, dirent, dirs); 286 free(dirent->dirname); 287 free(dirent); 288 } 289 syslog(LOG_ERR, "Log directories exhausted\n"); 290 return (-1); 291 } 292 293 /* 294 * Read the audit_control file contents. 295 */ 296 static int 297 read_control_file(void) 298 { 299 char cur_dir[MAXNAMLEN]; 300 struct dir_ent *dirent; 301 au_qctrl_t qctrl; 302 303 /* 304 * Clear old values. Force a re-read of the file the next time. 305 */ 306 free_dir_q(); 307 endac(); 308 309 /* 310 * Read the list of directories into a local linked list. 311 * 312 * XXX We should use the reentrant interfaces once they are 313 * available. 314 */ 315 while (getacdir(cur_dir, MAXNAMLEN) >= 0) { 316 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent)); 317 if (dirent == NULL) 318 return (-1); 319 dirent->softlim = 0; 320 dirent->dirname = (char *) malloc(MAXNAMLEN); 321 if (dirent->dirname == NULL) { 322 free(dirent); 323 return (-1); 324 } 325 strcpy(dirent->dirname, cur_dir); 326 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 327 } 328 329 allhardcount = 0; 330 if (swap_audit_file() == -1) { 331 syslog(LOG_ERR, "Could not swap audit file"); 332 /* 333 * XXX Faulty directory listing? - user should be given 334 * XXX an opportunity to change the audit_control file 335 * XXX switch to a reduced mode of auditing? 336 */ 337 return (-1); 338 } 339 340 /* 341 * XXX There are synchronization problems here 342 * XXX what should we do if a trigger for the earlier limit 343 * XXX is generated here? 344 */ 345 if (0 == (ret = getacmin(&minval))) { 346 syslog(LOG_DEBUG, "min free = %d\n", minval); 347 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 348 syslog(LOG_ERR, 349 "could not get audit queue settings"); 350 return (-1); 351 } 352 qctrl.aq_minfree = minval; 353 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 354 syslog(LOG_ERR, 355 "could not set audit queue settings"); 356 return (-1); 357 } 358 } 359 360 return (0); 361 } 362 363 /* 364 * Close all log files, control files, and tell the audit system. 365 */ 366 static int 367 close_all(void) 368 { 369 int err_ret = 0; 370 char TS[POSTFIX_LEN]; 371 int aufd; 372 token_t *tok; 373 long cond; 374 375 /* Generate an audit record. */ 376 if ((aufd = au_open()) == -1) 377 syslog(LOG_ERR, "Could not create audit shutdown event."); 378 else { 379 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL) 380 au_write(aufd, tok); 381 if (au_close(aufd, 1, AUE_audit_shutdown) == -1) 382 syslog(LOG_ERR, 383 "Could not close audit shutdown event."); 384 } 385 386 /* Flush contents. */ 387 cond = AUC_DISABLED; 388 err_ret = auditon(A_SETCOND, &cond, sizeof(cond)); 389 if (err_ret != 0) { 390 syslog(LOG_ERR, "Disabling audit failed! : %s", 391 strerror(errno)); 392 err_ret = 1; 393 } 394 if (getTSstr(TS, POSTFIX_LEN) == 0) 395 close_lastfile(TS); 396 if (lastfile != NULL) 397 free(lastfile); 398 399 free_dir_q(); 400 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) { 401 syslog(LOG_ERR, "Could not unregister"); 402 audit_warn_postsigterm(); 403 return (1); 404 } 405 endac(); 406 407 if (close(triggerfd) != 0) 408 syslog(LOG_ERR, "Error closing control file"); 409 syslog(LOG_INFO, "Finished"); 410 return (0); 411 } 412 413 /* 414 * When we get a signal, we are often not at a clean point. So, little can 415 * be done in the signal handler itself. Instead, we send a message to the 416 * main servicing loop to do proper handling from a non-signal-handler 417 * context. 418 */ 419 static void 420 relay_signal(int signal) 421 { 422 423 if (signal == SIGHUP) 424 sighups++; 425 if (signal == SIGTERM) 426 sigterms++; 427 if (signal == SIGCHLD) 428 sigchlds++; 429 } 430 431 /* 432 * Registering the daemon. 433 */ 434 static int 435 register_daemon(void) 436 { 437 FILE * pidfile; 438 int fd; 439 pid_t pid; 440 441 /* Set up the signal hander. */ 442 if (signal(SIGTERM, relay_signal) == SIG_ERR) { 443 syslog(LOG_ERR, 444 "Could not set signal handler for SIGTERM"); 445 fail_exit(); 446 } 447 if (signal(SIGCHLD, relay_signal) == SIG_ERR) { 448 syslog(LOG_ERR, 449 "Could not set signal handler for SIGCHLD"); 450 fail_exit(); 451 } 452 if (signal(SIGHUP, relay_signal) == SIG_ERR) { 453 syslog(LOG_ERR, 454 "Could not set signal handler for SIGHUP"); 455 fail_exit(); 456 } 457 458 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) { 459 syslog(LOG_ERR, "Could not open PID file"); 460 audit_warn_tmpfile(); 461 return (-1); 462 } 463 464 /* Attempt to lock the pid file; if a lock is present, exit. */ 465 fd = fileno(pidfile); 466 if (flock(fd, LOCK_EX | LOCK_NB) < 0) { 467 syslog(LOG_ERR, 468 "PID file is locked (is another auditd running?)."); 469 audit_warn_ebusy(); 470 return (-1); 471 } 472 473 pid = getpid(); 474 ftruncate(fd, 0); 475 if (fprintf(pidfile, "%u\n", pid) < 0) { 476 /* Should not start the daemon. */ 477 fail_exit(); 478 } 479 480 fflush(pidfile); 481 return (0); 482 } 483 484 /* 485 * Suppress duplicate messages within a 30 second interval. This should be 486 * enough to time to rotate log files without thrashing from soft warnings 487 * generated before the log is actually rotated. 488 */ 489 #define DUPLICATE_INTERVAL 30 490 static void 491 handle_audit_trigger(int trigger) 492 { 493 static int last_trigger; 494 static time_t last_time; 495 struct dir_ent *dirent; 496 497 /* 498 * Suppres duplicate messages from the kernel within the specified 499 * interval. 500 */ 501 struct timeval ts; 502 struct timezone tzp; 503 time_t tt; 504 505 if (gettimeofday(&ts, &tzp) == 0) { 506 tt = (time_t)ts.tv_sec; 507 if ((trigger == last_trigger) && 508 (tt < (last_time + DUPLICATE_INTERVAL))) 509 return; 510 last_trigger = trigger; 511 last_time = tt; 512 } 513 514 /* 515 * Message processing is done here. 516 */ 517 dirent = TAILQ_FIRST(&dir_q); 518 switch(trigger) { 519 520 case AUDIT_TRIGGER_LOW_SPACE: 521 syslog(LOG_INFO, "Got low space trigger"); 522 if (dirent && (dirent->softlim != 1)) { 523 TAILQ_REMOVE(&dir_q, dirent, dirs); 524 /* Add this node to the end of the list. */ 525 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 526 audit_warn_soft(dirent->dirname); 527 dirent->softlim = 1; 528 529 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL && 530 swap_audit_file() == -1) 531 syslog(LOG_ERR, "Error swapping audit file"); 532 533 /* 534 * Check if the next dir has already reached its soft 535 * limit. 536 */ 537 dirent = TAILQ_FIRST(&dir_q); 538 if (dirent->softlim == 1) { 539 /* All dirs have reached their soft limit. */ 540 audit_warn_allsoft(); 541 } 542 } else { 543 /* 544 * Continue auditing to the current file. Also 545 * generate an allsoft warning. 546 * XXX do we want to do this ? 547 */ 548 audit_warn_allsoft(); 549 } 550 break; 551 552 case AUDIT_TRIGGER_NO_SPACE: 553 syslog(LOG_INFO, "Got no space trigger"); 554 555 /* Delete current dir, go on to next. */ 556 TAILQ_REMOVE(&dir_q, dirent, dirs); 557 audit_warn_hard(dirent->dirname); 558 free(dirent->dirname); 559 free(dirent); 560 561 if (swap_audit_file() == -1) 562 syslog(LOG_ERR, "Error swapping audit file"); 563 564 /* We are out of log directories. */ 565 audit_warn_allhard(++allhardcount); 566 break; 567 568 case AUDIT_TRIGGER_OPEN_NEW: 569 /* 570 * Create a new file and swap with the one being used in 571 * kernel 572 */ 573 syslog(LOG_INFO, "Got open new trigger"); 574 if (swap_audit_file() == -1) 575 syslog(LOG_ERR, "Error swapping audit file"); 576 break; 577 578 case AUDIT_TRIGGER_READ_FILE: 579 syslog(LOG_INFO, "Got read file trigger"); 580 if (read_control_file() == -1) 581 syslog(LOG_ERR, "Error in audit control file"); 582 if (config_audit_controls() == -1) 583 syslog(LOG_ERR, "Error setting audit controls"); 584 break; 585 586 default: 587 syslog(LOG_ERR, "Got unknown trigger %d", trigger); 588 break; 589 } 590 } 591 592 static void 593 handle_sighup(void) 594 { 595 596 sighups_handled = sighups; 597 config_audit_controls(); 598 } 599 600 /* 601 * Reap our children. 602 */ 603 static void 604 reap_children(void) 605 { 606 pid_t child; 607 int wstatus; 608 609 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) { 610 if (!wstatus) 611 continue; 612 syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child, 613 ((WIFEXITED(wstatus)) ? "exited with non-zero status" : 614 "exited as a result of signal"), 615 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : 616 WTERMSIG(wstatus))); 617 } 618 } 619 620 static void 621 handle_sigchld(void) 622 { 623 624 sigchlds_handled = sigchlds; 625 reap_children(); 626 } 627 628 /* 629 * Read the control file for triggers/signals and handle appropriately. 630 */ 631 static int 632 wait_for_events(void) 633 { 634 int num; 635 unsigned int trigger; 636 637 for (;;) { 638 num = read(triggerfd, &trigger, sizeof(trigger)); 639 if ((num == -1) && (errno != EINTR)) { 640 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno); 641 return (-1); 642 } 643 if (sigterms != sigterms_handled) { 644 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__); 645 break; 646 } 647 if (sigchlds != sigchlds_handled) { 648 syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__); 649 handle_sigchld(); 650 } 651 if (sighups != sighups_handled) { 652 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__); 653 handle_sighup(); 654 } 655 if ((num == -1) && (errno == EINTR)) 656 continue; 657 if (num == 0) { 658 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__); 659 return (-1); 660 } 661 syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger); 662 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE) 663 break; 664 else 665 handle_audit_trigger(trigger); 666 } 667 return (close_all()); 668 } 669 670 /* 671 * Configure the audit controls in the kernel: the event to class mapping, 672 * kernel preselection mask, etc. 673 */ 674 static int 675 config_audit_controls(void) 676 { 677 au_event_ent_t ev, *evp; 678 au_evclass_map_t evc_map; 679 au_mask_t aumask; 680 int ctr = 0; 681 char naeventstr[NA_EVENT_STR_SIZE]; 682 683 /* 684 * Process the audit event file, obtaining a class mapping for each 685 * event, and send that mapping into the kernel. 686 * XXX There's a risk here that the BSM library will return NULL 687 * for an event when it can't properly map it to a class. In that 688 * case, we will not process any events beyond the one that failed, 689 * but should. We need a way to get a count of the events. 690 */ 691 ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX); 692 ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX); 693 if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) { 694 syslog(LOG_ERR, 695 "Memory allocation error when configuring audit controls."); 696 return (-1); 697 } 698 evp = &ev; 699 setauevent(); 700 while ((evp = getauevent_r(evp)) != NULL) { 701 evc_map.ec_number = evp->ae_number; 702 evc_map.ec_class = evp->ae_class; 703 if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) 704 != 0) 705 syslog(LOG_ERR, 706 "Failed to register class mapping for event %s", 707 evp->ae_name); 708 else 709 ctr++; 710 } 711 endauevent(); 712 free(ev.ae_name); 713 free(ev.ae_desc); 714 if (ctr == 0) 715 syslog(LOG_ERR, "No events to class mappings registered."); 716 else 717 syslog(LOG_DEBUG, "Registered %d event to class mappings.", 718 ctr); 719 720 /* 721 * Get the non-attributable event string and set the kernel mask from 722 * that. 723 */ 724 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) && 725 (getauditflagsbin(naeventstr, &aumask) == 0)) { 726 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))) 727 syslog(LOG_ERR, 728 "Failed to register non-attributable event mask."); 729 else 730 syslog(LOG_DEBUG, 731 "Registered non-attributable event mask."); 732 } else 733 syslog(LOG_ERR, 734 "Failed to obtain non-attributable event mask."); 735 736 /* 737 * Set the audit policy flags based on passed in parameter values. 738 */ 739 if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags))) 740 syslog(LOG_ERR, "Failed to set audit policy."); 741 742 return (0); 743 } 744 745 static void 746 setup(void) 747 { 748 auditinfo_t auinfo; 749 int aufd; 750 token_t *tok; 751 752 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) { 753 syslog(LOG_ERR, "Error opening trigger file"); 754 fail_exit(); 755 } 756 757 /* 758 * To provide event feedback cycles and avoid auditd becoming 759 * stalled if auditing is suspended, auditd and its children run 760 * without their events being audited. We allow the uid, tid, and 761 * mask fields to be implicitly set to zero, but do set the pid. We 762 * run this after opening the trigger device to avoid configuring 763 * audit state without audit present in the system. 764 * 765 * XXXRW: Is there more to it than this? 766 */ 767 bzero(&auinfo, sizeof(auinfo)); 768 auinfo.ai_asid = getpid(); 769 if (setaudit(&auinfo) == -1) { 770 syslog(LOG_ERR, "Error setting audit stat"); 771 fail_exit(); 772 } 773 774 TAILQ_INIT(&dir_q); 775 if (read_control_file() == -1) { 776 syslog(LOG_ERR, "Error reading control file"); 777 fail_exit(); 778 } 779 780 /* Generate an audit record. */ 781 if ((aufd = au_open()) == -1) 782 syslog(LOG_ERR, "Could not create audit startup event."); 783 else { 784 if ((tok = au_to_text("auditd::Audit startup")) != NULL) 785 au_write(aufd, tok); 786 if (au_close(aufd, 1, AUE_audit_startup) == -1) 787 syslog(LOG_ERR, 788 "Could not close audit startup event."); 789 } 790 791 if (config_audit_controls() == 0) 792 syslog(LOG_INFO, "Audit controls init successful"); 793 else 794 syslog(LOG_ERR, "Audit controls init failed"); 795 } 796 797 int 798 main(int argc, char **argv) 799 { 800 int ch; 801 int debug = 0; 802 int rc; 803 804 global_flags |= AUDIT_CNT; 805 while ((ch = getopt(argc, argv, "dhs")) != -1) { 806 switch(ch) { 807 case 'd': 808 /* Debug option. */ 809 debug = 1; 810 break; 811 812 case 's': 813 /* Fail-stop option. */ 814 global_flags &= ~(AUDIT_CNT); 815 break; 816 817 case 'h': 818 /* Halt-stop option. */ 819 global_flags |= AUDIT_AHLT; 820 break; 821 822 case '?': 823 default: 824 (void)fprintf(stderr, 825 "usage: auditd [-h | -s] [-d] \n"); 826 exit(1); 827 } 828 } 829 830 #ifdef LOG_SECURITY 831 openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY); 832 #else 833 openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH); 834 #endif 835 syslog(LOG_INFO, "starting..."); 836 837 if (debug == 0 && daemon(0, 0) == -1) { 838 syslog(LOG_ERR, "Failed to daemonize"); 839 exit(1); 840 } 841 842 if (register_daemon() == -1) { 843 syslog(LOG_ERR, "Could not register as daemon"); 844 exit(1); 845 } 846 847 setup(); 848 849 rc = wait_for_events(); 850 syslog(LOG_INFO, "auditd exiting."); 851 852 exit(rc); 853 } 854