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