2 * Copyright (c) 2004 Apple Computer, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#26 $
32 #include <sys/types.h>
33 #include <sys/dirent.h>
35 #include <sys/queue.h>
39 #include <bsm/audit.h>
40 #include <bsm/audit_uevents.h>
41 #include <bsm/libbsm.h>
57 #define NA_EVENT_STR_SIZE 25
58 #define POL_STR_SIZE 128
60 static int ret, minval;
61 static char *lastfile = NULL;
62 static int allhardcount = 0;
63 static int triggerfd = 0;
64 static int sigchlds, sigchlds_handled;
65 static int sighups, sighups_handled;
66 static int sigterms, sigterms_handled;
68 static TAILQ_HEAD(, dir_ent) dir_q;
70 static int config_audit_controls(void);
73 * Error starting auditd
84 * Free our local list of directory names.
89 struct dir_ent *dirent;
91 while ((dirent = TAILQ_FIRST(&dir_q))) {
92 TAILQ_REMOVE(&dir_q, dirent, dirs);
93 free(dirent->dirname);
99 * Generate the timestamp string.
102 getTSstr(char *buf, int len)
108 if (gettimeofday(&ts, &tzp) != 0)
110 tt = (time_t)ts.tv_sec;
111 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
117 * Concat the directory name to the given file name.
118 * XXX We should affix the hostname also
121 affixdir(char *name, struct dir_ent *dirent)
125 const char *sep = "/";
127 curdir = dirent->dirname;
128 syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
130 fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1);
140 * Close the previous audit trail file.
143 close_lastfile(char *TS)
148 if (lastfile != NULL) {
149 oldname = (char *)malloc(strlen(lastfile) + 1);
152 strcpy(oldname, lastfile);
154 /* Rename the last file -- append timestamp. */
155 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
158 if (rename(oldname, lastfile) != 0)
160 "Could not rename %s to %s: %m", oldname,
163 syslog(LOG_INFO, "renamed %s to %s",
165 audit_warn_closefile(lastfile);
176 * Create the new audit file with appropriate permissions and ownership. Try
177 * to clean up if something goes wrong.
180 #ifdef AUDIT_REVIEW_GROUP
181 open_trail(const char *fname, uid_t uid, gid_t gid)
183 open_trail(const char *fname)
188 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
191 #ifdef AUDIT_REVIEW_GROUP
192 if (fchown(fd, uid, gid) < 0) {
204 * Create the new file name, swap with existing audit file.
207 swap_audit_file(void)
209 char timestr[2 * POSTFIX_LEN];
211 char TS[POSTFIX_LEN];
212 struct dir_ent *dirent;
213 #ifdef AUDIT_REVIEW_GROUP
220 if (getTSstr(TS, POSTFIX_LEN) != 0)
224 strcat(timestr, NOT_TERMINATED);
226 #ifdef AUDIT_REVIEW_GROUP
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?
231 grp = getgrnam(AUDIT_REVIEW_GROUP);
234 "Audit review group '%s' not available, using daemon gid",
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",
251 * Create and open the file; then close and pass to the
252 * kernel if all went well.
254 syslog(LOG_INFO, "New audit file is %s", fn);
255 #ifdef AUDIT_REVIEW_GROUP
256 fd = open_trail(fn, uid, gid);
261 warn("open(%s)", fn);
263 error = auditctl(fn);
266 "auditctl failed setting log file! : %s",
279 * Tell the administrator about lack of permissions for dir.
281 audit_warn_getacdir(dirent->dirname);
283 /* Try again with a different directory. */
284 TAILQ_REMOVE(&dir_q, dirent, dirs);
285 free(dirent->dirname);
288 syslog(LOG_ERR, "Log directories exhausted");
293 * Read the audit_control file contents.
296 read_control_file(void)
298 char cur_dir[MAXNAMLEN];
299 struct dir_ent *dirent;
303 * Clear old values. Force a re-read of the file the next time.
309 * Read the list of directories into a local linked list.
311 * XXX We should use the reentrant interfaces once they are
314 while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
315 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
319 dirent->dirname = (char *) malloc(MAXNAMLEN);
320 if (dirent->dirname == NULL) {
324 strcpy(dirent->dirname, cur_dir);
325 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
329 if (swap_audit_file() == -1) {
330 syslog(LOG_ERR, "Could not swap audit file");
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?
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?
344 if (0 == (ret = getacmin(&minval))) {
345 syslog(LOG_DEBUG, "min free = %d", minval);
346 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
348 "could not get audit queue settings");
351 qctrl.aq_minfree = minval;
352 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
354 "could not set audit queue settings");
363 * Close all log files, control files, and tell the audit system.
370 char TS[POSTFIX_LEN];
375 /* Generate an audit record. */
376 if ((aufd = au_open()) == -1)
377 syslog(LOG_ERR, "Could not create audit shutdown event.");
379 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
382 * XXX we need to implement extended subject tokens so we can
383 * effectively represent terminal lines with this token type.
385 bzero(&ai, sizeof(ai));
386 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
387 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
390 if ((tok = au_to_return32(0, 0)) != NULL)
392 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
394 "Could not close audit shutdown event.");
397 /* Flush contents. */
399 err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
401 syslog(LOG_ERR, "Disabling audit failed! : %s",
405 if (getTSstr(TS, POSTFIX_LEN) == 0)
407 if (lastfile != NULL)
411 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
412 syslog(LOG_ERR, "Could not unregister");
413 audit_warn_postsigterm();
418 if (close(triggerfd) != 0)
419 syslog(LOG_ERR, "Error closing control file");
420 syslog(LOG_INFO, "Finished");
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
431 relay_signal(int signal)
434 if (signal == SIGHUP)
436 if (signal == SIGTERM)
438 if (signal == SIGCHLD)
443 * Registering the daemon.
446 register_daemon(void)
452 /* Set up the signal hander. */
453 if (signal(SIGTERM, relay_signal) == SIG_ERR) {
455 "Could not set signal handler for SIGTERM");
458 if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
460 "Could not set signal handler for SIGCHLD");
463 if (signal(SIGHUP, relay_signal) == SIG_ERR) {
465 "Could not set signal handler for SIGHUP");
469 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
470 syslog(LOG_ERR, "Could not open PID file");
471 audit_warn_tmpfile();
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) {
479 "PID file is locked (is another auditd running?).");
486 if (fprintf(pidfile, "%u\n", pid) < 0) {
487 /* Should not start the daemon. */
496 * Handle the audit trigger event.
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.
505 #define DUPLICATE_INTERVAL 30
507 handle_audit_trigger(int trigger)
509 static int last_trigger, last_warning;
510 static time_t last_time;
511 struct dir_ent *dirent;
517 * Suppress duplicate messages from the kernel within the specified
520 if (gettimeofday(&ts, &tzp) == 0) {
521 tt = (time_t)ts.tv_sec;
523 case AUDIT_TRIGGER_LOW_SPACE:
524 case AUDIT_TRIGGER_NO_SPACE:
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.
530 if ((trigger == last_trigger) &&
531 (tt < (last_time + DUPLICATE_INTERVAL))) {
532 if (tt >= (last_warning + DUPLICATE_INTERVAL))
534 "Suppressing duplicate trigger %d",
541 case AUDIT_TRIGGER_ROTATE_KERNEL:
542 case AUDIT_TRIGGER_ROTATE_USER:
543 case AUDIT_TRIGGER_READ_FILE:
545 * Triggers that we cannot suppress.
551 * Only update last_trigger after aborting due to a duplicate
552 * trigger, not before, or we will never allow that trigger
555 last_trigger = trigger;
560 * Message processing is done here.
562 dirent = TAILQ_FIRST(&dir_q);
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);
573 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
574 swap_audit_file() == -1)
575 syslog(LOG_ERR, "Error swapping audit file");
578 * Check if the next dir has already reached its soft
581 dirent = TAILQ_FIRST(&dir_q);
582 if (dirent->softlim == 1) {
583 /* All dirs have reached their soft limit. */
584 audit_warn_allsoft();
588 * Continue auditing to the current file. Also
589 * generate an allsoft warning.
591 * XXX do we want to do this ?
593 audit_warn_allsoft();
597 case AUDIT_TRIGGER_NO_SPACE:
598 syslog(LOG_INFO, "Got no space trigger");
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);
606 if (swap_audit_file() == -1)
607 syslog(LOG_ERR, "Error swapping audit file");
609 /* We are out of log directories. */
610 audit_warn_allhard(++allhardcount);
613 case AUDIT_TRIGGER_ROTATE_KERNEL:
614 case AUDIT_TRIGGER_ROTATE_USER:
616 * Create a new file and swap with the one being used in
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");
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");
634 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
643 sighups_handled = sighups;
644 config_audit_controls();
656 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
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) :
671 sigchlds_handled = sigchlds;
676 * Read the control file for triggers/signals and handle appropriately.
679 wait_for_events(void)
682 unsigned int trigger;
685 num = read(triggerfd, &trigger, sizeof(trigger));
686 if ((num == -1) && (errno != EINTR)) {
687 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
690 if (sigterms != sigterms_handled) {
691 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
694 if (sigchlds != sigchlds_handled)
696 if (sighups != sighups_handled) {
697 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
700 if ((num == -1) && (errno == EINTR))
703 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
706 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
709 handle_audit_trigger(trigger);
711 return (close_all());
715 * Configure the audit controls in the kernel: the event to class mapping,
716 * kernel preselection mask, etc.
719 config_audit_controls(void)
721 au_event_ent_t ev, *evp;
722 au_evclass_map_t evc_map;
725 char naeventstr[NA_EVENT_STR_SIZE];
726 char polstr[POL_STR_SIZE];
732 * Process the audit event file, obtaining a class mapping for each
733 * event, and send that mapping into the kernel.
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.
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)
746 "Memory allocation error when configuring audit controls.");
751 * XXXRW: Currently we have no way to remove mappings from the kernel
752 * when they are removed from the file-based mappings.
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))
762 "Failed to register class mapping for event %s",
771 syslog(LOG_ERR, "No events to class mappings registered.");
773 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
777 * Get the non-attributable event string and set the kernel mask from
780 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
781 (getauditflagsbin(naeventstr, &aumask) == 0)) {
782 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
784 "Failed to register non-attributable event mask.");
787 "Registered non-attributable event mask.");
790 "Failed to obtain non-attributable event mask.");
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.
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");
802 syslog(LOG_ERR, "Failed to obtain policy flags: %m");
804 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
806 "Failed to set default audit policy: %m");
810 * Set trail rotation size.
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");
818 syslog(LOG_ERR, "Failed to obtain filesz: %m");
831 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
832 syslog(LOG_ERR, "Error opening trigger file");
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.
844 * XXXRW: Is there more to it than this?
846 bzero(&auinfo, sizeof(auinfo));
847 auinfo.ai_asid = getpid();
848 if (setaudit(&auinfo) == -1) {
849 syslog(LOG_ERR, "Error setting audit stat");
854 if (read_control_file() == -1) {
855 syslog(LOG_ERR, "Error reading control file");
859 /* Generate an audit record. */
860 if ((aufd = au_open()) == -1)
861 syslog(LOG_ERR, "Could not create audit startup event.");
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?
868 bzero(&ai, sizeof(ai));
869 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
870 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
873 if ((tok = au_to_text("auditd::Audit startup")) != NULL)
875 if ((tok = au_to_return32(0, 0)) != NULL)
877 if (au_close(aufd, 1, AUE_audit_startup) == -1)
879 "Could not close audit startup event.");
882 if (config_audit_controls() == 0)
883 syslog(LOG_INFO, "Audit controls init successful");
885 syslog(LOG_ERR, "Audit controls init failed");
889 main(int argc, char **argv)
895 while ((ch = getopt(argc, argv, "d")) != -1) {
904 (void)fprintf(stderr,
905 "usage: auditd [-d] \n");
911 openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY);
913 openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH);
915 syslog(LOG_INFO, "starting...");
917 if (debug == 0 && daemon(0, 0) == -1) {
918 syslog(LOG_ERR, "Failed to daemonize");
922 if (register_daemon() == -1) {
923 syslog(LOG_ERR, "Could not register as daemon");
929 rc = wait_for_events();
930 syslog(LOG_INFO, "auditd exiting.");