xref: /freebsd/contrib/openbsm/bin/auditd/auditd.c (revision c74c7b73a005e689b922dfcfe5b94804669b595b)
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  *
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#41 $
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 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
76 
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  */
94 static int	launchd_flag = 0;
95 
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  */
101 static gid_t	audit_review_gid = -1;
102 
103 /*
104  * The path and file name of the last audit trail file.
105  */
106 static char	*lastfile = NULL;
107 
108 /*
109  * Error starting auditd. Run warn script and exit.
110  */
111 static void
112 fail_exit(void)
113 {
114 
115 	audit_warn_nostart();
116 	exit(1);
117 }
118 
119 /*
120  * Follow the 'current' symlink to get the active trail file name.
121  */
122 static char *
123 get_curfile(void)
124 {
125 	char *cf;
126 	int len;
127 
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);
138 	}
139 
140 	/* readlink() doesn't terminate string. */
141 	cf[len] = '\0';
142 
143 	return (cf);
144 }
145 
146 /*
147  * Close the previous audit trail file.
148  */
149 static int
150 close_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 
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)
171 				auditd_log_err(
172 				    "Could not rename %s to %s: %m", oldname,
173 				    lastfile);
174 			else {
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",
181 				    oldname, lastfile);
182 				audit_warn_closefile(lastfile);
183 			}
184 		} else
185 			auditd_log_err( "Could not rename %s to %s", oldname,
186 			    lastfile);
187 		free(lastfile);
188 		free(oldname);
189 		lastfile = NULL;
190 	}
191 	return (0);
192 }
193 
194 /*
195  * Create the new file name, swap with existing audit file.
196  */
197 static int
198 swap_audit_file(void)
199 {
200 	int err;
201 	char *newfile;
202 	char TS[TIMESTAMP_LEN];
203 	time_t tt;
204 
205 	if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
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 	}
214 
215 	/*
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.
218 	 */
219 	if (auditd_get_state() == AUD_STATE_ENABLED)
220 		close_lastfile(TS);
221 
222 
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));
235 
236 	lastfile = newfile;
237 	auditd_log_notice("New audit file is %s", newfile);
238 
239 	return (0);
240 }
241 
242 /*
243  * Create a new audit log trail file and swap with the current one, if any.
244  */
245 static int
246 do_trail_file(void)
247 {
248 	int err;
249 
250 	/*
251 	 * First, refresh the list of audit log directories.
252 	 */
253 	err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
254 	if (err) {
255 		auditd_log_err("auditd_read_dirs(): %s",
256 		    auditd_strerror(err));
257 		if (err == ADE_HARDLIM)
258 			audit_warn_allhard();
259 		if (err != ADE_SOFTLIM)
260 			return (-1);
261 		else
262 			audit_warn_allsoft();
263 			/* continue on with soft limit error */
264 	}
265 
266 	/*
267 	 * Create a new file and swap with the one being used in kernel.
268 	 */
269 	if (swap_audit_file() == -1) {
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 
278 	return (0);
279 }
280 
281 /*
282  * Start up auditing.
283  */
284 static void
285 audit_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();
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  */
311 static int
312 close_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 	}
326 	return (0);
327 }
328 
329 /*
330  * Close all log files, control files, and tell the audit system.
331  */
332 static int
333 close_all(void)
334 {
335 	int err_ret = 0;
336 	char TS[TIMESTAMP_LEN];
337 	int err;
338 	long cond;
339 	time_t tt;
340 
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));
345 
346 	/* Flush contents. */
347 	cond = AUC_DISABLED;
348 	err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
349 	if (err_ret != 0) {
350 		auditd_log_err("Disabling audit failed! : %s", strerror(errno));
351 		err_ret = 1;
352 	}
353 
354 	/*
355 	 * Updated the cached state that auditing has been disabled.
356 	 */
357 	auditd_set_state(AUD_STATE_DISABLED);
358 
359 	if (getTSstr(tt, TS, TIMESTAMP_LEN) == 0)
360 		close_lastfile(TS);
361 	if (lastfile != NULL)
362 		free(lastfile);
363 
364 	err_ret += close_misc();
365 
366 	if (err_ret) {
367 		auditd_log_err("Could not unregister");
368 		audit_warn_postsigterm();
369 	}
370 
371 	auditd_log_info("Finished");
372 	return (err_ret);
373 }
374 
375 /*
376  * Register the daemon with the signal handler and the auditd pid file.
377  */
378 static int
379 register_daemon(void)
380 {
381 	FILE * pidfile;
382 	int fd;
383 	pid_t pid;
384 
385 	/* Set up the signal hander. */
386 	if (signal(SIGTERM, auditd_relay_signal) == SIG_ERR) {
387 		auditd_log_err(
388 		    "Could not set signal handler for SIGTERM");
389 		fail_exit();
390 	}
391 	if (signal(SIGCHLD, auditd_relay_signal) == SIG_ERR) {
392 		auditd_log_err(
393 		    "Could not set signal handler for SIGCHLD");
394 		fail_exit();
395 	}
396 	if (signal(SIGHUP, auditd_relay_signal) == SIG_ERR) {
397 		auditd_log_err(
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 	}
406 
407 	if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
408 		auditd_log_err("Could not open PID file");
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) {
416 		auditd_log_err(
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 
433 /*
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
444 void
445 auditd_handle_trigger(int trigger)
446 {
447 	static int last_trigger, last_warning;
448 	static time_t last_time;
449 	struct timeval ts;
450 	struct timezone tzp;
451 	time_t tt;
452 	int au_state;
453 	int err = 0;
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))
472 					auditd_log_info(
473 					    "Suppressing duplicate trigger %d",
474 					    trigger);
475 				return;
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:
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 
502 	/*
503 	 * Message processing is done here.
504  	 */
505 	switch(trigger) {
506 	case AUDIT_TRIGGER_LOW_SPACE:
507 		auditd_log_notice("Got low space trigger");
508 		if (do_trail_file() == -1)
509 			auditd_log_err("Error swapping audit file");
510 		break;
511 
512 	case AUDIT_TRIGGER_NO_SPACE:
513 		auditd_log_notice("Got no space trigger");
514 		if (do_trail_file() == -1)
515 			auditd_log_err("Error swapping audit file");
516 		break;
517 
518 	case AUDIT_TRIGGER_ROTATE_KERNEL:
519 	case AUDIT_TRIGGER_ROTATE_USER:
520 		auditd_log_info("Got open new trigger from %s", trigger ==
521 		    AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
522 		if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
523 			auditd_log_err("Error swapping audit file");
524 		break;
525 
526 	case AUDIT_TRIGGER_READ_FILE:
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");
531 		break;
532 
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();
537 		/*
538 		 * Running under launchd don't exit.  Wait for launchd to
539 		 * send SIGTERM.
540 		 */
541 		if (!launchd_flag) {
542 			auditd_log_info("auditd exiting.");
543 			exit (err);
544 		}
545 		break;
546 
547 	case AUDIT_TRIGGER_INITIALIZE:
548 		auditd_log_info("Got audit initialize trigger");
549 		if (au_state == AUD_STATE_DISABLED)
550 			audit_setup();
551 		break;
552 
553 	default:
554 		auditd_log_err("Got unknown trigger %d", trigger);
555 		break;
556 	}
557 }
558 
559 /*
560  * Reap our children.
561  */
562 void
563 auditd_reap_children(void)
564 {
565 	pid_t child;
566 	int wstatus;
567 
568 	while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
569 		if (!wstatus)
570 			continue;
571 		auditd_log_info("warn process [pid=%d] %s %d.", child,
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 
579 /*
580  * Reap any children and terminate.  If under launchd don't shutdown auditing
581  * but just the other stuff.
582  */
583 void
584 auditd_terminate(void)
585 {
586 	int ret;
587 
588 	auditd_reap_children();
589 
590 	if (launchd_flag)
591 		ret = close_misc();
592 	else
593 		ret = close_all();
594 
595 	exit(ret);
596 }
597 
598 /*
599  * Configure the audit controls in the kernel: the event to class mapping,
600  * kernel preselection mask, etc.
601  */
602 int
603 auditd_config_controls(void)
604 {
605 	int cnt, err;
606 	int ret = 0;
607 
608 	/*
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);
620 
621 	/*
622 	 * Configure non-attributable event mask in kernel.
623 	 */
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.");
631 
632 	/*
633 	 * Configure audit policy in kernel.
634 	 */
635 	err = auditd_set_policy();
636 	if (err) {
637 		auditd_log_err("auditd_set_policy() %s: %m",
638 		    auditd_strerror(err));
639 		ret = -1;
640 	} else
641 		auditd_log_debug("Set audit policy in kernel.");
642 
643 	/*
644 	 * Configure audit trail log size in kernel.
645 	 */
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 
654 	/*
655 	 * Configure audit trail volume minimum free percentage of blocks in
656 	 * kernel.
657 	 */
658 	err = auditd_set_minfree();
659 	if (err) {
660 		auditd_log_err("auditd_set_minfree() %s: %m",
661 		    auditd_strerror(err));
662 		ret = -1;
663 	} else
664 		auditd_log_debug(
665 		    "Set audit trail min free percent in kernel.");
666 
667 	/*
668 	 * Configure host address in the audit kernel information.
669 	 */
670 	err = auditd_set_host();
671 	if (err) {
672 		auditd_log_err("auditd_set_host() %s: %m",
673 		    auditd_strerror(err));
674 		ret = -1;
675 	} else
676 		auditd_log_debug(
677 		    "Set audit host address information in kernel.");
678 
679 	return (ret);
680 }
681 
682 /*
683  * Setup and initialize auditd.
684  */
685 static void
686 setup(void)
687 {
688 	int err;
689 
690 	if (auditd_open_trigger(launchd_flag) < 0) {
691 		auditd_log_err("Error opening trigger messaging mechanism");
692 		fail_exit();
693 	}
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.
702 	 */
703 	err = auditd_prevent_audit();
704 	if (err) {
705 		auditd_log_err("auditd_prevent_audit() %s: %m",
706 		    auditd_strerror(err));
707 		fail_exit();
708 	}
709 
710 	/*
711 	 * Make sure auditd auditing state is correct.
712 	 */
713 	auditd_set_state(AUD_STATE_INIT);
714 
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();
721 }
722 
723 int
724 main(int argc, char **argv)
725 {
726 	int ch;
727 	int debug = 0;
728 #ifdef AUDIT_REVIEW_GROUP
729 	struct group *grp;
730 #endif
731 
732 	while ((ch = getopt(argc, argv, "dl")) != -1) {
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 
744 		case '?':
745 		default:
746 			(void)fprintf(stderr,
747 			    "usage: auditd [-d] [-l]\n");
748 			exit(1);
749 		}
750 	}
751 
752 	audit_review_gid = getgid();
753 
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;
762 #endif
763 
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");
779 		exit(1);
780 	}
781 
782 	if (register_daemon() == -1) {
783 		auditd_log_err("Could not register as daemon");
784 		exit(1);
785 	}
786 
787 	setup();
788 
789 	/*
790 	 * auditd_wait_for_events() shouldn't return unless something is wrong.
791 	 */
792 	auditd_wait_for_events();
793 
794 	auditd_log_err("abnormal exit.");
795 	close_all();
796 	exit(-1);
797 }
798