auditd.c (156283) | auditd.c (159248) |
---|---|
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 --- 16 unchanged lines hidden (view full) --- 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 * | 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 --- 16 unchanged lines hidden (view full) --- 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#13 $ | 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 | 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> |
|
47#include <errno.h> 48#include <fcntl.h> 49#include <grp.h> 50#include <stdio.h> 51#include <stdlib.h> 52#include <time.h> 53#include <unistd.h> 54#include <signal.h> 55#include <string.h> 56#include <syslog.h> 57 58#include "auditd.h" 59 60#define NA_EVENT_STR_SIZE 25 61 62static int ret, minval; 63static char *lastfile = NULL; 64static int allhardcount = 0; 65static int triggerfd = 0; | 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 63static int ret, minval; 64static char *lastfile = NULL; 65static int allhardcount = 0; 66static int triggerfd = 0; |
67static int sigchlds, sigchlds_handled; |
|
66static int sighups, sighups_handled; 67static int sigterms, sigterms_handled; 68static long global_flags; 69 70static TAILQ_HEAD(, dir_ent) dir_q; 71 72static int config_audit_controls(void); 73 --- 48 unchanged lines hidden (view full) --- 122static char * 123affixdir(char *name, struct dir_ent *dirent) 124{ 125 char *fn; 126 char *curdir; 127 const char *sep = "/"; 128 129 curdir = dirent->dirname; | 68static int sighups, sighups_handled; 69static int sigterms, sigterms_handled; 70static long global_flags; 71 72static TAILQ_HEAD(, dir_ent) dir_q; 73 74static int config_audit_controls(void); 75 --- 48 unchanged lines hidden (view full) --- 124static char * 125affixdir(char *name, struct dir_ent *dirent) 126{ 127 char *fn; 128 char *curdir; 129 const char *sep = "/"; 130 131 curdir = dirent->dirname; |
130 syslog(LOG_INFO, "dir = %s\n", dirent->dirname); | 132 syslog(LOG_DEBUG, "dir = %s", dirent->dirname); |
131 132 fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1); 133 if (fn == NULL) 134 return (NULL); 135 strcpy(fn, curdir); 136 strcat(fn, sep); 137 strcat(fn, name); 138 return (fn); --- 14 unchanged lines hidden (view full) --- 153 return (-1); 154 strcpy(oldname, lastfile); 155 156 /* Rename the last file -- append timestamp. */ 157 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) { 158 *ptr = '.'; 159 strcpy(ptr+1, TS); 160 if (rename(oldname, lastfile) != 0) | 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); --- 14 unchanged lines hidden (view full) --- 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) |
161 syslog(LOG_ERR, "Could not rename %s to %s \n", | 163 syslog(LOG_ERR, "Could not rename %s to %s", |
162 oldname, lastfile); 163 else | 164 oldname, lastfile); 165 else |
164 syslog(LOG_INFO, "renamed %s to %s \n", | 166 syslog(LOG_INFO, "renamed %s to %s", |
165 oldname, lastfile); 166 } 167 free(lastfile); 168 free(oldname); 169 lastfile = NULL; 170 } 171 return (0); 172} --- 63 unchanged lines hidden (view full) --- 236 } else 237 gid = grp->gr_gid; 238 uid = getuid(); 239#endif 240 241 /* Try until we succeed. */ 242 while ((dirent = TAILQ_FIRST(&dir_q))) { 243 if ((fn = affixdir(timestr, dirent)) == NULL) { | 167 oldname, lastfile); 168 } 169 free(lastfile); 170 free(oldname); 171 lastfile = NULL; 172 } 173 return (0); 174} --- 63 unchanged lines hidden (view full) --- 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) { |
244 syslog(LOG_INFO, "Failed to swap log at time %s\n", | 246 syslog(LOG_INFO, "Failed to swap log at time %s", |
245 timestr); 246 return (-1); 247 } 248 249 /* 250 * Create and open the file; then close and pass to the 251 * kernel if all went well. 252 */ | 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 */ |
253 syslog(LOG_INFO, "New audit file is %s\n", fn); | 255 syslog(LOG_INFO, "New audit file is %s", fn); |
254#ifdef AUDIT_REVIEW_GROUP 255 fd = open_trail(fn, uid, gid); 256#else 257 fd = open_trail(fn); 258#endif 259 if (fd < 0) 260 warn("open(%s)", fn); 261 if (fd >= 0) { 262 error = auditctl(fn); 263 if (error) { 264 syslog(LOG_ERR, | 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, |
265 "auditctl failed setting log file! : %s\n", | 267 "auditctl failed setting log file! : %s", |
266 strerror(errno)); 267 close(fd); 268 } else { 269 /* Success. */ 270 close_lastfile(TS); 271 lastfile = fn; 272 close(fd); 273 return (0); --- 5 unchanged lines hidden (view full) --- 279 */ 280 audit_warn_getacdir(dirent->dirname); 281 282 /* Try again with a different directory. */ 283 TAILQ_REMOVE(&dir_q, dirent, dirs); 284 free(dirent->dirname); 285 free(dirent); 286 } | 268 strerror(errno)); 269 close(fd); 270 } else { 271 /* Success. */ 272 close_lastfile(TS); 273 lastfile = fn; 274 close(fd); 275 return (0); --- 5 unchanged lines hidden (view full) --- 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 } |
287 syslog(LOG_INFO, "Log directories exhausted\n"); | 289 syslog(LOG_ERR, "Log directories exhausted\n"); |
288 return (-1); 289} 290 291/* 292 * Read the audit_control file contents. 293 */ 294static int 295read_control_file(void) --- 25 unchanged lines hidden (view full) --- 321 return (-1); 322 } 323 strcpy(dirent->dirname, cur_dir); 324 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 325 } 326 327 allhardcount = 0; 328 if (swap_audit_file() == -1) { | 290 return (-1); 291} 292 293/* 294 * Read the audit_control file contents. 295 */ 296static int 297read_control_file(void) --- 25 unchanged lines hidden (view full) --- 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) { |
329 syslog(LOG_ERR, "Could not swap audit file\n"); | 331 syslog(LOG_ERR, "Could not swap audit file"); |
330 /* 331 * XXX Faulty directory listing? - user should be given 332 * XXX an opportunity to change the audit_control file 333 * XXX switch to a reduced mode of auditing? 334 */ 335 return (-1); 336 } 337 338 /* 339 * XXX There are synchronization problems here 340 * XXX what should we do if a trigger for the earlier limit 341 * XXX is generated here? 342 */ 343 if (0 == (ret = getacmin(&minval))) { | 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))) { |
344 syslog(LOG_INFO, "min free = %d\n", minval); | 346 syslog(LOG_DEBUG, "min free = %d\n", minval); |
345 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 346 syslog(LOG_ERR, | 347 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 348 syslog(LOG_ERR, |
347 "could not get audit queue settings\n"); | 349 "could not get audit queue settings"); |
348 return (-1); 349 } 350 qctrl.aq_minfree = minval; 351 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 352 syslog(LOG_ERR, | 350 return (-1); 351 } 352 qctrl.aq_minfree = minval; 353 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) { 354 syslog(LOG_ERR, |
353 "could not set audit queue settings\n"); | 355 "could not set audit queue settings"); |
354 return (-1); 355 } 356 } 357 358 return (0); 359} 360 361/* --- 5 unchanged lines hidden (view full) --- 367 int err_ret = 0; 368 char TS[POSTFIX_LEN]; 369 int aufd; 370 token_t *tok; 371 long cond; 372 373 /* Generate an audit record. */ 374 if ((aufd = au_open()) == -1) | 356 return (-1); 357 } 358 } 359 360 return (0); 361} 362 363/* --- 5 unchanged lines hidden (view full) --- 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) |
375 syslog(LOG_ERR, "Could not create audit shutdown event.\n"); | 377 syslog(LOG_ERR, "Could not create audit shutdown event."); |
376 else { 377 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL) 378 au_write(aufd, tok); 379 if (au_close(aufd, 1, AUE_audit_shutdown) == -1) 380 syslog(LOG_ERR, | 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, |
381 "Could not close audit shutdown event.\n"); | 383 "Could not close audit shutdown event."); |
382 } 383 384 /* Flush contents. */ 385 cond = AUC_DISABLED; 386 err_ret = auditon(A_SETCOND, &cond, sizeof(cond)); 387 if (err_ret != 0) { | 384 } 385 386 /* Flush contents. */ 387 cond = AUC_DISABLED; 388 err_ret = auditon(A_SETCOND, &cond, sizeof(cond)); 389 if (err_ret != 0) { |
388 syslog(LOG_ERR, "Disabling audit failed! : %s\n", | 390 syslog(LOG_ERR, "Disabling audit failed! : %s", |
389 strerror(errno)); 390 err_ret = 1; 391 } 392 if (getTSstr(TS, POSTFIX_LEN) == 0) 393 close_lastfile(TS); 394 if (lastfile != NULL) 395 free(lastfile); 396 397 free_dir_q(); 398 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) { | 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) { |
399 syslog(LOG_ERR, "Could not unregister\n"); | 401 syslog(LOG_ERR, "Could not unregister"); |
400 audit_warn_postsigterm(); 401 return (1); 402 } 403 endac(); 404 405 if (close(triggerfd) != 0) | 402 audit_warn_postsigterm(); 403 return (1); 404 } 405 endac(); 406 407 if (close(triggerfd) != 0) |
406 syslog(LOG_ERR, "Error closing control file\n"); 407 syslog(LOG_INFO, "Finished.\n"); | 408 syslog(LOG_ERR, "Error closing control file"); 409 syslog(LOG_INFO, "Finished"); |
408 return (0); 409} 410 411/* 412 * When we get a signal, we are often not at a clean point. So, little can 413 * be done in the signal handler itself. Instead, we send a message to the 414 * main servicing loop to do proper handling from a non-signal-handler 415 * context. 416 */ 417static void 418relay_signal(int signal) 419{ 420 421 if (signal == SIGHUP) 422 sighups++; 423 if (signal == SIGTERM) 424 sigterms++; | 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 */ 419static void 420relay_signal(int signal) 421{ 422 423 if (signal == SIGHUP) 424 sighups++; 425 if (signal == SIGTERM) 426 sigterms++; |
427 if (signal == SIGCHLD) 428 sigchlds++; |
|
425} 426 427/* 428 * Registering the daemon. 429 */ 430static int 431register_daemon(void) 432{ 433 FILE * pidfile; 434 int fd; 435 pid_t pid; 436 437 /* Set up the signal hander. */ 438 if (signal(SIGTERM, relay_signal) == SIG_ERR) { 439 syslog(LOG_ERR, | 429} 430 431/* 432 * Registering the daemon. 433 */ 434static int 435register_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, |
440 "Could not set signal handler for SIGTERM\n"); | 444 "Could not set signal handler for SIGTERM"); |
441 fail_exit(); 442 } 443 if (signal(SIGCHLD, relay_signal) == SIG_ERR) { 444 syslog(LOG_ERR, | 445 fail_exit(); 446 } 447 if (signal(SIGCHLD, relay_signal) == SIG_ERR) { 448 syslog(LOG_ERR, |
445 "Could not set signal handler for SIGCHLD\n"); | 449 "Could not set signal handler for SIGCHLD"); |
446 fail_exit(); 447 } 448 if (signal(SIGHUP, relay_signal) == SIG_ERR) { 449 syslog(LOG_ERR, | 450 fail_exit(); 451 } 452 if (signal(SIGHUP, relay_signal) == SIG_ERR) { 453 syslog(LOG_ERR, |
450 "Could not set signal handler for SIGHUP\n"); | 454 "Could not set signal handler for SIGHUP"); |
451 fail_exit(); 452 } 453 454 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) { | 455 fail_exit(); 456 } 457 458 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) { |
455 syslog(LOG_ERR, 456 "Could not open PID file\n"); | 459 syslog(LOG_ERR, "Could not open PID file"); |
457 audit_warn_tmpfile(); 458 return (-1); 459 } 460 461 /* Attempt to lock the pid file; if a lock is present, exit. */ 462 fd = fileno(pidfile); 463 if (flock(fd, LOCK_EX | LOCK_NB) < 0) { 464 syslog(LOG_ERR, | 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, |
465 "PID file is locked (is another auditd running?).\n"); | 468 "PID file is locked (is another auditd running?)."); |
466 audit_warn_ebusy(); 467 return (-1); 468 } 469 470 pid = getpid(); 471 ftruncate(fd, 0); 472 if (fprintf(pidfile, "%u\n", pid) < 0) { 473 /* Should not start the daemon. */ --- 11 unchanged lines hidden (view full) --- 485 */ 486#define DUPLICATE_INTERVAL 30 487static void 488handle_audit_trigger(int trigger) 489{ 490 static int last_trigger; 491 static time_t last_time; 492 struct dir_ent *dirent; | 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. */ --- 11 unchanged lines hidden (view full) --- 488 */ 489#define DUPLICATE_INTERVAL 30 490static void 491handle_audit_trigger(int trigger) 492{ 493 static int last_trigger; 494 static time_t last_time; 495 struct dir_ent *dirent; |
493 int rc; | |
494 495 /* 496 * Suppres duplicate messages from the kernel within the specified 497 * interval. 498 */ 499 struct timeval ts; 500 struct timezone tzp; 501 time_t tt; --- 9 unchanged lines hidden (view full) --- 511 512 /* 513 * Message processing is done here. 514 */ 515 dirent = TAILQ_FIRST(&dir_q); 516 switch(trigger) { 517 518 case AUDIT_TRIGGER_LOW_SPACE: | 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; --- 9 unchanged lines hidden (view full) --- 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: |
519 syslog(LOG_INFO, "Got low space trigger\n"); | 521 syslog(LOG_INFO, "Got low space trigger"); |
520 if (dirent && (dirent->softlim != 1)) { 521 TAILQ_REMOVE(&dir_q, dirent, dirs); 522 /* Add this node to the end of the list. */ 523 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs); 524 audit_warn_soft(dirent->dirname); 525 dirent->softlim = 1; 526 527 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL && 528 swap_audit_file() == -1) | 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) |
529 syslog(LOG_ERR, "Error swapping audit file\n"); | 531 syslog(LOG_ERR, "Error swapping audit file"); |
530 531 /* 532 * Check if the next dir has already reached its soft 533 * limit. 534 */ 535 dirent = TAILQ_FIRST(&dir_q); 536 if (dirent->softlim == 1) { 537 /* All dirs have reached their soft limit. */ --- 5 unchanged lines hidden (view full) --- 543 * generate an allsoft warning. 544 * XXX do we want to do this ? 545 */ 546 audit_warn_allsoft(); 547 } 548 break; 549 550 case AUDIT_TRIGGER_NO_SPACE: | 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. */ --- 5 unchanged lines hidden (view full) --- 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: |
551 syslog(LOG_INFO, "Got no space trigger\n"); | 553 syslog(LOG_INFO, "Got no space trigger"); |
552 553 /* Delete current dir, go on to next. */ 554 TAILQ_REMOVE(&dir_q, dirent, dirs); 555 audit_warn_hard(dirent->dirname); 556 free(dirent->dirname); 557 free(dirent); 558 559 if (swap_audit_file() == -1) | 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) |
560 syslog(LOG_ERR, "Error swapping audit file\n"); | 562 syslog(LOG_ERR, "Error swapping audit file"); |
561 562 /* We are out of log directories. */ 563 audit_warn_allhard(++allhardcount); 564 break; 565 566 case AUDIT_TRIGGER_OPEN_NEW: 567 /* 568 * Create a new file and swap with the one being used in 569 * kernel 570 */ | 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 */ |
571 syslog(LOG_INFO, "Got open new trigger\n"); | 573 syslog(LOG_INFO, "Got open new trigger"); |
572 if (swap_audit_file() == -1) | 574 if (swap_audit_file() == -1) |
573 syslog(LOG_ERR, "Error swapping audit file\n"); | 575 syslog(LOG_ERR, "Error swapping audit file"); |
574 break; 575 576 case AUDIT_TRIGGER_READ_FILE: | 576 break; 577 578 case AUDIT_TRIGGER_READ_FILE: |
577 syslog(LOG_INFO, "Got read file trigger\n"); | 579 syslog(LOG_INFO, "Got read file trigger"); |
578 if (read_control_file() == -1) | 580 if (read_control_file() == -1) |
579 syslog(LOG_ERR, "Error in audit control file\n"); | 581 syslog(LOG_ERR, "Error in audit control file"); |
580 if (config_audit_controls() == -1) | 582 if (config_audit_controls() == -1) |
581 syslog(LOG_ERR, "Error setting audit controls\n"); | 583 syslog(LOG_ERR, "Error setting audit controls"); |
582 break; 583 584 default: | 584 break; 585 586 default: |
585 syslog(LOG_ERR, "Got unknown trigger %d\n", trigger); | 587 syslog(LOG_ERR, "Got unknown trigger %d", trigger); |
586 break; 587 } 588} 589 590static void 591handle_sighup(void) 592{ 593 594 sighups_handled = sighups; 595 config_audit_controls(); 596} 597 598/* | 588 break; 589 } 590} 591 592static void 593handle_sighup(void) 594{ 595 596 sighups_handled = sighups; 597 config_audit_controls(); 598} 599 600/* |
599 * Read the control file for triggers and handle appropriately. | 601 * Reap our children. |
600 */ | 602 */ |
603static void 604reap_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 620static void 621handle_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 */ |
|
601static int | 631static int |
602wait_for_triggers(void) | 632wait_for_events(void) |
603{ 604 int num; 605 unsigned int trigger; 606 607 for (;;) { 608 num = read(triggerfd, &trigger, sizeof(trigger)); 609 if ((num == -1) && (errno != EINTR)) { | 633{ 634 int num; 635 unsigned int trigger; 636 637 for (;;) { 638 num = read(triggerfd, &trigger, sizeof(trigger)); 639 if ((num == -1) && (errno != EINTR)) { |
610 syslog(LOG_ERR, "%s: error %d\n", __FUNCTION__, errno); | 640 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno); |
611 return (-1); 612 } 613 if (sigterms != sigterms_handled) { | 641 return (-1); 642 } 643 if (sigterms != sigterms_handled) { |
614 syslog(LOG_INFO, "%s: SIGTERM", __FUNCTION__); | 644 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__); |
615 break; 616 } | 645 break; 646 } |
647 if (sigchlds != sigchlds_handled) { 648 syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__); 649 handle_sigchld(); 650 } |
|
617 if (sighups != sighups_handled) { | 651 if (sighups != sighups_handled) { |
618 syslog(LOG_INFO, "%s: SIGHUP", __FUNCTION__); | 652 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__); |
619 handle_sighup(); 620 } 621 if ((num == -1) && (errno == EINTR)) 622 continue; 623 if (num == 0) { | 653 handle_sighup(); 654 } 655 if ((num == -1) && (errno == EINTR)) 656 continue; 657 if (num == 0) { |
624 syslog(LOG_INFO, "%s: read EOF\n", __FUNCTION__); | 658 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__); |
625 return (-1); 626 } | 659 return (-1); 660 } |
627 syslog(LOG_INFO, "%s: read %d\n", __FUNCTION__, trigger); | 661 syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger); |
628 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE) 629 break; 630 else 631 handle_audit_trigger(trigger); 632 } 633 return (close_all()); 634} 635 636/* | 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/* |
637 * Reap our children. 638 */ 639static void 640reap_children(void) 641{ 642 pid_t child; 643 int wstatus; 644 645 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) { 646 if (!wstatus) 647 continue; 648 syslog(LOG_INFO, "warn process [pid=%d] %s %d.\n", child, 649 ((WIFEXITED(wstatus)) ? "exited with non-zero status" : 650 "exited as a result of signal"), 651 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) : 652 WTERMSIG(wstatus))); 653 } 654} 655 656/* | |
657 * Configure the audit controls in the kernel: the event to class mapping, 658 * kernel preselection mask, etc. 659 */ 660static int 661config_audit_controls(void) 662{ 663 au_event_ent_t ev, *evp; 664 au_evclass_map_t evc_map; --- 30 unchanged lines hidden (view full) --- 695 ctr++; 696 } 697 endauevent(); 698 free(ev.ae_name); 699 free(ev.ae_desc); 700 if (ctr == 0) 701 syslog(LOG_ERR, "No events to class mappings registered."); 702 else | 671 * Configure the audit controls in the kernel: the event to class mapping, 672 * kernel preselection mask, etc. 673 */ 674static int 675config_audit_controls(void) 676{ 677 au_event_ent_t ev, *evp; 678 au_evclass_map_t evc_map; --- 30 unchanged lines hidden (view full) --- 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 |
703 syslog(LOG_INFO, "Registered %d event to class mappings.", | 717 syslog(LOG_DEBUG, "Registered %d event to class mappings.", |
704 ctr); 705 706 /* 707 * Get the non-attributable event string and set the kernel mask from 708 * that. 709 */ 710 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) && 711 (getauditflagsbin(naeventstr, &aumask) == 0)) { 712 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))) 713 syslog(LOG_ERR, 714 "Failed to register non-attributable event mask."); 715 else | 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 |
716 syslog(LOG_INFO, | 730 syslog(LOG_DEBUG, |
717 "Registered non-attributable event mask."); 718 } else 719 syslog(LOG_ERR, 720 "Failed to obtain non-attributable event mask."); 721 722 /* 723 * Set the audit policy flags based on passed in parameter values. 724 */ 725 if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags))) 726 syslog(LOG_ERR, "Failed to set audit policy."); 727 728 return (0); 729} 730 731static void 732setup(void) 733{ | 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 745static void 746setup(void) 747{ |
748 auditinfo_t auinfo; |
|
734 int aufd; 735 token_t *tok; 736 737 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) { | 749 int aufd; 750 token_t *tok; 751 752 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) { |
738 syslog(LOG_ERR, "Error opening trigger file\n"); | 753 syslog(LOG_ERR, "Error opening trigger file"); |
739 fail_exit(); 740 } 741 | 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 |
|
742 TAILQ_INIT(&dir_q); 743 if (read_control_file() == -1) { | 774 TAILQ_INIT(&dir_q); 775 if (read_control_file() == -1) { |
744 syslog(LOG_ERR, "Error reading control file\n"); | 776 syslog(LOG_ERR, "Error reading control file"); |
745 fail_exit(); 746 } 747 748 /* Generate an audit record. */ 749 if ((aufd = au_open()) == -1) | 777 fail_exit(); 778 } 779 780 /* Generate an audit record. */ 781 if ((aufd = au_open()) == -1) |
750 syslog(LOG_ERR, "Could not create audit startup event.\n"); | 782 syslog(LOG_ERR, "Could not create audit startup event."); |
751 else { 752 if ((tok = au_to_text("auditd::Audit startup")) != NULL) 753 au_write(aufd, tok); 754 if (au_close(aufd, 1, AUE_audit_startup) == -1) 755 syslog(LOG_ERR, | 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, |
756 "Could not close audit startup event.\n"); | 788 "Could not close audit startup event."); |
757 } 758 759 if (config_audit_controls() == 0) | 789 } 790 791 if (config_audit_controls() == 0) |
760 syslog(LOG_INFO, "Audit controls init successful\n"); | 792 syslog(LOG_INFO, "Audit controls init successful"); |
761 else | 793 else |
762 syslog(LOG_INFO, "Audit controls init failed\n"); | 794 syslog(LOG_ERR, "Audit controls init failed"); |
763} 764 765int 766main(int argc, char **argv) 767{ 768 int ch; 769 int debug = 0; 770 int rc; --- 24 unchanged lines hidden (view full) --- 795 } 796 } 797 798#ifdef LOG_SECURITY 799 openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY); 800#else 801 openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH); 802#endif | 795} 796 797int 798main(int argc, char **argv) 799{ 800 int ch; 801 int debug = 0; 802 int rc; --- 24 unchanged lines hidden (view full) --- 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 |
803 syslog(LOG_INFO, "starting...\n"); | 835 syslog(LOG_INFO, "starting..."); |
804 805 if (debug == 0 && daemon(0, 0) == -1) { | 836 837 if (debug == 0 && daemon(0, 0) == -1) { |
806 syslog(LOG_ERR, "Failed to daemonize\n"); | 838 syslog(LOG_ERR, "Failed to daemonize"); |
807 exit(1); 808 } 809 810 if (register_daemon() == -1) { | 839 exit(1); 840 } 841 842 if (register_daemon() == -1) { |
811 syslog(LOG_ERR, "Could not register as daemon\n"); | 843 syslog(LOG_ERR, "Could not register as daemon"); |
812 exit(1); 813 } 814 815 setup(); 816 | 844 exit(1); 845 } 846 847 setup(); 848 |
817 rc = wait_for_triggers(); 818 syslog(LOG_INFO, "auditd exiting.\n"); | 849 rc = wait_for_events(); 850 syslog(LOG_INFO, "auditd exiting."); |
819 820 exit(rc); 821} | 851 852 exit(rc); 853} |