xref: /freebsd/contrib/openbsm/bin/auditd/auditd.c (revision d184218c)
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.c#50 $
30  */
31 
32 #include <sys/types.h>
33 
34 #include <config/config.h>
35 
36 #include <sys/dirent.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>
49 #include <bsm/auditd_lib.h>
50 #include <bsm/libbsm.h>
51 
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>
62 
63 #include "auditd.h"
64 
65 #ifndef HAVE_STRLCPY
66 #include <compat/strlcpy.h>
67 #endif
68 
69 /*
70  * XXX The following are temporary until these can be added to the kernel
71  * audit.h header.
72  */
73 #ifndef	AUDIT_TRIGGER_INITIALIZE
74 #define	AUDIT_TRIGGER_INITIALIZE	7
75 #endif
76 #ifndef	AUDIT_TRIGGER_EXPIRE_TRAILS
77 #define	AUDIT_TRIGGER_EXPIRE_TRAILS	8
78 #endif
79 
80 
81 /*
82  * LaunchD flag (Mac OS X and, maybe, FreeBSD only.)  See launchd(8) and
83  * http://wiki.freebsd.org/launchd for more information.
84  *
85  *	In order for auditd to work "on demand" with launchd(8) it can't:
86  *		call daemon(3)
87  *		call fork and having the parent process exit
88  *		change uids or gids.
89  *		set up the current working directory or chroot.
90  *		set the session id
91  *		change stdio to /dev/null.
92  *		call setrusage(2)
93  *		call setpriority(2)
94  *		Ignore SIGTERM.
95  *	auditd (in 'launchd mode') is launched on demand so it must catch
96  *	SIGTERM to exit cleanly.
97  */
98 static int	launchd_flag = 0;
99 
100 /*
101  * The GID of the audit review group (if used).  The audit trail files and
102  * system logs (Mac OS X only) can only be reviewed by members of this group
103  * or the audit administrator (aka. "root").
104  */
105 static gid_t	audit_review_gid = -1;
106 
107 /*
108  * The path and file name of the last audit trail file.
109  */
110 static char	*lastfile = NULL;
111 
112 /*
113  * Error starting auditd. Run warn script and exit.
114  */
115 static void
116 fail_exit(void)
117 {
118 
119 	audit_warn_nostart();
120 	exit(1);
121 }
122 
123 /*
124  * Follow the 'current' symlink to get the active trail file name.
125  */
126 static char *
127 get_curfile(void)
128 {
129 	char *cf;
130 	int len;
131 
132 	cf = malloc(MAXPATHLEN);
133 	if (cf == NULL) {
134 		auditd_log_err("malloc failed: %m");
135 		return (NULL);
136 	}
137 
138 	len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1);
139 	if (len < 0) {
140 		free(cf);
141 		return (NULL);
142 	}
143 
144 	/* readlink() doesn't terminate string. */
145 	cf[len] = '\0';
146 
147 	return (cf);
148 }
149 
150 /*
151  * Close the previous audit trail file.
152  */
153 static int
154 close_lastfile(char *TS)
155 {
156 	char *ptr;
157 	char *oldname;
158 
159 	/* If lastfile is NULL try to get it from the 'current' link.  */
160 	if (lastfile == NULL)
161 		lastfile = get_curfile();
162 
163 	if (lastfile != NULL) {
164 		oldname = strdup(lastfile);
165 		if (oldname == NULL)
166 			return (-1);
167 
168 		/* Rename the last file -- append timestamp. */
169 		if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
170 			memcpy(ptr, TS, POSTFIX_LEN);
171 			if (auditd_rename(oldname, lastfile) != 0)
172 				auditd_log_err(
173 				    "Could not rename %s to %s: %m", oldname,
174 				    lastfile);
175 			else {
176 				/*
177 				 * Remove the 'current' symlink since the link
178 				 * is now invalid.
179 				 */
180 				(void) unlink(AUDIT_CURRENT_LINK);
181 				auditd_log_notice("renamed %s to %s",
182 				    oldname, lastfile);
183 				audit_warn_closefile(lastfile);
184 			}
185 		} else
186 			auditd_log_err("Could not rename %s to %s", oldname,
187 			    lastfile);
188 		free(lastfile);
189 		free(oldname);
190 		lastfile = NULL;
191 	}
192 	return (0);
193 }
194 
195 /*
196  * Create the new file name, swap with existing audit file.
197  */
198 static int
199 swap_audit_file(void)
200 {
201 	int err;
202 	char *newfile, *name;
203 	char TS[TIMESTAMP_LEN + 1];
204 	time_t tt;
205 
206 	if (getTSstr(tt, TS, sizeof(TS)) != 0)
207 		return (-1);
208 	/*
209 	 * If prefix and suffix are the same, it means that records are
210 	 * being produced too fast. We don't want to rename now, because
211 	 * next trail file can get the same name and once that one is
212 	 * terminated also within one second it will overwrite the current
213 	 * one. Just keep writing to the same trail and wait for the next
214 	 * trigger from the kernel.
215 	 * FREEBSD KERNEL WAS UPDATED TO KEEP SENDING TRIGGERS, WHICH MIGHT
216 	 * NOT BE THE CASE FOR OTHER OSES.
217 	 * If the kernel will not keep sending triggers, trail file will not
218 	 * be terminated.
219 	 */
220 	if (lastfile == NULL) {
221 		name = NULL;
222 	} else {
223 		name = strrchr(lastfile, '/');
224 		if (name != NULL)
225 			name++;
226 	}
227 	if (name != NULL && strncmp(name, TS, TIMESTAMP_LEN) == 0) {
228 		auditd_log_debug("Not ready to terminate trail file yet.");
229 		return (0);
230 	}
231 	err = auditd_swap_trail(TS, &newfile, audit_review_gid,
232 	    audit_warn_getacdir);
233 	if (err != ADE_NOERR) {
234 		auditd_log_err("%s: %m", auditd_strerror(err));
235 		if (err != ADE_ACTL)
236 			return (-1);
237 	}
238 
239 	/*
240 	 * Only close the last file if were in an auditing state before
241 	 * calling swap_audit_file().  We may need to recover from a crash.
242 	 */
243 	if (auditd_get_state() == AUD_STATE_ENABLED)
244 		close_lastfile(TS);
245 
246 
247 	/*
248 	 * auditd_swap_trail() potentially enables auditing (if not already
249 	 * enabled) so updated the cached state as well.
250 	 */
251 	auditd_set_state(AUD_STATE_ENABLED);
252 
253 	/*
254 	 *  Create 'current' symlink.  Recover from crash, if needed.
255 	 */
256 	if (auditd_new_curlink(newfile) != 0)
257 		auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m",
258 		    newfile, auditd_strerror(err));
259 
260 	lastfile = newfile;
261 	auditd_log_notice("New audit file is %s", newfile);
262 
263 	return (0);
264 }
265 
266 /*
267  * Create a new audit log trail file and swap with the current one, if any.
268  */
269 static int
270 do_trail_file(void)
271 {
272 	int err;
273 
274 	/*
275 	 * First, refresh the list of audit log directories.
276 	 */
277 	err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
278 	if (err) {
279 		auditd_log_err("auditd_read_dirs(): %s",
280 		    auditd_strerror(err));
281 		if (err == ADE_HARDLIM)
282 			audit_warn_allhard();
283 		if (err != ADE_SOFTLIM)
284 			return (-1);
285 		else
286 			audit_warn_allsoft();
287 			/* continue on with soft limit error */
288 	}
289 
290 	/*
291 	 * Create a new file and swap with the one being used in kernel.
292 	 */
293 	if (swap_audit_file() == -1) {
294 		/*
295 		 * XXX Faulty directory listing? - user should be given
296 		 * XXX an opportunity to change the audit_control file
297 		 * XXX switch to a reduced mode of auditing?
298 		 */
299 		return (-1);
300 	}
301 
302 	/*
303 	 * Finally, see if there are any trail files to expire.
304 	 */
305 	err = auditd_expire_trails(audit_warn_expired);
306 	if (err)
307 		auditd_log_err("auditd_expire_trails(): %s",
308 		    auditd_strerror(err));
309 
310 	return (0);
311 }
312 
313 /*
314  * Start up auditing.
315  */
316 static void
317 audit_setup(void)
318 {
319 	int err;
320 
321 	/* Configure trail files distribution. */
322 	err = auditd_set_dist();
323 	if (err) {
324 		auditd_log_err("auditd_set_dist() %s: %m",
325 		    auditd_strerror(err));
326 	} else
327 		auditd_log_debug("Configured trail files distribution.");
328 
329 	if (do_trail_file() == -1) {
330 		auditd_log_err("Error creating audit trail file");
331 		fail_exit();
332 	}
333 
334 	/* Generate an audit record. */
335 	err = auditd_gen_record(AUE_audit_startup, NULL);
336 	if (err)
337 		auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m",
338 		    auditd_strerror(err));
339 
340 	if (auditd_config_controls() == 0)
341 		auditd_log_info("Audit controls init successful");
342 	else
343 		auditd_log_err("Audit controls init failed");
344 }
345 
346 
347 /*
348  * Close auditd pid file and trigger mechanism.
349  */
350 static int
351 close_misc(void)
352 {
353 
354 	auditd_close_dirs();
355 	if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) {
356 		auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE);
357 		return (1);
358 	}
359 	endac();
360 
361 	if (auditd_close_trigger() != 0) {
362 		auditd_log_err("Error closing trigger messaging mechanism");
363 		return (1);
364 	}
365 	return (0);
366 }
367 
368 /*
369  * Close all log files, control files, and tell the audit system.
370  */
371 static int
372 close_all(void)
373 {
374 	int err_ret = 0;
375 	char TS[TIMESTAMP_LEN + 1];
376 	int err;
377 	int cond;
378 	time_t tt;
379 
380 	err = auditd_gen_record(AUE_audit_shutdown, NULL);
381 	if (err)
382 		auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m",
383 		    auditd_strerror(err));
384 
385 	/* Flush contents. */
386 	cond = AUC_DISABLED;
387 	err_ret = audit_set_cond(&cond);
388 	if (err_ret != 0) {
389 		auditd_log_err("Disabling audit failed! : %s", strerror(errno));
390 		err_ret = 1;
391 	}
392 
393 	/*
394 	 * Updated the cached state that auditing has been disabled.
395 	 */
396 	auditd_set_state(AUD_STATE_DISABLED);
397 
398 	if (getTSstr(tt, TS, sizeof(TS)) == 0)
399 		close_lastfile(TS);
400 	if (lastfile != NULL)
401 		free(lastfile);
402 
403 	err_ret += close_misc();
404 
405 	if (err_ret) {
406 		auditd_log_err("Could not unregister");
407 		audit_warn_postsigterm();
408 	}
409 
410 	auditd_log_info("Finished");
411 	return (err_ret);
412 }
413 
414 /*
415  * Register the daemon with the signal handler and the auditd pid file.
416  */
417 static int
418 register_daemon(void)
419 {
420 	FILE * pidfile;
421 	int fd;
422 	pid_t pid;
423 
424 	/* Set up the signal hander. */
425 	if (signal(SIGTERM, auditd_relay_signal) == SIG_ERR) {
426 		auditd_log_err(
427 		    "Could not set signal handler for SIGTERM");
428 		fail_exit();
429 	}
430 	if (signal(SIGCHLD, auditd_relay_signal) == SIG_ERR) {
431 		auditd_log_err(
432 		    "Could not set signal handler for SIGCHLD");
433 		fail_exit();
434 	}
435 	if (signal(SIGHUP, auditd_relay_signal) == SIG_ERR) {
436 		auditd_log_err(
437 		    "Could not set signal handler for SIGHUP");
438 		fail_exit();
439 	}
440 	if (signal(SIGALRM, auditd_relay_signal) == SIG_ERR) {
441 		auditd_log_err(
442 		    "Could not set signal handler for SIGALRM");
443 		fail_exit();
444 	}
445 
446 	if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
447 		auditd_log_err("Could not open PID file");
448 		audit_warn_tmpfile();
449 		return (-1);
450 	}
451 
452 	/* Attempt to lock the pid file; if a lock is present, exit. */
453 	fd = fileno(pidfile);
454 	if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
455 		auditd_log_err(
456 		    "PID file is locked (is another auditd running?).");
457 		audit_warn_ebusy();
458 		return (-1);
459 	}
460 
461 	pid = getpid();
462 	ftruncate(fd, 0);
463 	if (fprintf(pidfile, "%u\n", pid) < 0) {
464 		/* Should not start the daemon. */
465 		fail_exit();
466 	}
467 
468 	fflush(pidfile);
469 	return (0);
470 }
471 
472 /*
473  * Handle the audit trigger event.
474  *
475  * We suppress (ignore) duplicated triggers in close succession in order to
476  * try to avoid thrashing-like behavior.  However, not all triggers can be
477  * ignored, as triggers generally represent edge triggers, not level
478  * triggers, and won't be retransmitted if the condition persists.  Of
479  * specific concern is the rotate trigger -- if one is dropped, then it will
480  * not be retransmitted, and the log file will grow in an unbounded fashion.
481  */
482 #define	DUPLICATE_INTERVAL	30
483 void
484 auditd_handle_trigger(int trigger)
485 {
486 	static int last_trigger, last_warning;
487 	static time_t last_time;
488 	struct timeval ts;
489 	struct timezone tzp;
490 	time_t tt;
491 	int au_state;
492 	int err = 0;
493 
494 	/*
495 	 * Suppress duplicate messages from the kernel within the specified
496 	 * interval.
497 	 */
498 	if (gettimeofday(&ts, &tzp) == 0) {
499 		tt = (time_t)ts.tv_sec;
500 		switch (trigger) {
501 		case AUDIT_TRIGGER_LOW_SPACE:
502 		case AUDIT_TRIGGER_NO_SPACE:
503 			/*
504 			 * Triggers we can suppress.  Of course, we also need
505 			 * to rate limit the warnings, so apply the same
506 			 * interval limit on syslog messages.
507 			 */
508 			if ((trigger == last_trigger) &&
509 			    (tt < (last_time + DUPLICATE_INTERVAL))) {
510 				if (tt >= (last_warning + DUPLICATE_INTERVAL))
511 					auditd_log_info(
512 					    "Suppressing duplicate trigger %d",
513 					    trigger);
514 				return;
515 			}
516 			last_warning = tt;
517 			break;
518 
519 		case AUDIT_TRIGGER_ROTATE_KERNEL:
520 		case AUDIT_TRIGGER_ROTATE_USER:
521 		case AUDIT_TRIGGER_READ_FILE:
522 		case AUDIT_TRIGGER_CLOSE_AND_DIE:
523 		case AUDIT_TRIGGER_INITIALIZE:
524 			/*
525 			 * Triggers that we cannot suppress.
526 			 */
527 			break;
528 		}
529 
530 		/*
531 		 * Only update last_trigger after aborting due to a duplicate
532 		 * trigger, not before, or we will never allow that trigger
533 		 * again.
534 		 */
535 		last_trigger = trigger;
536 		last_time = tt;
537 	}
538 
539 	au_state = auditd_get_state();
540 
541 	/*
542 	 * Message processing is done here.
543 	 */
544 	switch(trigger) {
545 	case AUDIT_TRIGGER_LOW_SPACE:
546 		auditd_log_notice("Got low space trigger");
547 		if (do_trail_file() == -1)
548 			auditd_log_err("Error swapping audit file");
549 		break;
550 
551 	case AUDIT_TRIGGER_NO_SPACE:
552 		auditd_log_notice("Got no space trigger");
553 		if (do_trail_file() == -1)
554 			auditd_log_err("Error swapping audit file");
555 		break;
556 
557 	case AUDIT_TRIGGER_ROTATE_KERNEL:
558 	case AUDIT_TRIGGER_ROTATE_USER:
559 		auditd_log_info("Got open new trigger from %s", trigger ==
560 		    AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
561 		if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
562 			auditd_log_err("Error swapping audit file");
563 		break;
564 
565 	case AUDIT_TRIGGER_READ_FILE:
566 		auditd_log_info("Got read file trigger");
567 		if (au_state == AUD_STATE_ENABLED) {
568 			if (auditd_config_controls() == -1)
569 				auditd_log_err("Error setting audit controls");
570 			else if (do_trail_file() == -1)
571 				auditd_log_err("Error swapping audit file");
572 		}
573 		break;
574 
575 	case AUDIT_TRIGGER_CLOSE_AND_DIE:
576 		auditd_log_info("Got close and die trigger");
577 		if (au_state == AUD_STATE_ENABLED)
578 			err = close_all();
579 		/*
580 		 * Running under launchd don't exit.  Wait for launchd to
581 		 * send SIGTERM.
582 		 */
583 		if (!launchd_flag) {
584 			auditd_log_info("auditd exiting.");
585 			exit (err);
586 		}
587 		break;
588 
589 	case AUDIT_TRIGGER_INITIALIZE:
590 		auditd_log_info("Got audit initialize trigger");
591 		if (au_state == AUD_STATE_DISABLED)
592 			audit_setup();
593 		break;
594 
595 	case AUDIT_TRIGGER_EXPIRE_TRAILS:
596 		auditd_log_info("Got audit expire trails trigger");
597 		err = auditd_expire_trails(audit_warn_expired);
598 		if (err)
599 			auditd_log_err("auditd_expire_trails(): %s",
600 			    auditd_strerror(err));
601 		break;
602 
603 	default:
604 		auditd_log_err("Got unknown trigger %d", trigger);
605 		break;
606 	}
607 }
608 
609 /*
610  * Reap our children.
611  */
612 void
613 auditd_reap_children(void)
614 {
615 	pid_t child;
616 	int wstatus;
617 
618 	while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
619 		if (!wstatus)
620 			continue;
621 		auditd_log_info("warn process [pid=%d] %s %d.", child,
622 		    ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
623 		    "exited as a result of signal"),
624 		    ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
625 		    WTERMSIG(wstatus)));
626 	}
627 }
628 
629 /*
630  * Reap any children and terminate.  If under launchd don't shutdown auditing
631  * but just the other stuff.
632  */
633 void
634 auditd_terminate(void)
635 {
636 	int ret;
637 
638 	auditd_reap_children();
639 
640 	if (launchd_flag)
641 		ret = close_misc();
642 	else
643 		ret = close_all();
644 
645 	exit(ret);
646 }
647 
648 /*
649  * Configure the audit controls in the kernel: the event to class mapping,
650  * kernel preselection mask, etc.
651  */
652 int
653 auditd_config_controls(void)
654 {
655 	int cnt, err;
656 	int ret = 0;
657 
658 	/*
659 	 * Configure event to class mappings in kernel.
660 	 */
661 	cnt = auditd_set_evcmap();
662 	if (cnt < 0) {
663 		auditd_log_err("auditd_set_evcmap() failed: %m");
664 		ret = -1;
665 	} else if (cnt == 0) {
666 		auditd_log_err("No events to class mappings registered.");
667 		ret = -1;
668 	} else
669 		auditd_log_debug("Registered %d event to class mappings.", cnt);
670 
671 	/*
672 	 * Configure non-attributable event mask in kernel.
673 	 */
674 	err = auditd_set_namask();
675 	if (err) {
676 		auditd_log_err("auditd_set_namask() %s: %m",
677 		    auditd_strerror(err));
678 		ret = -1;
679 	} else
680 		auditd_log_debug("Registered non-attributable event mask.");
681 
682 	/*
683 	 * Configure audit policy in kernel.
684 	 */
685 	err = auditd_set_policy();
686 	if (err) {
687 		auditd_log_err("auditd_set_policy() %s: %m",
688 		    auditd_strerror(err));
689 		ret = -1;
690 	} else
691 		auditd_log_debug("Set audit policy in kernel.");
692 
693 	/*
694 	 * Configure audit trail log size in kernel.
695 	 */
696 	err = auditd_set_fsize();
697 	if (err) {
698 		auditd_log_err("audit_set_fsize() %s: %m",
699 		    auditd_strerror(err));
700 		ret = -1;
701 	} else
702 		auditd_log_debug("Set audit trail size in kernel.");
703 
704 	/*
705 	 * Configure audit trail volume minimum free percentage of blocks in
706 	 * kernel.
707 	 */
708 	err = auditd_set_minfree();
709 	if (err) {
710 		auditd_log_err("auditd_set_minfree() %s: %m",
711 		    auditd_strerror(err));
712 		ret = -1;
713 	} else
714 		auditd_log_debug(
715 		    "Set audit trail min free percent in kernel.");
716 
717 	/*
718 	 * Configure host address in the audit kernel information.
719 	 */
720 	err = auditd_set_host();
721 	if (err) {
722 		if (err == ADE_PARSE) {
723 			auditd_log_notice(
724 			    "audit_control(5) may be missing 'host:' field");
725 		} else {
726 			auditd_log_err("auditd_set_host() %s: %m",
727 			    auditd_strerror(err));
728 			ret = -1;
729 		}
730 	} else
731 		auditd_log_debug(
732 		    "Set audit host address information in kernel.");
733 
734 	return (ret);
735 }
736 
737 /*
738  * Setup and initialize auditd.
739  */
740 static void
741 setup(void)
742 {
743 	int err;
744 
745 	if (auditd_open_trigger(launchd_flag) < 0) {
746 		auditd_log_err("Error opening trigger messaging mechanism");
747 		fail_exit();
748 	}
749 
750 	/*
751 	 * To prevent event feedback cycles and avoid auditd becoming
752 	 * stalled if auditing is suspended, auditd and its children run
753 	 * without their events being audited.  We allow the uid, tid, and
754 	 * mask fields to be implicitly set to zero, but do set the pid.  We
755 	 * run this after opening the trigger device to avoid configuring
756 	 * audit state without audit present in the system.
757 	 */
758 	err = auditd_prevent_audit();
759 	if (err) {
760 		auditd_log_err("auditd_prevent_audit() %s: %m",
761 		    auditd_strerror(err));
762 		fail_exit();
763 	}
764 
765 	/*
766 	 * Make sure auditd auditing state is correct.
767 	 */
768 	auditd_set_state(AUD_STATE_INIT);
769 
770 	/*
771 	 * If under launchd, don't start auditing.  Wait for a trigger to
772 	 * do so.
773 	 */
774 	if (!launchd_flag)
775 		audit_setup();
776 }
777 
778 int
779 main(int argc, char **argv)
780 {
781 	int ch;
782 	int debug = 0;
783 #ifdef AUDIT_REVIEW_GROUP
784 	struct group *grp;
785 #endif
786 
787 	while ((ch = getopt(argc, argv, "dl")) != -1) {
788 		switch(ch) {
789 		case 'd':
790 			/* Debug option. */
791 			debug = 1;
792 			break;
793 
794 		case 'l':
795 			/* Be launchd friendly. */
796 			launchd_flag = 1;
797 			break;
798 
799 		case '?':
800 		default:
801 			(void)fprintf(stderr,
802 			    "usage: auditd [-d] [-l]\n");
803 			exit(1);
804 		}
805 	}
806 
807 	audit_review_gid = getgid();
808 
809 #ifdef AUDIT_REVIEW_GROUP
810 	/*
811 	 * XXXRW: Currently, this code falls back to the daemon gid, which is
812 	 * likely the wheel group.  Is there a better way to deal with this?
813 	 */
814 	grp = getgrnam(AUDIT_REVIEW_GROUP);
815 	if (grp != NULL)
816 		audit_review_gid = grp->gr_gid;
817 #endif
818 
819 	auditd_openlog(debug, audit_review_gid);
820 
821 	if (launchd_flag)
822 		auditd_log_info("started by launchd...");
823 	else
824 		auditd_log_info("starting...");
825 
826 #ifdef AUDIT_REVIEW_GROUP
827 	if (grp == NULL)
828 		auditd_log_info(
829 		    "Audit review group '%s' not available, using daemon gid (%d)",
830 		    AUDIT_REVIEW_GROUP, audit_review_gid);
831 #endif
832 	if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
833 		auditd_log_err("Failed to daemonize");
834 		exit(1);
835 	}
836 
837 	if (register_daemon() == -1) {
838 		auditd_log_err("Could not register as daemon");
839 		exit(1);
840 	}
841 
842 	setup();
843 
844 	/*
845 	 * auditd_wait_for_events() shouldn't return unless something is wrong.
846 	 */
847 	auditd_wait_for_events();
848 
849 	auditd_log_err("abnormal exit.");
850 	close_all();
851 	exit(-1);
852 }
853