1 /*- 2 * Copyright (c) 2004-2009 Apple Inc. 3 * All rights reserved. 4 * 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 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 * 29 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd_fbsd.c#4 $ 30 */ 31 32 #include <sys/types.h> 33 34 #include <config/config.h> 35 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <stdarg.h> 39 #include <signal.h> 40 #include <string.h> 41 #include <syslog.h> 42 #include <unistd.h> 43 44 #include <bsm/audit.h> 45 #include <bsm/audit_uevents.h> 46 #include <bsm/auditd_lib.h> 47 #include <bsm/libbsm.h> 48 49 #include "auditd.h" 50 51 /* 52 * Current auditing state (cache). 53 */ 54 static int auditing_state = AUD_STATE_INIT; 55 56 /* 57 * Maximum idle time before auditd terminates under launchd. 58 * If it is zero then auditd does not timeout while idle. 59 */ 60 static int max_idletime = 0; 61 62 static int sigchlds, sigchlds_handled; 63 static int sighups, sighups_handled; 64 static int sigterms, sigterms_handled; 65 static int sigalrms, sigalrms_handled; 66 67 static int triggerfd = 0; 68 69 /* 70 * Open and set up system logging. 71 */ 72 void 73 auditd_openlog(int debug, gid_t __unused gid) 74 { 75 int logopts = LOG_CONS | LOG_PID; 76 77 if (debug) 78 logopts |= LOG_PERROR; 79 80 #ifdef LOG_SECURITY 81 openlog("auditd", logopts, LOG_SECURITY); 82 #else 83 openlog("auditd", logopts, LOG_AUTH); 84 #endif 85 } 86 87 /* 88 * Log messages at different priority levels. 89 */ 90 void 91 auditd_log_err(const char *fmt, ...) 92 { 93 va_list ap; 94 95 va_start(ap, fmt); 96 vsyslog(LOG_ERR, fmt, ap); 97 va_end(ap); 98 } 99 100 void 101 auditd_log_notice(const char *fmt, ...) 102 { 103 va_list ap; 104 105 va_start(ap, fmt); 106 vsyslog(LOG_NOTICE, fmt, ap); 107 va_end(ap); 108 } 109 110 void 111 auditd_log_info(const char *fmt, ...) 112 { 113 va_list ap; 114 115 va_start(ap, fmt); 116 vsyslog(LOG_INFO, fmt, ap); 117 va_end(ap); 118 } 119 120 void 121 auditd_log_debug(const char *fmt, ...) 122 { 123 va_list ap; 124 125 va_start(ap, fmt); 126 vsyslog(LOG_DEBUG, fmt, ap); 127 va_end(ap); 128 } 129 130 /* 131 * Get the auditing state from the kernel and cache it. 132 */ 133 static void 134 init_audit_state(void) 135 { 136 int au_cond; 137 138 if (audit_get_cond(&au_cond) < 0) { 139 if (errno != ENOSYS) { 140 auditd_log_err("Audit status check failed (%s)", 141 strerror(errno)); 142 } 143 auditing_state = AUD_STATE_DISABLED; 144 } else 145 if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED) 146 auditing_state = AUD_STATE_DISABLED; 147 else 148 auditing_state = AUD_STATE_ENABLED; 149 } 150 151 /* 152 * Update the cached auditing state. 153 */ 154 void 155 auditd_set_state(int state) 156 { 157 int old_auditing_state = auditing_state; 158 159 if (state == AUD_STATE_INIT) 160 init_audit_state(); 161 else 162 auditing_state = state; 163 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"); 169 } 170 } 171 172 /* 173 * Get the cached auditing state. 174 */ 175 int 176 auditd_get_state(void) 177 { 178 179 if (auditing_state == AUD_STATE_INIT) 180 init_audit_state(); 181 182 return (auditing_state); 183 } 184 185 /* 186 * Open the trigger messaging mechanism. 187 */ 188 int 189 auditd_open_trigger(int __unused launchd_flag) 190 { 191 192 return ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0))); 193 } 194 195 /* 196 * Close the trigger messaging mechanism. 197 */ 198 int 199 auditd_close_trigger(void) 200 { 201 202 return (close(triggerfd)); 203 } 204 205 /* 206 * The main event loop. Wait for trigger messages or signals and handle them. 207 * It should not return unless there is a problem. 208 */ 209 void 210 auditd_wait_for_events(void) 211 { 212 int num; 213 unsigned int trigger; 214 215 for (;;) { 216 num = read(triggerfd, &trigger, sizeof(trigger)); 217 if ((num == -1) && (errno != EINTR)) { 218 auditd_log_err("%s: error %d", __FUNCTION__, errno); 219 return; 220 } 221 222 /* Reset the idle time alarm, if used. */ 223 if (max_idletime) 224 alarm(max_idletime); 225 226 if (sigterms != sigterms_handled) { 227 auditd_log_debug("%s: SIGTERM", __FUNCTION__); 228 auditd_terminate(); 229 /* not reached */ 230 } 231 if (sigalrms != sigalrms_handled) { 232 auditd_log_debug("%s: SIGALRM", __FUNCTION__); 233 auditd_terminate(); 234 /* not reached */ 235 } 236 if (sigchlds != sigchlds_handled) { 237 sigchlds_handled = sigchlds; 238 auditd_reap_children(); 239 } 240 if (sighups != sighups_handled) { 241 auditd_log_debug("%s: SIGHUP", __FUNCTION__); 242 sighups_handled = sighups; 243 auditd_config_controls(); 244 } 245 246 if ((num == -1) && (errno == EINTR)) 247 continue; 248 if (num == 0) { 249 auditd_log_err("%s: read EOF", __FUNCTION__); 250 return; 251 } 252 auditd_handle_trigger(trigger); 253 } 254 } 255 256 /* 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 260 * context. 261 */ 262 void 263 auditd_relay_signal(int signal) 264 { 265 if (signal == SIGHUP) 266 sighups++; 267 if (signal == SIGTERM) 268 sigterms++; 269 if (signal == SIGCHLD) 270 sigchlds++; 271 if (signal == SIGALRM) 272 sigalrms++; 273 } 274 275