2 * Copyright (c) 2004-2008 Apple 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 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#39 $
32 #include <sys/param.h>
34 #include <config/config.h>
36 #include <sys/dirent.h>
38 #include <sys/socket.h>
39 #ifdef HAVE_FULL_QUEUE_H
40 #include <sys/queue.h>
41 #else /* !HAVE_FULL_QUEUE_H */
42 #include <compat/queue.h>
43 #endif /* !HAVE_FULL_QUEUE_H */
47 #include <bsm/audit.h>
48 #include <bsm/audit_uevents.h>
49 #include <bsm/libbsm.h>
51 #include <netinet/in.h>
69 #include <mach/port.h>
70 #include <mach/mach_error.h>
71 #include <mach/mach_traps.h>
72 #include <mach/mach.h>
73 #include <mach/host_special_ports.h>
75 #include "auditd_control_server.h"
76 #include "audit_triggers_server.h"
77 #endif /* USE_MACH_IPC */
80 #include <compat/strlcpy.h>
83 #define NA_EVENT_STR_SIZE 25
84 #define POL_STR_SIZE 128
85 static int ret, minval;
86 static char *lastfile = NULL;
87 static int allhardcount = 0;
88 static int sigchlds, sigchlds_handled;
89 static int sighups, sighups_handled;
91 static int sigterms, sigterms_handled;
92 static int triggerfd = 0;
94 #else /* USE_MACH_IPC */
96 static mach_port_t control_port = MACH_PORT_NULL;
97 static mach_port_t signal_port = MACH_PORT_NULL;
98 static mach_port_t port_set = MACH_PORT_NULL;
100 #ifndef __BSM_INTERNAL_NOTIFY_KEY
101 #define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
102 #endif /* __BSM_INTERNAL_NOTIFY_KEY */
103 #endif /* USE_MACH_IPC */
105 static TAILQ_HEAD(, dir_ent) dir_q;
107 static int config_audit_controls(void);
110 * Error starting auditd
116 audit_warn_nostart();
121 * Free our local list of directory names.
126 struct dir_ent *dirent;
128 while ((dirent = TAILQ_FIRST(&dir_q))) {
129 TAILQ_REMOVE(&dir_q, dirent, dirs);
130 free(dirent->dirname);
136 * Generate the timestamp string.
139 getTSstr(char *buf, int len)
145 if (gettimeofday(&ts, &tzp) != 0)
147 tt = (time_t)ts.tv_sec;
148 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
154 * Concat the directory name to the given file name.
155 * XXX We should affix the hostname also
158 affixdir(char *name, struct dir_ent *dirent)
162 syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
164 * Sanity check on file name.
166 if (strlen(name) != (FILENAME_LEN - 1)) {
167 syslog(LOG_ERR, "Invalid file name: %s", name);
170 asprintf(&fn, "%s/%s", dirent->dirname, name);
175 * Close the previous audit trail file.
178 close_lastfile(char *TS)
184 if (lastfile != NULL) {
185 len = strlen(lastfile) + 1;
186 oldname = (char *)malloc(len);
189 strlcpy(oldname, lastfile, len);
191 /* Rename the last file -- append timestamp. */
192 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
193 strlcpy(ptr, TS, TIMESTAMP_LEN);
194 if (rename(oldname, lastfile) != 0)
196 "Could not rename %s to %s: %m", oldname,
199 syslog(LOG_INFO, "renamed %s to %s",
201 audit_warn_closefile(lastfile);
204 syslog(LOG_ERR, "Could not rename %s to %s", oldname,
214 * Create the new audit file with appropriate permissions and ownership. Try
215 * to clean up if something goes wrong.
218 #ifdef AUDIT_REVIEW_GROUP
219 open_trail(const char *fname, uid_t uid, gid_t gid)
221 open_trail(const char *fname)
226 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
229 #ifdef AUDIT_REVIEW_GROUP
230 if (fchown(fd, uid, gid) < 0) {
242 * Create the new file name, swap with existing audit file.
245 swap_audit_file(void)
247 char timestr[FILENAME_LEN];
249 char TS[TIMESTAMP_LEN];
250 struct dir_ent *dirent;
251 #ifdef AUDIT_REVIEW_GROUP
258 if (getTSstr(TS, TIMESTAMP_LEN) != 0)
261 snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED);
263 #ifdef AUDIT_REVIEW_GROUP
265 * XXXRW: Currently, this code falls back to the daemon gid, which is
266 * likely the wheel group. Is there a better way to deal with this?
268 grp = getgrnam(AUDIT_REVIEW_GROUP);
271 "Audit review group '%s' not available, using daemon gid",
279 /* Try until we succeed. */
280 while ((dirent = TAILQ_FIRST(&dir_q))) {
281 if ((fn = affixdir(timestr, dirent)) == NULL) {
282 syslog(LOG_INFO, "Failed to swap log at time %s",
288 * Create and open the file; then close and pass to the
289 * kernel if all went well.
291 syslog(LOG_INFO, "New audit file is %s", fn);
292 #ifdef AUDIT_REVIEW_GROUP
293 fd = open_trail(fn, uid, gid);
298 warn("open(%s)", fn);
300 error = auditctl(fn);
303 "auditctl failed setting log file! : %s",
310 * auditctl() potentially changes the audit
311 * state so post that the audit config (may
314 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
324 * Tell the administrator about lack of permissions for dir.
326 audit_warn_getacdir(dirent->dirname);
328 /* Try again with a different directory. */
329 TAILQ_REMOVE(&dir_q, dirent, dirs);
330 free(dirent->dirname);
333 syslog(LOG_ERR, "Log directories exhausted");
338 * Read the audit_control file contents.
341 read_control_file(void)
343 char cur_dir[MAXNAMLEN];
344 struct dir_ent *dirent;
348 * Clear old values. Force a re-read of the file the next time.
354 * Read the list of directories into a local linked list.
356 * XXX We should use the reentrant interfaces once they are
359 while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
360 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
364 dirent->dirname = (char *) malloc(MAXNAMLEN);
365 if (dirent->dirname == NULL) {
369 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
370 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
374 if (swap_audit_file() == -1) {
375 syslog(LOG_ERR, "Could not swap audit file");
377 * XXX Faulty directory listing? - user should be given
378 * XXX an opportunity to change the audit_control file
379 * XXX switch to a reduced mode of auditing?
385 * XXX There are synchronization problems here
386 * XXX what should we do if a trigger for the earlier limit
387 * XXX is generated here?
389 if (0 == (ret = getacmin(&minval))) {
390 syslog(LOG_DEBUG, "min free = %d", minval);
391 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
393 "could not get audit queue settings");
396 qctrl.aq_minfree = minval;
397 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
399 "could not set audit queue settings");
408 * Close all log files, control files, and tell the audit system.
415 char TS[TIMESTAMP_LEN];
420 /* Generate an audit record. */
421 if ((aufd = au_open()) == -1)
422 syslog(LOG_ERR, "Could not create audit shutdown event.");
424 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
427 * XXX we need to implement extended subject tokens so we can
428 * effectively represent terminal lines with this token type.
430 bzero(&ai, sizeof(ai));
431 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
432 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
435 if ((tok = au_to_return32(0, 0)) != NULL)
437 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
439 "Could not close audit shutdown event.");
442 /* Flush contents. */
444 err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
446 syslog(LOG_ERR, "Disabling audit failed! : %s",
452 * Post a notification that the audit config changed.
454 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
456 if (getTSstr(TS, TIMESTAMP_LEN) == 0)
458 if (lastfile != NULL)
462 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
463 syslog(LOG_ERR, "Could not unregister");
464 audit_warn_postsigterm();
470 if (close(triggerfd) != 0)
471 syslog(LOG_ERR, "Error closing control file");
473 syslog(LOG_INFO, "Finished");
478 * When we get a signal, we are often not at a clean point. So, little can
479 * be done in the signal handler itself. Instead, we send a message to the
480 * main servicing loop to do proper handling from a non-signal-handler
485 relay_signal(int signal)
487 mach_msg_empty_send_t msg;
489 msg.header.msgh_id = signal;
490 msg.header.msgh_remote_port = signal_port;
491 msg.header.msgh_local_port = MACH_PORT_NULL;
492 msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
493 mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
494 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
497 #else /* ! USE_MACH_IPC */
500 relay_signal(int signal)
503 if (signal == SIGHUP)
505 if (signal == SIGTERM)
507 if (signal == SIGCHLD)
510 #endif /* ! USE_MACH_IPC */
513 * Registering the daemon.
516 register_daemon(void)
522 /* Set up the signal hander. */
523 if (signal(SIGTERM, relay_signal) == SIG_ERR) {
525 "Could not set signal handler for SIGTERM");
528 if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
530 "Could not set signal handler for SIGCHLD");
533 if (signal(SIGHUP, relay_signal) == SIG_ERR) {
535 "Could not set signal handler for SIGHUP");
539 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
540 syslog(LOG_ERR, "Could not open PID file");
541 audit_warn_tmpfile();
545 /* Attempt to lock the pid file; if a lock is present, exit. */
546 fd = fileno(pidfile);
547 if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
549 "PID file is locked (is another auditd running?).");
556 if (fprintf(pidfile, "%u\n", pid) < 0) {
557 /* Should not start the daemon. */
567 * Implementation of the auditd_control() MIG simpleroutine.
569 * React to input from the audit(1) tool.
574 auditd_control(mach_port_t __unused auditd_port, int trigger)
580 case AUDIT_TRIGGER_ROTATE_USER:
582 * Create a new file and swap with the one
583 * being used in kernel.
585 if (swap_audit_file() == -1)
586 syslog(LOG_ERR, "Error swapping audit file");
589 case AUDIT_TRIGGER_READ_FILE:
590 if (read_control_file() == -1)
591 syslog(LOG_ERR, "Error in audit control file");
594 case AUDIT_TRIGGER_CLOSE_AND_DIE:
595 err_ret = close_all();
603 return (KERN_SUCCESS);
605 #endif /* USE_MACH_IPC */
608 * Handle the audit trigger event.
610 * We suppress (ignore) duplicated triggers in close succession in order to
611 * try to avoid thrashing-like behavior. However, not all triggers can be
612 * ignored, as triggers generally represent edge triggers, not level
613 * triggers, and won't be retransmitted if the condition persists. Of
614 * specific concern is the rotate trigger -- if one is dropped, then it will
615 * not be retransmitted, and the log file will grow in an unbounded fashion.
617 #define DUPLICATE_INTERVAL 30
619 #define AT_SUCCESS KERN_SUCCESS
623 audit_triggers(mach_port_t __unused audit_port, int trigger)
628 handle_audit_trigger(int trigger)
631 static int last_trigger, last_warning;
632 static time_t last_time;
633 struct dir_ent *dirent;
639 * Suppress duplicate messages from the kernel within the specified
642 if (gettimeofday(&ts, &tzp) == 0) {
643 tt = (time_t)ts.tv_sec;
645 case AUDIT_TRIGGER_LOW_SPACE:
646 case AUDIT_TRIGGER_NO_SPACE:
648 * Triggers we can suppress. Of course, we also need
649 * to rate limit the warnings, so apply the same
650 * interval limit on syslog messages.
652 if ((trigger == last_trigger) &&
653 (tt < (last_time + DUPLICATE_INTERVAL))) {
654 if (tt >= (last_warning + DUPLICATE_INTERVAL))
656 "Suppressing duplicate trigger %d",
663 case AUDIT_TRIGGER_ROTATE_KERNEL:
664 case AUDIT_TRIGGER_ROTATE_USER:
665 case AUDIT_TRIGGER_READ_FILE:
667 * Triggers that we cannot suppress.
673 * Only update last_trigger after aborting due to a duplicate
674 * trigger, not before, or we will never allow that trigger
677 last_trigger = trigger;
682 * Message processing is done here.
684 dirent = TAILQ_FIRST(&dir_q);
686 case AUDIT_TRIGGER_LOW_SPACE:
687 syslog(LOG_INFO, "Got low space trigger");
688 if (dirent && (dirent->softlim != 1)) {
689 TAILQ_REMOVE(&dir_q, dirent, dirs);
690 /* Add this node to the end of the list. */
691 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
692 audit_warn_soft(dirent->dirname);
695 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
696 swap_audit_file() == -1)
697 syslog(LOG_ERR, "Error swapping audit file");
700 * Check if the next dir has already reached its soft
703 dirent = TAILQ_FIRST(&dir_q);
704 if (dirent->softlim == 1) {
705 /* All dirs have reached their soft limit. */
706 audit_warn_allsoft();
710 * Continue auditing to the current file. Also
711 * generate an allsoft warning.
713 * XXX do we want to do this ?
715 audit_warn_allsoft();
719 case AUDIT_TRIGGER_NO_SPACE:
720 syslog(LOG_INFO, "Got no space trigger");
722 /* Delete current dir, go on to next. */
723 TAILQ_REMOVE(&dir_q, dirent, dirs);
724 audit_warn_hard(dirent->dirname);
725 free(dirent->dirname);
728 if (swap_audit_file() == -1)
729 syslog(LOG_ERR, "Error swapping audit file");
731 /* We are out of log directories. */
732 audit_warn_allhard(++allhardcount);
735 case AUDIT_TRIGGER_ROTATE_KERNEL:
736 case AUDIT_TRIGGER_ROTATE_USER:
738 * Create a new file and swap with the one being used in
741 syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
742 AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
743 if (swap_audit_file() == -1)
744 syslog(LOG_ERR, "Error swapping audit file");
747 case AUDIT_TRIGGER_READ_FILE:
748 syslog(LOG_INFO, "Got read file trigger");
749 if (read_control_file() == -1)
750 syslog(LOG_ERR, "Error in audit control file");
751 if (config_audit_controls() == -1)
752 syslog(LOG_ERR, "Error setting audit controls");
756 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
769 sighups_handled = sighups;
770 config_audit_controls();
774 config_audit_host(void)
776 char hoststr[MAXHOSTNAMELEN];
777 struct sockaddr_in6 *sin6;
778 struct sockaddr_in *sin;
779 struct addrinfo *res;
780 struct auditinfo_addr aia;
783 if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
785 "warning: failed to read 'host' param in control file");
787 * To maintain reverse compatability with older audit_control
788 * files, simply drop a warning if the host parameter has not
789 * been set. However, we will explicitly disable the
790 * generation of extended audit header by passing in a zeroed
793 bzero(&aia, sizeof(aia));
794 aia.ai_termid.at_type = AU_IPv4;
795 error = auditon(A_SETKAUDIT, &aia, sizeof(aia));
796 if (error < 0 && errno == ENOSYS)
798 else if (error < 0) {
800 "Failed to set audit host info");
805 error = getaddrinfo(hoststr, NULL, NULL, &res);
807 syslog(LOG_ERR, "Failed to lookup hostname: %s", hoststr);
810 switch (res->ai_family) {
812 sin6 = (struct sockaddr_in6 *) res->ai_addr;
813 bcopy(&sin6->sin6_addr.s6_addr,
814 &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
815 aia.ai_termid.at_type = AU_IPv6;
818 sin = (struct sockaddr_in *) res->ai_addr;
819 bcopy(&sin->sin_addr.s_addr,
820 &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
821 aia.ai_termid.at_type = AU_IPv4;
825 "Un-supported address family in host parameter");
828 if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) {
830 "auditon: failed to set audit host information");
845 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
848 syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
849 ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
850 "exited as a result of signal"),
851 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
860 sigchlds_handled = sigchlds;
865 * Read the control file for triggers/signals and handle appropriately.
868 #define MAX_MSG_SIZE 4096
871 auditd_combined_server(mach_msg_header_t *InHeadP,
872 mach_msg_header_t *OutHeadP)
874 mach_port_t local_port = InHeadP->msgh_local_port;
876 if (local_port == signal_port) {
877 int signo = InHeadP->msgh_id;
894 syslog(LOG_INFO, "Received signal %d", signo);
897 } else if (local_port == control_port) {
900 result = audit_triggers_server(InHeadP, OutHeadP);
902 result = auditd_control_server(InHeadP, OutHeadP);
905 syslog(LOG_INFO, "Recevied msg on bad port 0x%x.", local_port);
910 wait_for_events(void)
912 kern_return_t result;
914 result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
915 port_set, MACH_MSG_OPTION_NONE);
916 syslog(LOG_ERR, "abnormal exit\n");
917 return (close_all());
920 #else /* ! USE_MACH_IPC */
923 wait_for_events(void)
926 unsigned int trigger;
929 num = read(triggerfd, &trigger, sizeof(trigger));
930 if ((num == -1) && (errno != EINTR)) {
931 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
934 if (sigterms != sigterms_handled) {
935 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
938 if (sigchlds != sigchlds_handled)
940 if (sighups != sighups_handled) {
941 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
944 if ((num == -1) && (errno == EINTR))
947 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
950 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
953 (void)handle_audit_trigger(trigger);
955 return (close_all());
957 #endif /* ! USE_MACH_IPC */
960 * Configure the audit controls in the kernel: the event to class mapping,
961 * kernel preselection mask, etc.
964 config_audit_controls(void)
966 au_event_ent_t ev, *evp;
967 au_evclass_map_t evc_map;
970 char naeventstr[NA_EVENT_STR_SIZE];
971 char polstr[POL_STR_SIZE];
977 * Process the audit event file, obtaining a class mapping for each
978 * event, and send that mapping into the kernel.
980 * XXX There's a risk here that the BSM library will return NULL
981 * for an event when it can't properly map it to a class. In that
982 * case, we will not process any events beyond the one that failed,
983 * but should. We need a way to get a count of the events.
985 ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
986 ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
987 if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
988 if (ev.ae_name != NULL)
991 "Memory allocation error when configuring audit controls.");
996 * XXXRW: Currently we have no way to remove mappings from the kernel
997 * when they are removed from the file-based mappings.
1001 while ((evp = getauevent_r(evp)) != NULL) {
1002 evc_map.ec_number = evp->ae_number;
1003 evc_map.ec_class = evp->ae_class;
1004 if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
1007 "Failed to register class mapping for event %s",
1016 syslog(LOG_ERR, "No events to class mappings registered.");
1018 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
1022 * Get the non-attributable event string and set the kernel mask from
1025 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
1026 (getauditflagsbin(naeventstr, &aumask) == 0)) {
1027 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
1029 "Failed to register non-attributable event mask.");
1032 "Registered non-attributable event mask.");
1035 "Failed to obtain non-attributable event mask.");
1038 * If a policy is configured in audit_control(5), implement the
1039 * policy. However, if one isn't defined, set AUDIT_CNT to avoid
1040 * leaving the system in a fragile state.
1042 if ((getacpol(polstr, POL_STR_SIZE) == 0) &&
1043 (au_strtopol(polstr, &policy) == 0)) {
1044 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
1045 syslog(LOG_ERR, "Failed to set audit policy: %m");
1047 syslog(LOG_ERR, "Failed to obtain policy flags: %m");
1049 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
1051 "Failed to set default audit policy: %m");
1055 * Set trail rotation size.
1057 if (getacfilesz(&filesz) == 0) {
1058 bzero(&au_fstat, sizeof(au_fstat));
1059 au_fstat.af_filesz = filesz;
1060 if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0)
1061 syslog(LOG_ERR, "Failed to set filesz: %m");
1063 syslog(LOG_ERR, "Failed to obtain filesz: %m");
1065 return (config_audit_host());
1072 mach_msg_type_name_t poly;
1075 * Allocate a port set
1077 if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
1078 &port_set) != KERN_SUCCESS) {
1079 syslog(LOG_ERR, "Allocation of port set failed");
1084 * Allocate a signal reflection port
1086 if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
1087 &signal_port) != KERN_SUCCESS ||
1088 mach_port_move_member(mach_task_self(), signal_port, port_set) !=
1090 syslog(LOG_ERR, "Allocation of signal port failed");
1095 * Allocate a trigger port
1097 if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
1098 &control_port) != KERN_SUCCESS ||
1099 mach_port_move_member(mach_task_self(), control_port, port_set)
1101 syslog(LOG_ERR, "Allocation of trigger port failed");
1104 * Create a send right on our trigger port.
1106 mach_port_extract_right(mach_task_self(), control_port,
1107 MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
1110 * Register the trigger port with the kernel.
1112 if (host_set_audit_control_port(mach_host_self(), control_port) !=
1114 syslog(LOG_ERR, "Cannot set Mach control port");
1117 syslog(LOG_DEBUG, "Mach control port registered");
1119 #endif /* USE_MACH_IPC */
1124 struct auditinfo ai;
1132 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
1133 syslog(LOG_ERR, "Error opening trigger file");
1139 * To prevent event feedback cycles and avoid auditd becoming
1140 * stalled if auditing is suspended, auditd and its children run
1141 * without their events being audited. We allow the uid, tid, and
1142 * mask fields to be implicitly set to zero, but do set the pid. We
1143 * run this after opening the trigger device to avoid configuring
1144 * audit state without audit present in the system.
1146 * XXXRW: Is there more to it than this?
1148 bzero(&auinfo, sizeof(auinfo));
1149 auinfo.ai_asid = getpid();
1150 if (setaudit(&auinfo) == -1) {
1151 syslog(LOG_ERR, "Error setting audit stat");
1156 if (read_control_file() == -1) {
1157 syslog(LOG_ERR, "Error reading control file");
1161 /* Generate an audit record. */
1162 if ((aufd = au_open()) == -1)
1163 syslog(LOG_ERR, "Could not create audit startup event.");
1166 * XXXCSJP Perhaps we want more robust audit records for
1167 * audit start up and shutdown. This might include capturing
1168 * failures to initialize the audit subsystem?
1170 bzero(&ai, sizeof(ai));
1171 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
1172 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
1174 au_write(aufd, tok);
1175 if ((tok = au_to_text("auditd::Audit startup")) != NULL)
1176 au_write(aufd, tok);
1177 if ((tok = au_to_return32(0, 0)) != NULL)
1178 au_write(aufd, tok);
1179 if (au_close(aufd, 1, AUE_audit_startup) == -1)
1181 "Could not close audit startup event.");
1184 if (config_audit_controls() == 0)
1185 syslog(LOG_INFO, "Audit controls init successful");
1187 syslog(LOG_ERR, "Audit controls init failed");
1191 main(int argc, char **argv)
1197 while ((ch = getopt(argc, argv, "d")) != -1) {
1206 (void)fprintf(stderr,
1207 "usage: auditd [-d] \n");
1212 logopts = LOG_CONS | LOG_PID;
1214 logopts |= LOG_PERROR;
1217 openlog("auditd", logopts, LOG_SECURITY);
1219 openlog("auditd", logopts, LOG_AUTH);
1221 syslog(LOG_INFO, "starting...");
1223 if (debug == 0 && daemon(0, 0) == -1) {
1224 syslog(LOG_ERR, "Failed to daemonize");
1228 if (register_daemon() == -1) {
1229 syslog(LOG_ERR, "Could not register as daemon");
1235 rc = wait_for_events();
1236 syslog(LOG_INFO, "auditd exiting.");