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