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