2 * Copyright (c) 2004-2009 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_fbsd.c#4 $
32 #include <sys/types.h>
34 #include <config/config.h>
44 #include <bsm/audit.h>
45 #include <bsm/audit_uevents.h>
46 #include <bsm/auditd_lib.h>
47 #include <bsm/libbsm.h>
52 * Current auditing state (cache).
54 static int auditing_state = AUD_STATE_INIT;
57 * Maximum idle time before auditd terminates under launchd.
58 * If it is zero then auditd does not timeout while idle.
60 static int max_idletime = 0;
62 static int sigchlds, sigchlds_handled;
63 static int sighups, sighups_handled;
64 static int sigterms, sigterms_handled;
65 static int sigalrms, sigalrms_handled;
67 static int triggerfd = 0;
70 * Open and set up system logging.
73 auditd_openlog(int debug, gid_t __unused gid)
75 int logopts = LOG_CONS | LOG_PID;
78 logopts |= LOG_PERROR;
81 openlog("auditd", logopts, LOG_SECURITY);
83 openlog("auditd", logopts, LOG_AUTH);
88 * Log messages at different priority levels.
91 auditd_log_err(const char *fmt, ...)
96 vsyslog(LOG_ERR, fmt, ap);
101 auditd_log_notice(const char *fmt, ...)
106 vsyslog(LOG_NOTICE, fmt, ap);
111 auditd_log_info(const char *fmt, ...)
116 vsyslog(LOG_INFO, fmt, ap);
121 auditd_log_debug(const char *fmt, ...)
126 vsyslog(LOG_DEBUG, fmt, ap);
131 * Get the auditing state from the kernel and cache it.
134 init_audit_state(void)
138 if (audit_get_cond(&au_cond) < 0) {
139 if (errno != ENOSYS) {
140 auditd_log_err("Audit status check failed (%s)",
143 auditing_state = AUD_STATE_DISABLED;
145 if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED)
146 auditing_state = AUD_STATE_DISABLED;
148 auditing_state = AUD_STATE_ENABLED;
152 * Update the cached auditing state.
155 auditd_set_state(int state)
157 int old_auditing_state = auditing_state;
159 if (state == AUD_STATE_INIT)
162 auditing_state = state;
164 if (auditing_state != old_auditing_state) {
165 if (auditing_state == AUD_STATE_ENABLED)
166 auditd_log_notice("Auditing enabled");
167 if (auditing_state == AUD_STATE_DISABLED)
168 auditd_log_notice("Auditing disabled");
173 * Get the cached auditing state.
176 auditd_get_state(void)
179 if (auditing_state == AUD_STATE_INIT)
182 return (auditing_state);
186 * Open the trigger messaging mechanism.
189 auditd_open_trigger(int __unused launchd_flag)
192 return ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)));
196 * Close the trigger messaging mechanism.
199 auditd_close_trigger(void)
202 return (close(triggerfd));
206 * The main event loop. Wait for trigger messages or signals and handle them.
207 * It should not return unless there is a problem.
210 auditd_wait_for_events(void)
213 unsigned int trigger;
216 num = read(triggerfd, &trigger, sizeof(trigger));
217 if ((num == -1) && (errno != EINTR)) {
218 auditd_log_err("%s: error %d", __FUNCTION__, errno);
222 /* Reset the idle time alarm, if used. */
226 if (sigterms != sigterms_handled) {
227 auditd_log_debug("%s: SIGTERM", __FUNCTION__);
231 if (sigalrms != sigalrms_handled) {
232 auditd_log_debug("%s: SIGALRM", __FUNCTION__);
236 if (sigchlds != sigchlds_handled) {
237 sigchlds_handled = sigchlds;
238 auditd_reap_children();
240 if (sighups != sighups_handled) {
241 auditd_log_debug("%s: SIGHUP", __FUNCTION__);
242 sighups_handled = sighups;
243 auditd_config_controls();
246 if ((num == -1) && (errno == EINTR))
249 auditd_log_err("%s: read EOF", __FUNCTION__);
252 auditd_handle_trigger(trigger);
257 * When we get a signal, we are often not at a clean point. So, little can
258 * be done in the signal handler itself. Instead, we send a message to the
259 * main servicing loop to do proper handling from a non-signal-handler
263 auditd_relay_signal(int signal)
265 if (signal == SIGHUP)
267 if (signal == SIGTERM)
269 if (signal == SIGCHLD)
271 if (signal == SIGALRM)