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 */
98static 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 */
105static gid_t	audit_review_gid = -1;
106
107/*
108 * The path and file name of the last audit trail file.
109 */
110static char	*lastfile = NULL;
111
112/*
113 * Error starting auditd. Run warn script and exit.
114 */
115static void
116fail_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 */
126static char *
127get_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 */
153static int
154close_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 */
198static int
199swap_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 */
269static int
270do_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 */
316static void
317audit_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 */
350static int
351close_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 */
371static int
372close_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 */
417static int
418register_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
483void
484auditd_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 */
612void
613auditd_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 */
633void
634auditd_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 */
652int
653auditd_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 */
740static void
741setup(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
778int
779main(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