Deleted Added
full compact
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}