2 * Copyright (c) 2004 Apple Computer, Inc.
5 * @APPLE_BSD_LICENSE_HEADER_START@
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
31 * @APPLE_BSD_LICENSE_HEADER_END@
33 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#25 $
36 #include <sys/types.h>
37 #include <sys/dirent.h>
39 #include <sys/queue.h>
43 #include <bsm/audit.h>
44 #include <bsm/audit_uevents.h>
45 #include <bsm/libbsm.h>
61 #define NA_EVENT_STR_SIZE 25
62 #define POL_STR_SIZE 128
64 static int ret, minval;
65 static char *lastfile = NULL;
66 static int allhardcount = 0;
67 static int triggerfd = 0;
68 static int sigchlds, sigchlds_handled;
69 static int sighups, sighups_handled;
70 static int sigterms, sigterms_handled;
72 static TAILQ_HEAD(, dir_ent) dir_q;
74 static int config_audit_controls(void);
77 * Error starting auditd
88 * Free our local list of directory names.
93 struct dir_ent *dirent;
95 while ((dirent = TAILQ_FIRST(&dir_q))) {
96 TAILQ_REMOVE(&dir_q, dirent, dirs);
97 free(dirent->dirname);
103 * Generate the timestamp string.
106 getTSstr(char *buf, int len)
112 if (gettimeofday(&ts, &tzp) != 0)
114 tt = (time_t)ts.tv_sec;
115 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
121 * Concat the directory name to the given file name.
122 * XXX We should affix the hostname also
125 affixdir(char *name, struct dir_ent *dirent)
129 const char *sep = "/";
131 curdir = dirent->dirname;
132 syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
134 fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1);
144 * Close the previous audit trail file.
147 close_lastfile(char *TS)
152 if (lastfile != NULL) {
153 oldname = (char *)malloc(strlen(lastfile) + 1);
156 strcpy(oldname, lastfile);
158 /* Rename the last file -- append timestamp. */
159 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
162 if (rename(oldname, lastfile) != 0)
164 "Could not rename %s to %s: %m", oldname,
167 syslog(LOG_INFO, "renamed %s to %s",
169 audit_warn_closefile(lastfile);
180 * Create the new audit file with appropriate permissions and ownership. Try
181 * to clean up if something goes wrong.
184 #ifdef AUDIT_REVIEW_GROUP
185 open_trail(const char *fname, uid_t uid, gid_t gid)
187 open_trail(const char *fname)
192 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
195 #ifdef AUDIT_REVIEW_GROUP
196 if (fchown(fd, uid, gid) < 0) {
208 * Create the new file name, swap with existing audit file.
211 swap_audit_file(void)
213 char timestr[2 * POSTFIX_LEN];
215 char TS[POSTFIX_LEN];
216 struct dir_ent *dirent;
217 #ifdef AUDIT_REVIEW_GROUP
224 if (getTSstr(TS, POSTFIX_LEN) != 0)
228 strcat(timestr, NOT_TERMINATED);
230 #ifdef AUDIT_REVIEW_GROUP
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?
235 grp = getgrnam(AUDIT_REVIEW_GROUP);
238 "Audit review group '%s' not available, using daemon gid",
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",
255 * Create and open the file; then close and pass to the
256 * kernel if all went well.
258 syslog(LOG_INFO, "New audit file is %s", fn);
259 #ifdef AUDIT_REVIEW_GROUP
260 fd = open_trail(fn, uid, gid);
265 warn("open(%s)", fn);
267 error = auditctl(fn);
270 "auditctl failed setting log file! : %s",
283 * Tell the administrator about lack of permissions for dir.
285 audit_warn_getacdir(dirent->dirname);
287 /* Try again with a different directory. */
288 TAILQ_REMOVE(&dir_q, dirent, dirs);
289 free(dirent->dirname);
292 syslog(LOG_ERR, "Log directories exhausted");
297 * Read the audit_control file contents.
300 read_control_file(void)
302 char cur_dir[MAXNAMLEN];
303 struct dir_ent *dirent;
307 * Clear old values. Force a re-read of the file the next time.
313 * Read the list of directories into a local linked list.
315 * XXX We should use the reentrant interfaces once they are
318 while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
319 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
323 dirent->dirname = (char *) malloc(MAXNAMLEN);
324 if (dirent->dirname == NULL) {
328 strcpy(dirent->dirname, cur_dir);
329 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
333 if (swap_audit_file() == -1) {
334 syslog(LOG_ERR, "Could not swap audit file");
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?
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?
348 if (0 == (ret = getacmin(&minval))) {
349 syslog(LOG_DEBUG, "min free = %d", minval);
350 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
352 "could not get audit queue settings");
355 qctrl.aq_minfree = minval;
356 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
358 "could not set audit queue settings");
367 * Close all log files, control files, and tell the audit system.
374 char TS[POSTFIX_LEN];
379 /* Generate an audit record. */
380 if ((aufd = au_open()) == -1)
381 syslog(LOG_ERR, "Could not create audit shutdown event.");
383 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
386 * XXX we need to implement extended subject tokens so we can
387 * effectively represent terminal lines with this token type.
389 bzero(&ai, sizeof(ai));
390 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
391 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
394 if ((tok = au_to_return32(0, 0)) != NULL)
396 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
398 "Could not close audit shutdown event.");
401 /* Flush contents. */
403 err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
405 syslog(LOG_ERR, "Disabling audit failed! : %s",
409 if (getTSstr(TS, POSTFIX_LEN) == 0)
411 if (lastfile != NULL)
415 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
416 syslog(LOG_ERR, "Could not unregister");
417 audit_warn_postsigterm();
422 if (close(triggerfd) != 0)
423 syslog(LOG_ERR, "Error closing control file");
424 syslog(LOG_INFO, "Finished");
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
435 relay_signal(int signal)
438 if (signal == SIGHUP)
440 if (signal == SIGTERM)
442 if (signal == SIGCHLD)
447 * Registering the daemon.
450 register_daemon(void)
456 /* Set up the signal hander. */
457 if (signal(SIGTERM, relay_signal) == SIG_ERR) {
459 "Could not set signal handler for SIGTERM");
462 if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
464 "Could not set signal handler for SIGCHLD");
467 if (signal(SIGHUP, relay_signal) == SIG_ERR) {
469 "Could not set signal handler for SIGHUP");
473 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
474 syslog(LOG_ERR, "Could not open PID file");
475 audit_warn_tmpfile();
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) {
483 "PID file is locked (is another auditd running?).");
490 if (fprintf(pidfile, "%u\n", pid) < 0) {
491 /* Should not start the daemon. */
500 * Handle the audit trigger event.
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.
509 #define DUPLICATE_INTERVAL 30
511 handle_audit_trigger(int trigger)
513 static int last_trigger, last_warning;
514 static time_t last_time;
515 struct dir_ent *dirent;
521 * Suppress duplicate messages from the kernel within the specified
524 if (gettimeofday(&ts, &tzp) == 0) {
525 tt = (time_t)ts.tv_sec;
527 case AUDIT_TRIGGER_LOW_SPACE:
528 case AUDIT_TRIGGER_NO_SPACE:
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.
534 if ((trigger == last_trigger) &&
535 (tt < (last_time + DUPLICATE_INTERVAL))) {
536 if (tt >= (last_warning + DUPLICATE_INTERVAL))
538 "Suppressing duplicate trigger %d",
545 case AUDIT_TRIGGER_ROTATE_KERNEL:
546 case AUDIT_TRIGGER_ROTATE_USER:
547 case AUDIT_TRIGGER_READ_FILE:
549 * Triggers that we cannot suppress.
555 * Only update last_trigger after aborting due to a duplicate
556 * trigger, not before, or we will never allow that trigger
559 last_trigger = trigger;
564 * Message processing is done here.
566 dirent = TAILQ_FIRST(&dir_q);
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);
577 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
578 swap_audit_file() == -1)
579 syslog(LOG_ERR, "Error swapping audit file");
582 * Check if the next dir has already reached its soft
585 dirent = TAILQ_FIRST(&dir_q);
586 if (dirent->softlim == 1) {
587 /* All dirs have reached their soft limit. */
588 audit_warn_allsoft();
592 * Continue auditing to the current file. Also
593 * generate an allsoft warning.
595 * XXX do we want to do this ?
597 audit_warn_allsoft();
601 case AUDIT_TRIGGER_NO_SPACE:
602 syslog(LOG_INFO, "Got no space trigger");
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);
610 if (swap_audit_file() == -1)
611 syslog(LOG_ERR, "Error swapping audit file");
613 /* We are out of log directories. */
614 audit_warn_allhard(++allhardcount);
617 case AUDIT_TRIGGER_ROTATE_KERNEL:
618 case AUDIT_TRIGGER_ROTATE_USER:
620 * Create a new file and swap with the one being used in
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");
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");
638 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
647 sighups_handled = sighups;
648 config_audit_controls();
660 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
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) :
675 sigchlds_handled = sigchlds;
680 * Read the control file for triggers/signals and handle appropriately.
683 wait_for_events(void)
686 unsigned int trigger;
689 num = read(triggerfd, &trigger, sizeof(trigger));
690 if ((num == -1) && (errno != EINTR)) {
691 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
694 if (sigterms != sigterms_handled) {
695 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
698 if (sigchlds != sigchlds_handled)
700 if (sighups != sighups_handled) {
701 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
704 if ((num == -1) && (errno == EINTR))
707 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
710 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
713 handle_audit_trigger(trigger);
715 return (close_all());
719 * Configure the audit controls in the kernel: the event to class mapping,
720 * kernel preselection mask, etc.
723 config_audit_controls(void)
725 au_event_ent_t ev, *evp;
726 au_evclass_map_t evc_map;
729 char naeventstr[NA_EVENT_STR_SIZE];
730 char polstr[POL_STR_SIZE];
736 * Process the audit event file, obtaining a class mapping for each
737 * event, and send that mapping into the kernel.
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.
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)
750 "Memory allocation error when configuring audit controls.");
755 * XXXRW: Currently we have no way to remove mappings from the kernel
756 * when they are removed from the file-based mappings.
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))
766 "Failed to register class mapping for event %s",
775 syslog(LOG_ERR, "No events to class mappings registered.");
777 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
781 * Get the non-attributable event string and set the kernel mask from
784 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
785 (getauditflagsbin(naeventstr, &aumask) == 0)) {
786 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
788 "Failed to register non-attributable event mask.");
791 "Registered non-attributable event mask.");
794 "Failed to obtain non-attributable event mask.");
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.
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");
806 syslog(LOG_ERR, "Failed to obtain policy flags: %m");
808 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
810 "Failed to set default audit policy: %m");
814 * Set trail rotation size.
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");
822 syslog(LOG_ERR, "Failed to obtain filesz: %m");
835 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
836 syslog(LOG_ERR, "Error opening trigger file");
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.
848 * XXXRW: Is there more to it than this?
850 bzero(&auinfo, sizeof(auinfo));
851 auinfo.ai_asid = getpid();
852 if (setaudit(&auinfo) == -1) {
853 syslog(LOG_ERR, "Error setting audit stat");
858 if (read_control_file() == -1) {
859 syslog(LOG_ERR, "Error reading control file");
863 /* Generate an audit record. */
864 if ((aufd = au_open()) == -1)
865 syslog(LOG_ERR, "Could not create audit startup event.");
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?
872 bzero(&ai, sizeof(ai));
873 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
874 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
877 if ((tok = au_to_text("auditd::Audit startup")) != NULL)
879 if ((tok = au_to_return32(0, 0)) != NULL)
881 if (au_close(aufd, 1, AUE_audit_startup) == -1)
883 "Could not close audit startup event.");
886 if (config_audit_controls() == 0)
887 syslog(LOG_INFO, "Audit controls init successful");
889 syslog(LOG_ERR, "Audit controls init failed");
893 main(int argc, char **argv)
899 while ((ch = getopt(argc, argv, "d")) != -1) {
908 (void)fprintf(stderr,
909 "usage: auditd [-d] \n");
915 openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY);
917 openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH);
919 syslog(LOG_INFO, "starting...");
921 if (debug == 0 && daemon(0, 0) == -1) {
922 syslog(LOG_ERR, "Failed to daemonize");
926 if (register_daemon() == -1) {
927 syslog(LOG_ERR, "Could not register as daemon");
933 rc = wait_for_events();
934 syslog(LOG_INFO, "auditd exiting.");