Deleted Added
full compact
auditd.c (185573) auditd.c (186647)
1/*-
2 * Copyright (c) 2004-2008 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 *

--- 12 unchanged lines hidden (view full) ---

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 *
1/*-
2 * Copyright (c) 2004-2008 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 *

--- 12 unchanged lines hidden (view full) ---

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.c#39 $
29 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#40 $
30 */
31
30 */
31
32#include <sys/param.h>
32#include <sys/types.h>
33
34#include <config/config.h>
35
36#include <sys/dirent.h>
33
34#include <config/config.h>
35
36#include <sys/dirent.h>
37#include <sys/mman.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 */
37#ifdef HAVE_FULL_QUEUE_H
38#include <sys/queue.h>
39#else /* !HAVE_FULL_QUEUE_H */
40#include <compat/queue.h>
41#endif /* !HAVE_FULL_QUEUE_H */
42#include <sys/mman.h>
43#include <sys/param.h>
44#include <sys/stat.h>
45#include <sys/wait.h>
46
47#include <bsm/audit.h>
48#include <bsm/audit_uevents.h>
44#include <sys/stat.h>
45#include <sys/wait.h>
46
47#include <bsm/audit.h>
48#include <bsm/audit_uevents.h>
49#include <bsm/auditd_lib.h>
49#include <bsm/libbsm.h>
50
50#include <bsm/libbsm.h>
51
51#include <netinet/in.h>
52
53#include <err.h>
54#include <errno.h>
55#include <fcntl.h>
56#include <grp.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <time.h>
60#include <unistd.h>
61#include <signal.h>
62#include <string.h>
52#include <err.h>
53#include <errno.h>
54#include <fcntl.h>
55#include <grp.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <time.h>
59#include <unistd.h>
60#include <signal.h>
61#include <string.h>
63#include <syslog.h>
64#include <netdb.h>
65
66#include "auditd.h"
62
63#include "auditd.h"
67#ifdef USE_MACH_IPC
68#include <notify.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>
74
64
75#include "auditd_control_server.h"
76#include "audit_triggers_server.h"
77#endif /* USE_MACH_IPC */
78
79#ifndef HAVE_STRLCPY
80#include <compat/strlcpy.h>
81#endif
82
65#ifndef HAVE_STRLCPY
66#include <compat/strlcpy.h>
67#endif
68
83#define NA_EVENT_STR_SIZE 25
84#define POL_STR_SIZE 128
85static int ret, minval;
86static char *lastfile = NULL;
87static int allhardcount = 0;
88static int sigchlds, sigchlds_handled;
89static int sighups, sighups_handled;
90#ifndef USE_MACH_IPC
91static int sigterms, sigterms_handled;
92static int triggerfd = 0;
69/*
70 * XXX the following is temporary until this can be added to the kernel
71 * audit.h header.
72 */
73#ifndef AUDIT_TRIGGER_INITIALIZE
74#define AUDIT_TRIGGER_INITIALIZE 7
75#endif
93
76
94#else /* USE_MACH_IPC */
77/*
78 * LaunchD flag (Mac OS X and, maybe, FreeBSD only.) See launchd(8) and
79 * http://wiki.freebsd.org/launchd for more information.
80 *
81 * In order for auditd to work "on demand" with launchd(8) it can't:
82 * call daemon(3)
83 * call fork and having the parent process exit
84 * change uids or gids.
85 * set up the current working directory or chroot.
86 * set the session id
87 * change stdio to /dev/null.
88 * call setrusage(2)
89 * call setpriority(2)
90 * Ignore SIGTERM.
91 * auditd (in 'launchd mode') is launched on demand so it must catch
92 * SIGTERM to exit cleanly.
93 */
94static int launchd_flag = 0;
95
95
96static mach_port_t control_port = MACH_PORT_NULL;
97static mach_port_t signal_port = MACH_PORT_NULL;
98static mach_port_t port_set = MACH_PORT_NULL;
96/*
97 * The GID of the audit review group (if used). The audit trail files and
98 * system logs (Mac OS X only) can only be reviewed by members of this group
99 * or the audit administrator (aka. "root").
100 */
101static gid_t audit_review_gid = -1;
99
102
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 */
103/*
104 * The path and file name of the last audit trail file.
105 */
106static char *lastfile = NULL;
104
107
105static TAILQ_HEAD(, dir_ent) dir_q;
106
107static int config_audit_controls(void);
108
109/*
108/*
110 * Error starting auditd
109 * Error starting auditd. Run warn script and exit.
111 */
112static void
113fail_exit(void)
114{
115
116 audit_warn_nostart();
117 exit(1);
118}
119
120/*
110 */
111static void
112fail_exit(void)
113{
114
115 audit_warn_nostart();
116 exit(1);
117}
118
119/*
121 * Free our local list of directory names.
120 * Follow the 'current' symlink to get the active trail file name.
122 */
121 */
123static void
124free_dir_q(void)
122static char *
123get_curfile(void)
125{
124{
126 struct dir_ent *dirent;
125 char *cf;
126 int len;
127
127
128 while ((dirent = TAILQ_FIRST(&dir_q))) {
129 TAILQ_REMOVE(&dir_q, dirent, dirs);
130 free(dirent->dirname);
131 free(dirent);
128 cf = malloc(MAXPATHLEN);
129 if (cf == NULL) {
130 auditd_log_err("malloc failed: %m");
131 return (NULL);
132 }
133
134 len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1);
135 if (len < 0) {
136 free(cf);
137 return (NULL);
132 }
138 }
133}
134
139
135/*
136 * Generate the timestamp string.
137 */
138static int
139getTSstr(char *buf, int len)
140{
141 struct timeval ts;
142 struct timezone tzp;
143 time_t tt;
140 /* readlink() doesn't terminate string. */
141 cf[len] = '\0';
144
142
145 if (gettimeofday(&ts, &tzp) != 0)
146 return (-1);
147 tt = (time_t)ts.tv_sec;
148 if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
149 return (-1);
150 return (0);
143 return (cf);
151}
152
153/*
144}
145
146/*
154 * Concat the directory name to the given file name.
155 * XXX We should affix the hostname also
156 */
157static char *
158affixdir(char *name, struct dir_ent *dirent)
159{
160 char *fn = NULL;
161
162 syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
163 /*
164 * Sanity check on file name.
165 */
166 if (strlen(name) != (FILENAME_LEN - 1)) {
167 syslog(LOG_ERR, "Invalid file name: %s", name);
168 return (NULL);
169 }
170 asprintf(&fn, "%s/%s", dirent->dirname, name);
171 return (fn);
172}
173
174/*
175 * Close the previous audit trail file.
176 */
177static int
178close_lastfile(char *TS)
179{
180 char *ptr;
181 char *oldname;
182 size_t len;
183
147 * Close the previous audit trail file.
148 */
149static int
150close_lastfile(char *TS)
151{
152 char *ptr;
153 char *oldname;
154 size_t len;
155
156 /* If lastfile is NULL try to get it from the 'current' link. */
157 if (lastfile == NULL)
158 lastfile = get_curfile();
159
184 if (lastfile != NULL) {
185 len = strlen(lastfile) + 1;
186 oldname = (char *)malloc(len);
187 if (oldname == NULL)
188 return (-1);
189 strlcpy(oldname, lastfile, len);
190
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)
160 if (lastfile != NULL) {
161 len = strlen(lastfile) + 1;
162 oldname = (char *)malloc(len);
163 if (oldname == NULL)
164 return (-1);
165 strlcpy(oldname, lastfile, len);
166
167 /* Rename the last file -- append timestamp. */
168 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
169 strlcpy(ptr, TS, TIMESTAMP_LEN);
170 if (rename(oldname, lastfile) != 0)
195 syslog(LOG_ERR,
171 auditd_log_err(
196 "Could not rename %s to %s: %m", oldname,
197 lastfile);
198 else {
172 "Could not rename %s to %s: %m", oldname,
173 lastfile);
174 else {
199 syslog(LOG_INFO, "renamed %s to %s",
175 /*
176 * Remove the 'current' symlink since the link
177 * is now invalid.
178 */
179 (void) unlink(AUDIT_CURRENT_LINK);
180 auditd_log_notice( "renamed %s to %s",
200 oldname, lastfile);
201 audit_warn_closefile(lastfile);
202 }
203 } else
181 oldname, lastfile);
182 audit_warn_closefile(lastfile);
183 }
184 } else
204 syslog(LOG_ERR, "Could not rename %s to %s", oldname,
185 auditd_log_err( "Could not rename %s to %s", oldname,
205 lastfile);
206 free(lastfile);
207 free(oldname);
208 lastfile = NULL;
209 }
210 return (0);
211}
212
213/*
186 lastfile);
187 free(lastfile);
188 free(oldname);
189 lastfile = NULL;
190 }
191 return (0);
192}
193
194/*
214 * Create the new audit file with appropriate permissions and ownership. Try
215 * to clean up if something goes wrong.
216 */
217static int
218#ifdef AUDIT_REVIEW_GROUP
219open_trail(const char *fname, uid_t uid, gid_t gid)
220#else
221open_trail(const char *fname)
222#endif
223{
224 int error, fd;
225
226 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
227 if (fd < 0)
228 return (-1);
229#ifdef AUDIT_REVIEW_GROUP
230 if (fchown(fd, uid, gid) < 0) {
231 error = errno;
232 close(fd);
233 (void)unlink(fname);
234 errno = error;
235 return (-1);
236 }
237#endif
238 return (fd);
239}
240
241/*
242 * Create the new file name, swap with existing audit file.
243 */
244static int
245swap_audit_file(void)
246{
195 * Create the new file name, swap with existing audit file.
196 */
197static int
198swap_audit_file(void)
199{
247 char timestr[FILENAME_LEN];
248 char *fn;
200 int err;
201 char *newfile;
249 char TS[TIMESTAMP_LEN];
202 char TS[TIMESTAMP_LEN];
250 struct dir_ent *dirent;
251#ifdef AUDIT_REVIEW_GROUP
252 struct group *grp;
253 gid_t gid;
254 uid_t uid;
255#endif
256 int error, fd;
203 time_t tt;
257
204
258 if (getTSstr(TS, TIMESTAMP_LEN) != 0)
205 if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
259 return (-1);
206 return (-1);
207 err = auditd_swap_trail(TS, &newfile, audit_review_gid,
208 audit_warn_getacdir);
209 if (err != ADE_NOERR) {
210 auditd_log_err( "%s: %m", auditd_strerror(err));
211 if (err != ADE_ACTL)
212 return (-1);
213 }
260
214
261 snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED);
262
263#ifdef AUDIT_REVIEW_GROUP
264 /*
215 /*
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?
216 * Only close the last file if were in an auditing state before
217 * calling swap_audit_file(). We may need to recover from a crash.
267 */
218 */
268 grp = getgrnam(AUDIT_REVIEW_GROUP);
269 if (grp == NULL) {
270 syslog(LOG_INFO,
271 "Audit review group '%s' not available, using daemon gid",
272 AUDIT_REVIEW_GROUP);
273 gid = -1;
274 } else
275 gid = grp->gr_gid;
276 uid = getuid();
277#endif
219 if (auditd_get_state() == AUD_STATE_ENABLED)
220 close_lastfile(TS);
278
221
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",
283 timestr);
284 return (-1);
285 }
286
222
287 /*
288 * Create and open the file; then close and pass to the
289 * kernel if all went well.
290 */
291 syslog(LOG_INFO, "New audit file is %s", fn);
292#ifdef AUDIT_REVIEW_GROUP
293 fd = open_trail(fn, uid, gid);
294#else
295 fd = open_trail(fn);
296#endif
297 if (fd < 0)
298 warn("open(%s)", fn);
299 if (fd >= 0) {
300 error = auditctl(fn);
301 if (error) {
302 syslog(LOG_ERR,
303 "auditctl failed setting log file! : %s",
304 strerror(errno));
305 close(fd);
306 } else {
307 /* Success. */
308#ifdef USE_MACH_IPC
309 /*
310 * auditctl() potentially changes the audit
311 * state so post that the audit config (may
312 * have) changed.
313 */
314 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
315#endif
316 close_lastfile(TS);
317 lastfile = fn;
318 close(fd);
319 return (0);
320 }
321 }
223 /*
224 * auditd_swap_trail() potentially enables auditing (if not already
225 * enabled) so updated the cached state as well.
226 */
227 auditd_set_state(AUD_STATE_ENABLED);
228
229 /*
230 * Create 'current' symlink. Recover from crash, if needed.
231 */
232 if (auditd_new_curlink(newfile) != 0)
233 auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m",
234 newfile, auditd_strerror(err));
322
235
323 /*
324 * Tell the administrator about lack of permissions for dir.
325 */
326 audit_warn_getacdir(dirent->dirname);
236 lastfile = newfile;
237 auditd_log_notice("New audit file is %s", newfile);
327
238
328 /* Try again with a different directory. */
329 TAILQ_REMOVE(&dir_q, dirent, dirs);
330 free(dirent->dirname);
331 free(dirent);
332 }
333 syslog(LOG_ERR, "Log directories exhausted");
334 return (-1);
239 return (0);
335}
336
337/*
240}
241
242/*
338 * Read the audit_control file contents.
243 * Create a new audit log trail file and swap with the current one, if any.
339 */
340static int
244 */
245static int
341read_control_file(void)
246do_trail_file(void)
342{
247{
343 char cur_dir[MAXNAMLEN];
344 struct dir_ent *dirent;
345 au_qctrl_t qctrl;
248 int err;
346
347 /*
249
250 /*
348 * Clear old values. Force a re-read of the file the next time.
251 * First, refresh the list of audit log directories.
349 */
252 */
350 free_dir_q();
351 endac();
352
353 /*
354 * Read the list of directories into a local linked list.
355 *
356 * XXX We should use the reentrant interfaces once they are
357 * available.
358 */
359 while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
360 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
361 if (dirent == NULL)
253 err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
254 if (err) {
255 auditd_log_err("auditd_read_dirs() %s: %m",
256 auditd_strerror(err));
257 if (err == ADE_HARDLIM)
258 audit_warn_allhard();
259 if (err != ADE_SOFTLIM)
362 return (-1);
260 return (-1);
363 dirent->softlim = 0;
364 dirent->dirname = (char *) malloc(MAXNAMLEN);
365 if (dirent->dirname == NULL) {
366 free(dirent);
367 return (-1);
368 }
369 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
370 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
261 else
262 audit_warn_allsoft();
263 /* continue on with soft limit error */
371 }
372
264 }
265
373 allhardcount = 0;
266 /*
267 * Create a new file and swap with the one being used in kernel.
268 */
374 if (swap_audit_file() == -1) {
269 if (swap_audit_file() == -1) {
375 syslog(LOG_ERR, "Could not swap audit file");
376 /*
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?
380 */
381 return (-1);
382 }
383
270 /*
271 * XXX Faulty directory listing? - user should be given
272 * XXX an opportunity to change the audit_control file
273 * XXX switch to a reduced mode of auditing?
274 */
275 return (-1);
276 }
277
384 /*
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?
388 */
389 if (0 == (ret = getacmin(&minval))) {
390 syslog(LOG_DEBUG, "min free = %d", minval);
391 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
392 syslog(LOG_ERR,
393 "could not get audit queue settings");
394 return (-1);
395 }
396 qctrl.aq_minfree = minval;
397 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
398 syslog(LOG_ERR,
399 "could not set audit queue settings");
400 return (-1);
401 }
278 return (0);
279}
280
281/*
282 * Start up auditing.
283 */
284static void
285audit_setup(void)
286{
287 int err;
288
289 if (do_trail_file() == -1) {
290 auditd_log_err("Error creating audit trail file");
291 fail_exit();
402 }
403
292 }
293
294 /* Generate an audit record. */
295 err = auditd_gen_record(AUE_audit_startup, NULL);
296 if (err)
297 auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m",
298 auditd_strerror(err));
299
300 if (auditd_config_controls() == 0)
301 auditd_log_info("Audit controls init successful");
302 else
303 auditd_log_err("Audit controls init failed");
304
305}
306
307
308/*
309 * Close auditd pid file and trigger mechanism.
310 */
311static int
312close_misc(void)
313{
314
315 auditd_close_dirs();
316 if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) {
317 auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE);
318 return (1);
319 }
320 endac();
321
322 if (auditd_close_trigger() != 0) {
323 auditd_log_err("Error closing trigger messaging mechanism");
324 return (1);
325 }
404 return (0);
405}
406
407/*
408 * Close all log files, control files, and tell the audit system.
409 */
410static int
411close_all(void)
412{
326 return (0);
327}
328
329/*
330 * Close all log files, control files, and tell the audit system.
331 */
332static int
333close_all(void)
334{
413 struct auditinfo ai;
414 int err_ret = 0;
415 char TS[TIMESTAMP_LEN];
335 int err_ret = 0;
336 char TS[TIMESTAMP_LEN];
416 int aufd;
417 token_t *tok;
337 int err;
418 long cond;
338 long cond;
339 time_t tt;
419
340
420 /* Generate an audit record. */
421 if ((aufd = au_open()) == -1)
422 syslog(LOG_ERR, "Could not create audit shutdown event.");
423 else {
424 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
425 au_write(aufd, tok);
426 /*
427 * XXX we need to implement extended subject tokens so we can
428 * effectively represent terminal lines with this token type.
429 */
430 bzero(&ai, sizeof(ai));
431 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
432 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
433 != NULL)
434 au_write(aufd, tok);
435 if ((tok = au_to_return32(0, 0)) != NULL)
436 au_write(aufd, tok);
437 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
438 syslog(LOG_ERR,
439 "Could not close audit shutdown event.");
440 }
341 err = auditd_gen_record(AUE_audit_shutdown, NULL);
342 if (err)
343 auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m",
344 auditd_strerror(err));
441
442 /* Flush contents. */
443 cond = AUC_DISABLED;
444 err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
445 if (err_ret != 0) {
345
346 /* Flush contents. */
347 cond = AUC_DISABLED;
348 err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
349 if (err_ret != 0) {
446 syslog(LOG_ERR, "Disabling audit failed! : %s",
447 strerror(errno));
350 auditd_log_err("Disabling audit failed! : %s", strerror(errno));
448 err_ret = 1;
449 }
351 err_ret = 1;
352 }
450#ifdef USE_MACH_IPC
451 /*
452 * Post a notification that the audit config changed.
353
354 /*
355 * Updated the cached state that auditing has been disabled.
453 */
356 */
454 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
455#endif
456 if (getTSstr(TS, TIMESTAMP_LEN) == 0)
357 auditd_set_state(AUD_STATE_DISABLED);
358
359 if (getTSstr(tt, TS, TIMESTAMP_LEN) == 0)
457 close_lastfile(TS);
458 if (lastfile != NULL)
459 free(lastfile);
460
360 close_lastfile(TS);
361 if (lastfile != NULL)
362 free(lastfile);
363
461 free_dir_q();
462 if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
463 syslog(LOG_ERR, "Could not unregister");
364 err_ret += close_misc();
365
366 if (err_ret) {
367 auditd_log_err("Could not unregister");
464 audit_warn_postsigterm();
368 audit_warn_postsigterm();
465 return (1);
466 }
369 }
467 endac();
468
370
469#ifndef USE_MACH_IPC
470 if (close(triggerfd) != 0)
471 syslog(LOG_ERR, "Error closing control file");
472#endif
473 syslog(LOG_INFO, "Finished");
474 return (0);
371 auditd_log_info("Finished");
372 return (err_ret);
475}
476
477/*
373}
374
375/*
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
481 * context.
376 * Register the daemon with the signal handler and the auditd pid file.
482 */
377 */
483#ifdef USE_MACH_IPC
484static void
485relay_signal(int signal)
486{
487 mach_msg_empty_send_t msg;
488
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);
495}
496
497#else /* ! USE_MACH_IPC */
498
499static void
500relay_signal(int signal)
501{
502
503 if (signal == SIGHUP)
504 sighups++;
505 if (signal == SIGTERM)
506 sigterms++;
507 if (signal == SIGCHLD)
508 sigchlds++;
509}
510#endif /* ! USE_MACH_IPC */
511
512/*
513 * Registering the daemon.
514 */
515static int
516register_daemon(void)
517{
518 FILE * pidfile;
519 int fd;
520 pid_t pid;
521
522 /* Set up the signal hander. */
378static int
379register_daemon(void)
380{
381 FILE * pidfile;
382 int fd;
383 pid_t pid;
384
385 /* Set up the signal hander. */
523 if (signal(SIGTERM, relay_signal) == SIG_ERR) {
524 syslog(LOG_ERR,
386 if (signal(SIGTERM, auditd_relay_signal) == SIG_ERR) {
387 auditd_log_err(
525 "Could not set signal handler for SIGTERM");
526 fail_exit();
527 }
388 "Could not set signal handler for SIGTERM");
389 fail_exit();
390 }
528 if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
529 syslog(LOG_ERR,
391 if (signal(SIGCHLD, auditd_relay_signal) == SIG_ERR) {
392 auditd_log_err(
530 "Could not set signal handler for SIGCHLD");
531 fail_exit();
532 }
393 "Could not set signal handler for SIGCHLD");
394 fail_exit();
395 }
533 if (signal(SIGHUP, relay_signal) == SIG_ERR) {
534 syslog(LOG_ERR,
396 if (signal(SIGHUP, auditd_relay_signal) == SIG_ERR) {
397 auditd_log_err(
535 "Could not set signal handler for SIGHUP");
536 fail_exit();
537 }
398 "Could not set signal handler for SIGHUP");
399 fail_exit();
400 }
401 if (signal(SIGALRM, auditd_relay_signal) == SIG_ERR) {
402 auditd_log_err(
403 "Could not set signal handler for SIGALRM");
404 fail_exit();
405 }
538
539 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
406
407 if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
540 syslog(LOG_ERR, "Could not open PID file");
408 auditd_log_err("Could not open PID file");
541 audit_warn_tmpfile();
542 return (-1);
543 }
544
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) {
409 audit_warn_tmpfile();
410 return (-1);
411 }
412
413 /* Attempt to lock the pid file; if a lock is present, exit. */
414 fd = fileno(pidfile);
415 if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
548 syslog(LOG_ERR,
416 auditd_log_err(
549 "PID file is locked (is another auditd running?).");
550 audit_warn_ebusy();
551 return (-1);
552 }
553
554 pid = getpid();
555 ftruncate(fd, 0);
556 if (fprintf(pidfile, "%u\n", pid) < 0) {
557 /* Should not start the daemon. */
558 fail_exit();
559 }
560
561 fflush(pidfile);
562 return (0);
563}
564
417 "PID file is locked (is another auditd running?).");
418 audit_warn_ebusy();
419 return (-1);
420 }
421
422 pid = getpid();
423 ftruncate(fd, 0);
424 if (fprintf(pidfile, "%u\n", pid) < 0) {
425 /* Should not start the daemon. */
426 fail_exit();
427 }
428
429 fflush(pidfile);
430 return (0);
431}
432
565#ifdef USE_MACH_IPC
566/*
433/*
567 * Implementation of the auditd_control() MIG simpleroutine.
568 *
569 * React to input from the audit(1) tool.
570 */
571
572/* ARGSUSED */
573kern_return_t
574auditd_control(mach_port_t __unused auditd_port, int trigger)
575{
576 int err_ret = 0;
577
578 switch (trigger) {
579
580 case AUDIT_TRIGGER_ROTATE_USER:
581 /*
582 * Create a new file and swap with the one
583 * being used in kernel.
584 */
585 if (swap_audit_file() == -1)
586 syslog(LOG_ERR, "Error swapping audit file");
587 break;
588
589 case AUDIT_TRIGGER_READ_FILE:
590 if (read_control_file() == -1)
591 syslog(LOG_ERR, "Error in audit control file");
592 break;
593
594 case AUDIT_TRIGGER_CLOSE_AND_DIE:
595 err_ret = close_all();
596 exit (err_ret);
597 break;
598
599 default:
600 break;
601 }
602
603 return (KERN_SUCCESS);
604}
605#endif /* USE_MACH_IPC */
606
607/*
608 * Handle the audit trigger event.
609 *
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.
616 */
617#define DUPLICATE_INTERVAL 30
434 * Handle the audit trigger event.
435 *
436 * We suppress (ignore) duplicated triggers in close succession in order to
437 * try to avoid thrashing-like behavior. However, not all triggers can be
438 * ignored, as triggers generally represent edge triggers, not level
439 * triggers, and won't be retransmitted if the condition persists. Of
440 * specific concern is the rotate trigger -- if one is dropped, then it will
441 * not be retransmitted, and the log file will grow in an unbounded fashion.
442 */
443#define DUPLICATE_INTERVAL 30
618#ifdef USE_MACH_IPC
619#define AT_SUCCESS KERN_SUCCESS
620
621/* ARGSUSED */
622kern_return_t
623audit_triggers(mach_port_t __unused audit_port, int trigger)
624#else
625#define AT_SUCCESS 0
626
627static int
628handle_audit_trigger(int trigger)
629#endif
444void
445auditd_handle_trigger(int trigger)
630{
631 static int last_trigger, last_warning;
632 static time_t last_time;
446{
447 static int last_trigger, last_warning;
448 static time_t last_time;
633 struct dir_ent *dirent;
634 struct timeval ts;
635 struct timezone tzp;
636 time_t tt;
449 struct timeval ts;
450 struct timezone tzp;
451 time_t tt;
452 int au_state;
453 int err = 0;
637
638 /*
639 * Suppress duplicate messages from the kernel within the specified
640 * interval.
641 */
642 if (gettimeofday(&ts, &tzp) == 0) {
643 tt = (time_t)ts.tv_sec;
644 switch (trigger) {
645 case AUDIT_TRIGGER_LOW_SPACE:
646 case AUDIT_TRIGGER_NO_SPACE:
647 /*
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.
651 */
652 if ((trigger == last_trigger) &&
653 (tt < (last_time + DUPLICATE_INTERVAL))) {
654 if (tt >= (last_warning + DUPLICATE_INTERVAL))
454
455 /*
456 * Suppress duplicate messages from the kernel within the specified
457 * interval.
458 */
459 if (gettimeofday(&ts, &tzp) == 0) {
460 tt = (time_t)ts.tv_sec;
461 switch (trigger) {
462 case AUDIT_TRIGGER_LOW_SPACE:
463 case AUDIT_TRIGGER_NO_SPACE:
464 /*
465 * Triggers we can suppress. Of course, we also need
466 * to rate limit the warnings, so apply the same
467 * interval limit on syslog messages.
468 */
469 if ((trigger == last_trigger) &&
470 (tt < (last_time + DUPLICATE_INTERVAL))) {
471 if (tt >= (last_warning + DUPLICATE_INTERVAL))
655 syslog(LOG_INFO,
472 auditd_log_info(
656 "Suppressing duplicate trigger %d",
657 trigger);
473 "Suppressing duplicate trigger %d",
474 trigger);
658 return (AT_SUCCESS);
475 return;
659 }
660 last_warning = tt;
661 break;
662
663 case AUDIT_TRIGGER_ROTATE_KERNEL:
664 case AUDIT_TRIGGER_ROTATE_USER:
665 case AUDIT_TRIGGER_READ_FILE:
476 }
477 last_warning = tt;
478 break;
479
480 case AUDIT_TRIGGER_ROTATE_KERNEL:
481 case AUDIT_TRIGGER_ROTATE_USER:
482 case AUDIT_TRIGGER_READ_FILE:
483 case AUDIT_TRIGGER_CLOSE_AND_DIE:
484 case AUDIT_TRIGGER_INITIALIZE:
666 /*
667 * Triggers that we cannot suppress.
668 */
669 break;
670 }
671
672 /*
673 * Only update last_trigger after aborting due to a duplicate
674 * trigger, not before, or we will never allow that trigger
675 * again.
676 */
677 last_trigger = trigger;
678 last_time = tt;
679 }
680
485 /*
486 * Triggers that we cannot suppress.
487 */
488 break;
489 }
490
491 /*
492 * Only update last_trigger after aborting due to a duplicate
493 * trigger, not before, or we will never allow that trigger
494 * again.
495 */
496 last_trigger = trigger;
497 last_time = tt;
498 }
499
500 au_state = auditd_get_state();
501
681 /*
682 * Message processing is done here.
683 */
502 /*
503 * Message processing is done here.
504 */
684 dirent = TAILQ_FIRST(&dir_q);
685 switch(trigger) {
686 case AUDIT_TRIGGER_LOW_SPACE:
505 switch(trigger) {
506 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);
693 dirent->softlim = 1;
694
695 if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
696 swap_audit_file() == -1)
697 syslog(LOG_ERR, "Error swapping audit file");
698
699 /*
700 * Check if the next dir has already reached its soft
701 * limit.
702 */
703 dirent = TAILQ_FIRST(&dir_q);
704 if (dirent->softlim == 1) {
705 /* All dirs have reached their soft limit. */
706 audit_warn_allsoft();
707 }
708 } else {
709 /*
710 * Continue auditing to the current file. Also
711 * generate an allsoft warning.
712 *
713 * XXX do we want to do this ?
714 */
715 audit_warn_allsoft();
716 }
507 auditd_log_notice("Got low space trigger");
508 if (do_trail_file() == -1)
509 auditd_log_err("Error swapping audit file");
717 break;
718
719 case AUDIT_TRIGGER_NO_SPACE:
510 break;
511
512 case AUDIT_TRIGGER_NO_SPACE:
720 syslog(LOG_INFO, "Got no space trigger");
721
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);
726 free(dirent);
727
728 if (swap_audit_file() == -1)
729 syslog(LOG_ERR, "Error swapping audit file");
730
731 /* We are out of log directories. */
732 audit_warn_allhard(++allhardcount);
513 auditd_log_notice("Got no space trigger");
514 if (do_trail_file() == -1)
515 auditd_log_err("Error swapping audit file");
733 break;
734
735 case AUDIT_TRIGGER_ROTATE_KERNEL:
736 case AUDIT_TRIGGER_ROTATE_USER:
516 break;
517
518 case AUDIT_TRIGGER_ROTATE_KERNEL:
519 case AUDIT_TRIGGER_ROTATE_USER:
737 /*
738 * Create a new file and swap with the one being used in
739 * kernel
740 */
741 syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
520 auditd_log_info("Got open new trigger from %s", trigger ==
742 AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
521 AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
743 if (swap_audit_file() == -1)
744 syslog(LOG_ERR, "Error swapping audit file");
522 if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
523 auditd_log_err("Error swapping audit file");
745 break;
746
747 case AUDIT_TRIGGER_READ_FILE:
524 break;
525
526 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");
527 auditd_log_info("Got read file trigger");
528 if (au_state == AUD_STATE_ENABLED &&
529 auditd_config_controls() == -1)
530 auditd_log_err("Error setting audit controls");
753 break;
754
531 break;
532
755 default:
756 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
757 break;
758 }
759
760 return (AT_SUCCESS);
761}
762
763#undef AT_SUCCESS
764
765static void
766handle_sighup(void)
767{
768
769 sighups_handled = sighups;
770 config_audit_controls();
771}
772
773static int
774config_audit_host(void)
775{
776 char hoststr[MAXHOSTNAMELEN];
777 struct sockaddr_in6 *sin6;
778 struct sockaddr_in *sin;
779 struct addrinfo *res;
780 struct auditinfo_addr aia;
781 int error;
782
783 if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
784 syslog(LOG_WARNING,
785 "warning: failed to read 'host' param in control file");
533 case AUDIT_TRIGGER_CLOSE_AND_DIE:
534 auditd_log_info("Got close and die trigger");
535 if (au_state == AUD_STATE_ENABLED)
536 err = close_all();
786 /*
537 /*
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
791 * termid structure.
538 * Running under launchd don't exit. Wait for launchd to
539 * send SIGTERM.
792 */
540 */
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)
797 return (0);
798 else if (error < 0) {
799 syslog(LOG_ERR,
800 "Failed to set audit host info");
801 return (-1);
541 if (!launchd_flag) {
542 auditd_log_info("auditd exiting.");
543 exit (err);
802 }
544 }
803 return (0);
804 }
805 error = getaddrinfo(hoststr, NULL, NULL, &res);
806 if (error) {
807 syslog(LOG_ERR, "Failed to lookup hostname: %s", hoststr);
808 return (-1);
809 }
810 switch (res->ai_family) {
811 case PF_INET6:
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;
816 break;
545 break;
817 case PF_INET:
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;
546
547 case AUDIT_TRIGGER_INITIALIZE:
548 auditd_log_info("Got audit initialize trigger");
549 if (au_state == AUD_STATE_DISABLED)
550 audit_setup();
822 break;
551 break;
552
823 default:
553 default:
824 syslog(LOG_ERR,
825 "Un-supported address family in host parameter");
826 return (-1);
554 auditd_log_err("Got unknown trigger %d", trigger);
555 break;
827 }
556 }
828 if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) {
829 syslog(LOG_ERR,
830 "auditon: failed to set audit host information");
831 return (-1);
832 }
833 return (0);
834}
835
836/*
837 * Reap our children.
838 */
557}
558
559/*
560 * Reap our children.
561 */
839static void
840reap_children(void)
562void
563auditd_reap_children(void)
841{
842 pid_t child;
843 int wstatus;
844
845 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
846 if (!wstatus)
847 continue;
564{
565 pid_t child;
566 int wstatus;
567
568 while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
569 if (!wstatus)
570 continue;
848 syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
571 auditd_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) :
852 WTERMSIG(wstatus)));
853 }
854}
855
572 ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
573 "exited as a result of signal"),
574 ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
575 WTERMSIG(wstatus)));
576 }
577}
578
856static void
857handle_sigchld(void)
858{
859
860 sigchlds_handled = sigchlds;
861 reap_children();
862}
863
864/*
579/*
865 * Read the control file for triggers/signals and handle appropriately.
580 * Reap any children and terminate. If under launchd don't shutdown auditing
581 * but just the other stuff.
866 */
582 */
867#ifdef USE_MACH_IPC
868#define MAX_MSG_SIZE 4096
869
870static boolean_t
871auditd_combined_server(mach_msg_header_t *InHeadP,
872 mach_msg_header_t *OutHeadP)
583void
584auditd_terminate(void)
873{
585{
874 mach_port_t local_port = InHeadP->msgh_local_port;
586 int ret;
875
587
876 if (local_port == signal_port) {
877 int signo = InHeadP->msgh_id;
878 int ret;
588 auditd_reap_children();
589
590 if (launchd_flag)
591 ret = close_misc();
592 else
593 ret = close_all();
879
594
880 switch(signo) {
881 case SIGTERM:
882 ret = close_all();
883 exit(ret);
884
885 case SIGCHLD:
886 handle_sigchld();
887 return (TRUE);
888
889 case SIGHUP:
890 handle_sighup();
891 return (TRUE);
892
893 default:
894 syslog(LOG_INFO, "Received signal %d", signo);
895 return (TRUE);
896 }
897 } else if (local_port == control_port) {
898 boolean_t result;
899
900 result = audit_triggers_server(InHeadP, OutHeadP);
901 if (!result)
902 result = auditd_control_server(InHeadP, OutHeadP);
903 return (result);
904 }
905 syslog(LOG_INFO, "Recevied msg on bad port 0x%x.", local_port);
906 return (FALSE);
595 exit(ret);
907}
908
596}
597
909static int
910wait_for_events(void)
911{
912 kern_return_t result;
913
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());
918}
919
920#else /* ! USE_MACH_IPC */
921
922static int
923wait_for_events(void)
924{
925 int num;
926 unsigned int trigger;
927
928 for (;;) {
929 num = read(triggerfd, &trigger, sizeof(trigger));
930 if ((num == -1) && (errno != EINTR)) {
931 syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
932 return (-1);
933 }
934 if (sigterms != sigterms_handled) {
935 syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
936 break;
937 }
938 if (sigchlds != sigchlds_handled)
939 handle_sigchld();
940 if (sighups != sighups_handled) {
941 syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
942 handle_sighup();
943 }
944 if ((num == -1) && (errno == EINTR))
945 continue;
946 if (num == 0) {
947 syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
948 return (-1);
949 }
950 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
951 break;
952 else
953 (void)handle_audit_trigger(trigger);
954 }
955 return (close_all());
956}
957#endif /* ! USE_MACH_IPC */
958
959/*
960 * Configure the audit controls in the kernel: the event to class mapping,
961 * kernel preselection mask, etc.
962 */
598/*
599 * Configure the audit controls in the kernel: the event to class mapping,
600 * kernel preselection mask, etc.
601 */
963static int
964config_audit_controls(void)
602int
603auditd_config_controls(void)
965{
604{
966 au_event_ent_t ev, *evp;
967 au_evclass_map_t evc_map;
968 au_mask_t aumask;
969 int ctr = 0;
970 char naeventstr[NA_EVENT_STR_SIZE];
971 char polstr[POL_STR_SIZE];
972 long policy;
973 au_fstat_t au_fstat;
974 size_t filesz;
605 int cnt, err;
606 int ret = 0;
975
976 /*
607
608 /*
977 * Process the audit event file, obtaining a class mapping for each
978 * event, and send that mapping into the kernel.
979 *
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.
984 */
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)
989 free(ev.ae_name);
990 syslog(LOG_ERR,
991 "Memory allocation error when configuring audit controls.");
992 return (-1);
993 }
609 * Configure event to class mappings in kernel.
610 */
611 cnt = auditd_set_evcmap();
612 if (cnt < 0) {
613 auditd_log_err("auditd_set_evcmap() failed: %m");
614 ret = -1;
615 } else if (cnt == 0) {
616 auditd_log_err("No events to class mappings registered.");
617 ret = -1;
618 } else
619 auditd_log_debug("Registered %d event to class mappings.", cnt);
994
995 /*
620
621 /*
996 * XXXRW: Currently we have no way to remove mappings from the kernel
997 * when they are removed from the file-based mappings.
622 * Configure non-attributable event mask in kernel.
998 */
623 */
999 evp = &ev;
1000 setauevent();
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))
1005 != 0)
1006 syslog(LOG_ERR,
1007 "Failed to register class mapping for event %s",
1008 evp->ae_name);
1009 else
1010 ctr++;
1011 }
1012 endauevent();
1013 free(ev.ae_name);
1014 free(ev.ae_desc);
1015 if (ctr == 0)
1016 syslog(LOG_ERR, "No events to class mappings registered.");
1017 else
1018 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
1019 ctr);
624 err = auditd_set_namask();
625 if (err) {
626 auditd_log_err("auditd_set_namask() %s: %m",
627 auditd_strerror(err));
628 ret = -1;
629 } else
630 auditd_log_debug("Registered non-attributable event mask.");
1020
1021 /*
631
632 /*
1022 * Get the non-attributable event string and set the kernel mask from
1023 * that.
633 * Configure audit policy in kernel.
1024 */
634 */
1025 if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
1026 (getauditflagsbin(naeventstr, &aumask) == 0)) {
1027 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
1028 syslog(LOG_ERR,
1029 "Failed to register non-attributable event mask.");
1030 else
1031 syslog(LOG_DEBUG,
1032 "Registered non-attributable event mask.");
635 err = auditd_set_policy();
636 if (err) {
637 auditd_log_err("auditd_set_policy() %s: %m",
638 auditd_strerror(err));
639 ret = -1;
1033 } else
640 } else
1034 syslog(LOG_ERR,
1035 "Failed to obtain non-attributable event mask.");
1036
641 auditd_log_debug("Set audit policy in kernel.");
642
1037 /*
643 /*
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.
644 * Configure audit trail log size in kernel.
1041 */
645 */
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");
1046 } else {
1047 syslog(LOG_ERR, "Failed to obtain policy flags: %m");
1048 policy = AUDIT_CNT;
1049 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
1050 syslog(LOG_ERR,
1051 "Failed to set default audit policy: %m");
1052 }
1053
646 err = auditd_set_fsize();
647 if (err) {
648 auditd_log_err("audit_set_fsize() %s: %m",
649 auditd_strerror(err));
650 ret = -1;
651 } else
652 auditd_log_debug("Set audit trail size in kernel.");
653
1054 /*
654 /*
1055 * Set trail rotation size.
655 * Configure audit trail volume minimum free percentage of blocks in
656 * kernel.
1056 */
657 */
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");
658 err = auditd_set_minfree();
659 if (err) {
660 auditd_log_err("auditd_set_minfree() %s: %m",
661 auditd_strerror(err));
662 ret = -1;
1062 } else
663 } else
1063 syslog(LOG_ERR, "Failed to obtain filesz: %m");
664 auditd_log_debug(
665 "Set audit trail min free percent in kernel.");
1064
666
1065 return (config_audit_host());
1066}
1067
1068#ifdef USE_MACH_IPC
1069static void
1070mach_setup(void)
1071{
1072 mach_msg_type_name_t poly;
1073
1074 /*
667 /*
1075 * Allocate a port set
668 * Configure host address in the audit kernel information.
1076 */
669 */
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");
1080 fail_exit();
1081 }
1082
1083 /*
1084 * Allocate a signal reflection port
1085 */
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) !=
1089 KERN_SUCCESS) {
1090 syslog(LOG_ERR, "Allocation of signal port failed");
1091 fail_exit();
1092 }
1093
1094 /*
1095 * Allocate a trigger port
1096 */
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)
1100 != KERN_SUCCESS)
1101 syslog(LOG_ERR, "Allocation of trigger port failed");
1102
1103 /*
1104 * Create a send right on our trigger port.
1105 */
1106 mach_port_extract_right(mach_task_self(), control_port,
1107 MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
1108
1109 /*
1110 * Register the trigger port with the kernel.
1111 */
1112 if (host_set_audit_control_port(mach_host_self(), control_port) !=
1113 KERN_SUCCESS) {
1114 syslog(LOG_ERR, "Cannot set Mach control port");
1115 fail_exit();
670 err = auditd_set_host();
671 if (err) {
672 auditd_log_err("auditd_set_host() %s: %m",
673 auditd_strerror(err));
674 ret = -1;
1116 } else
675 } else
1117 syslog(LOG_DEBUG, "Mach control port registered");
676 auditd_log_debug(
677 "Set audit host address information in kernel.");
678
679 return (ret);
1118}
680}
1119#endif /* USE_MACH_IPC */
1120
681
682/*
683 * Setup and initialize auditd.
684 */
1121static void
1122setup(void)
1123{
685static void
686setup(void)
687{
1124 struct auditinfo ai;
1125 auditinfo_t auinfo;
1126 int aufd;
1127 token_t *tok;
688 int err;
1128
689
1129#ifdef USE_MACH_IPC
1130 mach_setup();
1131#else
1132 if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
1133 syslog(LOG_ERR, "Error opening trigger file");
690 if (auditd_open_trigger(launchd_flag) < 0) {
691 auditd_log_err("Error opening trigger messaging mechanism");
1134 fail_exit();
1135 }
692 fail_exit();
693 }
1136#endif
1137
1138 /*
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.
694
695 /*
696 * To prevent event feedback cycles and avoid auditd becoming
697 * stalled if auditing is suspended, auditd and its children run
698 * without their events being audited. We allow the uid, tid, and
699 * mask fields to be implicitly set to zero, but do set the pid. We
700 * run this after opening the trigger device to avoid configuring
701 * audit state without audit present in the system.
1145 *
1146 * XXXRW: Is there more to it than this?
1147 */
702 */
1148 bzero(&auinfo, sizeof(auinfo));
1149 auinfo.ai_asid = getpid();
1150 if (setaudit(&auinfo) == -1) {
1151 syslog(LOG_ERR, "Error setting audit stat");
703 err = auditd_prevent_audit();
704 if (err) {
705 auditd_log_err("auditd_prevent_audit() %s: %m",
706 auditd_strerror(err));
1152 fail_exit();
1153 }
1154
707 fail_exit();
708 }
709
1155 TAILQ_INIT(&dir_q);
1156 if (read_control_file() == -1) {
1157 syslog(LOG_ERR, "Error reading control file");
1158 fail_exit();
1159 }
710 /*
711 * Make sure auditd auditing state is correct.
712 */
713 auditd_set_state(AUD_STATE_INIT);
1160
714
1161 /* Generate an audit record. */
1162 if ((aufd = au_open()) == -1)
1163 syslog(LOG_ERR, "Could not create audit startup event.");
1164 else {
1165 /*
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?
1169 */
1170 bzero(&ai, sizeof(ai));
1171 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
1172 getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
1173 != NULL)
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)
1180 syslog(LOG_ERR,
1181 "Could not close audit startup event.");
1182 }
1183
1184 if (config_audit_controls() == 0)
1185 syslog(LOG_INFO, "Audit controls init successful");
1186 else
1187 syslog(LOG_ERR, "Audit controls init failed");
715 /*
716 * If under launchd, don't start auditing. Wait for a trigger to
717 * do so.
718 */
719 if (!launchd_flag)
720 audit_setup();
1188}
1189
1190int
1191main(int argc, char **argv)
1192{
1193 int ch;
1194 int debug = 0;
721}
722
723int
724main(int argc, char **argv)
725{
726 int ch;
727 int debug = 0;
1195 int rc, logopts;
728#ifdef AUDIT_REVIEW_GROUP
729 struct group *grp;
730#endif
1196
731
1197 while ((ch = getopt(argc, argv, "d")) != -1) {
732 while ((ch = getopt(argc, argv, "dl")) != -1) {
1198 switch(ch) {
1199 case 'd':
1200 /* Debug option. */
1201 debug = 1;
1202 break;
1203
733 switch(ch) {
734 case 'd':
735 /* Debug option. */
736 debug = 1;
737 break;
738
739 case 'l':
740 /* Be launchd friendly. */
741 launchd_flag = 1;
742 break;
743
1204 case '?':
1205 default:
1206 (void)fprintf(stderr,
744 case '?':
745 default:
746 (void)fprintf(stderr,
1207 "usage: auditd [-d] \n");
747 "usage: auditd [-d] [-l]\n");
1208 exit(1);
1209 }
1210 }
1211
748 exit(1);
749 }
750 }
751
1212 logopts = LOG_CONS | LOG_PID;
1213 if (debug != 0)
1214 logopts |= LOG_PERROR;
752 audit_review_gid = getgid();
1215
753
1216#ifdef LOG_SECURITY
1217 openlog("auditd", logopts, LOG_SECURITY);
1218#else
1219 openlog("auditd", logopts, LOG_AUTH);
754#ifdef AUDIT_REVIEW_GROUP
755 /*
756 * XXXRW: Currently, this code falls back to the daemon gid, which is
757 * likely the wheel group. Is there a better way to deal with this?
758 */
759 grp = getgrnam(AUDIT_REVIEW_GROUP);
760 if (grp != NULL)
761 audit_review_gid = grp->gr_gid;
1220#endif
762#endif
1221 syslog(LOG_INFO, "starting...");
1222
763
1223 if (debug == 0 && daemon(0, 0) == -1) {
1224 syslog(LOG_ERR, "Failed to daemonize");
764 auditd_openlog(debug, audit_review_gid);
765
766 if (launchd_flag)
767 auditd_log_info("started by launchd...");
768 else
769 auditd_log_info("starting...");
770
771#ifdef AUDIT_REVIEW_GROUP
772 if (grp == NULL)
773 auditd_log_info(
774 "Audit review group '%s' not available, using daemon gid (%d)",
775 AUDIT_REVIEW_GROUP, audit_review_gid);
776#endif
777 if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
778 auditd_log_err("Failed to daemonize");
1225 exit(1);
1226 }
1227
1228 if (register_daemon() == -1) {
779 exit(1);
780 }
781
782 if (register_daemon() == -1) {
1229 syslog(LOG_ERR, "Could not register as daemon");
783 auditd_log_err("Could not register as daemon");
1230 exit(1);
1231 }
1232
1233 setup();
1234
784 exit(1);
785 }
786
787 setup();
788
1235 rc = wait_for_events();
1236 syslog(LOG_INFO, "auditd exiting.");
789 /*
790 * auditd_wait_for_events() shouldn't return unless something is wrong.
791 */
792 auditd_wait_for_events();
1237
793
1238 exit(rc);
794 auditd_log_err("abnormal exit.");
795 close_all();
796 exit(-1);
1239}
797}