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#8 $ 34 */ 35 36 #include <sys/dirent.h> 37 #include <sys/mman.h> 38 #include <sys/queue.h> 39 #include <sys/stat.h> 40 #include <sys/types.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 <errno.h> 48 #include <fcntl.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <time.h> 52 #include <unistd.h> 53 #include <signal.h> 54 #include <string.h> 55 #include <syslog.h> 56 57 #include "auditd.h" 58 59 #define NA_EVENT_STR_SIZE 25 60 61 static int ret, minval; 62 static char *lastfile = NULL; 63 static int allhardcount = 0; 64 static int triggerfd = 0; 65 static int sighups, sighups_handled; 66 static int sigterms, sigterms_handled; 67 static long global_flags; 68 69 static TAILQ_HEAD(, dir_ent) dir_q; 70 71 static int config_audit_controls(void); 72 73 /* 74 * Error starting auditd 75 */ 76 static void 77 fail_exit(void) 78 { 79 80 audit_warn_nostart(); 81 exit(1); 82 } 83 84 /* 85 * Free our local list of directory names. 86 */ 87 static void 88 free_dir_q() 89 { 90 struct dir_ent *dirent; 91 92 while ((dirent = TAILQ_FIRST(&dir_q))) { 93 TAILQ_REMOVE(&dir_q, dirent, dirs); 94 free(dirent->dirname); 95 free(dirent); 96 } 97 } 98 99 /* 100 * Generate the timestamp string. 101 */ 102 static int 103 getTSstr(char *buf, int len) 104 { 105 struct timeval ts; 106 struct timezone tzp; 107 time_t tt; 108 109 if (gettimeofday(&ts, &tzp) != 0) 110 return (-1); 111 tt = (time_t)ts.tv_sec; 112 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt))) 113 return (-1); 114 return (0); 115 } 116 117 /* 118 * Concat the directory name to the given file name. 119 * XXX We should affix the hostname also 120 */ 121 static char * 122 affixdir(char *name, struct dir_ent *dirent) 123 { 124 char *fn; 125 char *curdir; 126 const char *sep = "/"; 127 128 curdir = dirent->dirname; 129 syslog(LOG_INFO, "dir = %s\n", dirent->dirname); 130 131 fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1); 132 if (fn == NULL) 133 return (NULL); 134 strcpy(fn, curdir); 135 strcat(fn, sep); 136 strcat(fn, name); 137 return (fn); 138 } 139 140 /* 141 * Close the previous audit trail file. 142 */ 143 static int 144 close_lastfile(char *TS) 145 { 146 char *ptr; 147 char *oldname; 148 149 if (lastfile != NULL) { 150 oldname = (char *)malloc(strlen(lastfile) + 1); 151 if (oldname == NULL) 152 return (-1); 153 strcpy(oldname, lastfile); 154 155 /* Rename the last file -- append timestamp. */ 156 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) { 157 *ptr = '.'; 158 strcpy(ptr+1, TS); 159 if (rename(oldname, lastfile) != 0) 160 syslog(LOG_ERR, "Could not rename %s to %s \n", 161 oldname, lastfile); 162 else 163 syslog(LOG_INFO, "renamed %s to %s \n", 164 oldname, lastfile); 165 } 166 free(lastfile); 167 free(oldname); 168 lastfile = NULL; 169 } 170 return (0); 171 } 172 173 /* 174 * Create the new file name, swap with existing audit file. 175 */ 176 static int 177 swap_audit_file(void) 178 { 179 char timestr[2 * POSTFIX_LEN]; 180 char *fn; 181 char TS[POSTFIX_LEN]; 182 struct dir_ent *dirent; 183 int fd; 184 185 if (getTSstr(TS, POSTFIX_LEN) != 0) 186 return (-1); 187 188 strcpy(timestr, TS); 189 strcat(timestr, NOT_TERMINATED); 190 191 /* Try until we succeed. */ 192 while ((dirent = TAILQ_FIRST(&dir_q))) { 193 if ((fn = affixdir(timestr, dirent)) == NULL) { 194 syslog(LOG_INFO, "Failed to swap log at time %s\n", 195 timestr); 196 return (-1); 197 } 198 199 /* 200 * Create and open the file; then close and pass to the 201 * kernel if all went well. 202 */ 203 syslog(LOG_INFO, "New audit file is %s\n", fn); 204 fd = open(fn, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP); 205 if (fd < 0) 206 perror("File open"); 207 else if (auditctl(fn) != 0) { 208 syslog(LOG_ERR, 209 "auditctl failed setting log file! : %s\n", 210 strerror(errno)); 211 close(fd); 212 } else { 213 /* Success. */ 214 close_lastfile(TS); 215 lastfile = fn; 216 close(fd); 217 return (0); 218 } 219 220 /* 221 * Tell the administrator about lack of permissions for dir. 222 */ 223 audit_warn_getacdir(dirent->dirname); 224 225 /* Try again with a different directory. */ 226 TAILQ_REMOVE(&dir_q, dirent, dirs); 227 free(dirent->dirname); 228 free(dirent); 229 } 230 syslog(LOG_INFO, "Log directories exhausted\n"); 231 return (-1); 232 } 233 234 /* 235 * Read the audit_control file contents. 236 */ 237 static int 238 read_control_file(void) 239 { 240 char cur_dir[MAXNAMLEN]; 241 struct dir_ent *dirent; 242 au_qctrl_t qctrl; 243 244 /* 245 * Clear old values. Force a re-read of the file the next time. 246 */ 247 free_dir_q(); 248 endac(); 249 250 /* 251 * Read the list of directories into a local linked list. 252 * 253 * XXX We should use the reentrant interfaces once they are 254 * available. 255 */ 256 while (getacdir(cur_dir, MAXNAMLEN) >= 0) { 257 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent)); 258 if (dirent == NULL) 259 return (-1); 260 dirent->softlim = 0; 261 dirent->dirname = (char *) malloc(MAXNAMLEN); 262 if (dirent->dirname == NULL) { 263 free(dirent); 264 return (-1); 265 } 266 strcpy(dirent->dirname, cur_dir); 267 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 268 } 269 270 allhardcount = 0; 271 if (swap_audit_file() == -1) { 272 syslog(LOG_ERR, "Could not swap audit file\n"); 273 /* 274 * XXX Faulty directory listing? - user should be given 275 * XXX an opportunity to change the audit_control file 276 * XXX switch to a reduced mode of auditing? 277 */ 278 return (-1); 279 } 280 281 /* 282 * XXX There are synchronization problems here 283 * XXX what should we do if a trigger for the earlier limit 284 * XXX is generated here? 285 */ 286 if (0 == (ret = getacmin(&minval))) { 287 syslog(LOG_INFO, "min free = %d\n", minval); 288 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 289 syslog(LOG_ERR, 290 "could not get audit queue settings\n"); 291 return (-1); 292 } 293 qctrl.aq_minfree = minval; 294 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 295 syslog(LOG_ERR, 296 "could not set audit queue settings\n"); 297 return (-1); 298 } 299 } 300 301 return (0); 302 } 303 304 /* 305 * Close all log files, control files, and tell the audit system. 306 */ 307 static int 308 close_all(void) 309 { 310 int err_ret = 0; 311 char TS[POSTFIX_LEN]; 312 int aufd; 313 token_t *tok; 314 long cond; 315 316 /* Generate an audit record. */ 317 if ((aufd = au_open()) == -1) 318 syslog(LOG_ERR, "Could not create audit shutdown event.\n"); 319 else { 320 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL) 321 au_write(aufd, tok); 322 if (au_close(aufd, 1, AUE_audit_shutdown) == -1) 323 syslog(LOG_ERR, 324 "Could not close audit shutdown event.\n"); 325 } 326 327 /* Flush contents. */ 328 cond = AUC_DISABLED; 329 err_ret = auditon(A_SETCOND, &cond, sizeof(cond)); 330 if (err_ret != 0) { 331 syslog(LOG_ERR, "Disabling audit failed! : %s\n", 332 strerror(errno)); 333 err_ret = 1; 334 } 335 if (getTSstr(TS, POSTFIX_LEN) == 0) 336 close_lastfile(TS); 337 if (lastfile != NULL) 338 free(lastfile); 339 340 free_dir_q(); 341 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) { 342 syslog(LOG_ERR, "Could not unregister\n"); 343 audit_warn_postsigterm(); 344 return (1); 345 } 346 endac(); 347 348 if (close(triggerfd) != 0) 349 syslog(LOG_ERR, "Error closing control file\n"); 350 syslog(LOG_INFO, "Finished.\n"); 351 return (0); 352 } 353 354 /* 355 * When we get a signal, we are often not at a clean point. So, little can 356 * be done in the signal handler itself. Instead, we send a message to the 357 * main servicing loop to do proper handling from a non-signal-handler 358 * context. 359 */ 360 static void 361 relay_signal(int signal) 362 { 363 364 if (signal == SIGHUP) 365 sighups++; 366 if (signal == SIGTERM) 367 sigterms++; 368 } 369 370 /* 371 * Registering the daemon. 372 */ 373 static int 374 register_daemon(void) 375 { 376 FILE * pidfile; 377 int fd; 378 pid_t pid; 379 380 /* Set up the signal hander. */ 381 if (signal(SIGTERM, relay_signal) == SIG_ERR) { 382 syslog(LOG_ERR, 383 "Could not set signal handler for SIGTERM\n"); 384 fail_exit(); 385 } 386 if (signal(SIGCHLD, relay_signal) == SIG_ERR) { 387 syslog(LOG_ERR, 388 "Could not set signal handler for SIGCHLD\n"); 389 fail_exit(); 390 } 391 if (signal(SIGHUP, relay_signal) == SIG_ERR) { 392 syslog(LOG_ERR, 393 "Could not set signal handler for SIGHUP\n"); 394 fail_exit(); 395 } 396 397 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) { 398 syslog(LOG_ERR, 399 "Could not open PID file\n"); 400 audit_warn_tmpfile(); 401 return (-1); 402 } 403 404 /* Attempt to lock the pid file; if a lock is present, exit. */ 405 fd = fileno(pidfile); 406 if (flock(fd, LOCK_EX | LOCK_NB) < 0) { 407 syslog(LOG_ERR, 408 "PID file is locked (is another auditd running?).\n"); 409 audit_warn_ebusy(); 410 return (-1); 411 } 412 413 pid = getpid(); 414 ftruncate(fd, 0); 415 if (fprintf(pidfile, "%u\n", pid) < 0) { 416 /* Should not start the daemon. */ 417 fail_exit(); 418 } 419 420 fflush(pidfile); 421 return (0); 422 } 423 424 /* 425 * Suppress duplicate messages within a 30 second interval. This should be 426 * enough to time to rotate log files without thrashing from soft warnings 427 * generated before the log is actually rotated. 428 */ 429 #define DUPLICATE_INTERVAL 30 430 static void 431 handle_audit_trigger(int trigger) 432 { 433 static int last_trigger; 434 static time_t last_time; 435 struct dir_ent *dirent; 436 int rc; 437 438 /* 439 * Suppres duplicate messages from the kernel within the specified 440 * interval. 441 */ 442 struct timeval ts; 443 struct timezone tzp; 444 time_t tt; 445 446 if (gettimeofday(&ts, &tzp) == 0) { 447 tt = (time_t)ts.tv_sec; 448 if ((trigger == last_trigger) && 449 (tt < (last_time + DUPLICATE_INTERVAL))) 450 return; 451 last_trigger = trigger; 452 last_time = tt; 453 } 454 455 /* 456 * Message processing is done here. 457 */ 458 dirent = TAILQ_FIRST(&dir_q); 459 switch(trigger) { 460 461 case AUDIT_TRIGGER_LOW_SPACE: 462 syslog(LOG_INFO, "Got low space trigger\n"); 463 if (dirent && (dirent->softlim != 1)) { 464 TAILQ_REMOVE(&dir_q, dirent, dirs); 465 /* Add this node to the end of the list. */ 466 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 467 audit_warn_soft(dirent->dirname); 468 dirent->softlim = 1; 469 470 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL && 471 swap_audit_file() == -1) 472 syslog(LOG_ERR, "Error swapping audit file\n"); 473 474 /* 475 * Check if the next dir has already reached its soft 476 * limit. 477 */ 478 dirent = TAILQ_FIRST(&dir_q); 479 if (dirent->softlim == 1) { 480 /* All dirs have reached their soft limit. */ 481 audit_warn_allsoft(); 482 } 483 } else { 484 /* 485 * Continue auditing to the current file. Also 486 * generate an allsoft warning. 487 * XXX do we want to do this ? 488 */ 489 audit_warn_allsoft(); 490 } 491 break; 492 493 case AUDIT_TRIGGER_NO_SPACE: 494 syslog(LOG_INFO, "Got no space trigger\n"); 495 496 /* Delete current dir, go on to next. */ 497 TAILQ_REMOVE(&dir_q, dirent, dirs); 498 audit_warn_hard(dirent->dirname); 499 free(dirent->dirname); 500 free(dirent); 501 502 if (swap_audit_file() == -1) 503 syslog(LOG_ERR, "Error swapping audit file\n"); 504 505 /* We are out of log directories. */ 506 audit_warn_allhard(++allhardcount); 507 break; 508 509 case AUDIT_TRIGGER_OPEN_NEW: 510 /* 511 * Create a new file and swap with the one being used in 512 * kernel 513 */ 514 syslog(LOG_INFO, "Got open new trigger\n"); 515 if (swap_audit_file() == -1) 516 syslog(LOG_ERR, "Error swapping audit file\n"); 517 break; 518 519 case AUDIT_TRIGGER_READ_FILE: 520 syslog(LOG_INFO, "Got read file trigger\n"); 521 if (read_control_file() == -1) 522 syslog(LOG_ERR, "Error in audit control file\n"); 523 if (config_audit_controls() == -1) 524 syslog(LOG_ERR, "Error setting audit controls\n"); 525 break; 526 527 default: 528 syslog(LOG_ERR, "Got unknown trigger %d\n", trigger); 529 break; 530 } 531 } 532 533 static void 534 handle_sighup(void) 535 { 536 537 sighups_handled = sighups; 538 config_audit_controls(); 539 } 540 541 /* 542 * Read the control file for triggers and handle appropriately. 543 */ 544 static int 545 wait_for_triggers(void) 546 { 547 int num; 548 unsigned int trigger; 549 550 for (;;) { 551 num = read(triggerfd, &trigger, sizeof(trigger)); 552 if ((num == -1) && (errno != EINTR)) { 553 syslog(LOG_ERR, "%s: error %d\n", __FUNCTION__, errno); 554 return (-1); 555 } 556 if (sigterms != sigterms_handled) { 557 syslog(LOG_INFO, "%s: SIGTERM", __FUNCTION__); 558 break; 559 } 560 if (sighups != sighups_handled) { 561 syslog(LOG_INFO, "%s: SIGHUP", __FUNCTION__); 562 handle_sighup(); 563 } 564 if ((num == -1) && (errno == EINTR)) 565 continue; 566 if (num == 0) { 567 syslog(LOG_INFO, "%s: read EOF\n", __FUNCTION__); 568 return (-1); 569 } 570 syslog(LOG_INFO, "%s: read %d\n", __FUNCTION__, trigger); 571 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE) 572 break; 573 else 574 handle_audit_trigger(trigger); 575 } 576 return (close_all()); 577 } 578 579 /* 580 * Reap our children. 581 */ 582 static void 583 reap_children(void) 584 { 585 pid_t child; 586 int wstatus; 587 588 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) { 589 if (!wstatus) 590 continue; 591 syslog(LOG_INFO, "warn process [pid=%d] %s %d.\n", child, 592 ((WIFEXITED(wstatus)) ? "exited with non-zero status" : 593 "exited as a result of signal"), 594 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : 595 WTERMSIG(wstatus))); 596 } 597 } 598 599 /* 600 * Configure the audit controls in the kernel: the event to class mapping, 601 * kernel preselection mask, etc. 602 */ 603 static int 604 config_audit_controls(void) 605 { 606 au_event_ent_t ev, *evp; 607 au_evclass_map_t evc_map; 608 au_mask_t aumask; 609 int ctr = 0; 610 char naeventstr[NA_EVENT_STR_SIZE]; 611 612 /* 613 * Process the audit event file, obtaining a class mapping for each 614 * event, and send that mapping into the kernel. 615 * XXX There's a risk here that the BSM library will return NULL 616 * for an event when it can't properly map it to a class. In that 617 * case, we will not process any events beyond the one that failed, 618 * but should. We need a way to get a count of the events. 619 */ 620 ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX); 621 ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX); 622 if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) { 623 syslog(LOG_ERR, 624 "Memory allocation error when configuring audit controls."); 625 return (-1); 626 } 627 evp = &ev; 628 setauevent(); 629 while ((evp = getauevent_r(evp)) != NULL) { 630 evc_map.ec_number = evp->ae_number; 631 evc_map.ec_class = evp->ae_class; 632 if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) 633 != 0) 634 syslog(LOG_ERR, 635 "Failed to register class mapping for event %s", 636 evp->ae_name); 637 else 638 ctr++; 639 } 640 endauevent(); 641 free(ev.ae_name); 642 free(ev.ae_desc); 643 if (ctr == 0) 644 syslog(LOG_ERR, "No events to class mappings registered."); 645 else 646 syslog(LOG_INFO, "Registered %d event to class mappings.", 647 ctr); 648 649 /* 650 * Get the non-attributable event string and set the kernel mask from 651 * that. 652 */ 653 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) && 654 (getauditflagsbin(naeventstr, &aumask) == 0)) { 655 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))) 656 syslog(LOG_ERR, 657 "Failed to register non-attributable event mask."); 658 else 659 syslog(LOG_INFO, 660 "Registered non-attributable event mask."); 661 } else 662 syslog(LOG_ERR, 663 "Failed to obtain non-attributable event mask."); 664 665 /* 666 * Set the audit policy flags based on passed in parameter values. 667 */ 668 if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags))) 669 syslog(LOG_ERR, "Failed to set audit policy."); 670 671 return (0); 672 } 673 674 static void 675 setup(void) 676 { 677 int aufd; 678 token_t *tok; 679 680 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) { 681 syslog(LOG_ERR, "Error opening trigger file\n"); 682 fail_exit(); 683 } 684 685 TAILQ_INIT(&dir_q); 686 if (read_control_file() == -1) { 687 syslog(LOG_ERR, "Error reading control file\n"); 688 fail_exit(); 689 } 690 691 /* Generate an audit record. */ 692 if ((aufd = au_open()) == -1) 693 syslog(LOG_ERR, "Could not create audit startup event.\n"); 694 else { 695 if ((tok = au_to_text("auditd::Audit startup")) != NULL) 696 au_write(aufd, tok); 697 if (au_close(aufd, 1, AUE_audit_startup) == -1) 698 syslog(LOG_ERR, 699 "Could not close audit startup event.\n"); 700 } 701 702 if (config_audit_controls() == 0) 703 syslog(LOG_INFO, "Audit controls init successful\n"); 704 else 705 syslog(LOG_INFO, "Audit controls init failed\n"); 706 } 707 708 int 709 main(int argc, char **argv) 710 { 711 char ch; 712 int debug = 0; 713 int rc; 714 715 global_flags |= AUDIT_CNT; 716 while ((ch = getopt(argc, argv, "dhs")) != -1) { 717 switch(ch) { 718 case 'd': 719 /* Debug option. */ 720 debug = 1; 721 break; 722 723 case 's': 724 /* Fail-stop option. */ 725 global_flags &= ~(AUDIT_CNT); 726 break; 727 728 case 'h': 729 /* Halt-stop option. */ 730 global_flags |= AUDIT_AHLT; 731 break; 732 733 case '?': 734 default: 735 (void)fprintf(stderr, 736 "usage: auditd [-h | -s] [-d] \n"); 737 exit(1); 738 } 739 } 740 741 openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY); 742 syslog(LOG_INFO, "starting...\n"); 743 744 if (debug == 0 && daemon(0, 0) == -1) { 745 syslog(LOG_ERR, "Failed to daemonize\n"); 746 exit(1); 747 } 748 749 if (register_daemon() == -1) { 750 syslog(LOG_ERR, "Could not register as daemon\n"); 751 exit(1); 752 } 753 754 setup(); 755 756 rc = wait_for_triggers(); 757 syslog(LOG_INFO, "auditd exiting.\n"); 758 759 exit(rc); 760 } 761