auditd.c revision 161630
1/*
2 * Copyright (c) 2004 Apple Computer, Inc.
3 * All rights reserved.
4 *
5 * @APPLE_BSD_LICENSE_HEADER_START@
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1.  Redistributions of source code must retain the above copyright
12 *     notice, this list of conditions and the following disclaimer.
13 * 2.  Redistributions in binary form must reproduce the above copyright
14 *     notice, this list of conditions and the following disclaimer in the
15 *     documentation and/or other materials provided with the distribution.
16 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
17 *     its contributors may be used to endorse or promote products derived
18 *     from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * @APPLE_BSD_LICENSE_HEADER_END@
32 *
33 * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#17 $
34 */
35
36#include <sys/types.h>
37#include <sys/dirent.h>
38#include <sys/mman.h>
39#include <sys/queue.h>
40#include <sys/stat.h>
41#include <sys/wait.h>
42
43#include <bsm/audit.h>
44#include <bsm/audit_uevents.h>
45#include <bsm/libbsm.h>
46
47#include <err.h>
48#include <errno.h>
49#include <fcntl.h>
50#include <grp.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <time.h>
54#include <unistd.h>
55#include <signal.h>
56#include <string.h>
57#include <syslog.h>
58
59#include "auditd.h"
60
61#define	NA_EVENT_STR_SIZE	25
62
63static int	 ret, minval;
64static char	*lastfile = NULL;
65static int	 allhardcount = 0;
66static int	 triggerfd = 0;
67static int	 sigchlds, sigchlds_handled;
68static int	 sighups, sighups_handled;
69static int	 sigterms, sigterms_handled;
70static long	 global_flags;
71
72static TAILQ_HEAD(, dir_ent)	dir_q;
73
74static int	config_audit_controls(void);
75
76/*
77 * Error starting auditd
78 */
79static void
80fail_exit(void)
81{
82
83	audit_warn_nostart();
84	exit(1);
85}
86
87/*
88 * Free our local list of directory names.
89 */
90static void
91free_dir_q(void)
92{
93	struct dir_ent *dirent;
94
95	while ((dirent = TAILQ_FIRST(&dir_q))) {
96		TAILQ_REMOVE(&dir_q, dirent, dirs);
97		free(dirent->dirname);
98		free(dirent);
99	}
100}
101
102/*
103 * Generate the timestamp string.
104 */
105static int
106getTSstr(char *buf, int len)
107{
108	struct timeval ts;
109	struct timezone tzp;
110	time_t tt;
111
112	if (gettimeofday(&ts, &tzp) != 0)
113		return (-1);
114	tt = (time_t)ts.tv_sec;
115	if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
116		return (-1);
117	return (0);
118}
119
120/*
121 * Concat the directory name to the given file name.
122 * XXX We should affix the hostname also
123 */
124static char *
125affixdir(char *name, struct dir_ent *dirent)
126{
127	char *fn;
128	char *curdir;
129	const char *sep = "/";
130
131	curdir = dirent->dirname;
132	syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
133
134	fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1);
135	if (fn == NULL)
136		return (NULL);
137	strcpy(fn, curdir);
138	strcat(fn, sep);
139	strcat(fn, name);
140	return (fn);
141}
142
143/*
144 * Close the previous audit trail file.
145 */
146static int
147close_lastfile(char *TS)
148{
149	char *ptr;
150	char *oldname;
151
152	if (lastfile != NULL) {
153		oldname = (char *)malloc(strlen(lastfile) + 1);
154		if (oldname == NULL)
155			return (-1);
156		strcpy(oldname, lastfile);
157
158		/* Rename the last file -- append timestamp. */
159		if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
160			*ptr = '.';
161			strcpy(ptr+1, TS);
162			if (rename(oldname, lastfile) != 0)
163				syslog(LOG_ERR, "Could not rename %s to %s",
164				    oldname, lastfile);
165			else
166				syslog(LOG_INFO, "renamed %s to %s",
167				    oldname, lastfile);
168		}
169		free(lastfile);
170		free(oldname);
171		lastfile = NULL;
172	}
173	return (0);
174}
175
176/*
177 * Create the new audit file with appropriate permissions and ownership.  Try
178 * to clean up if something goes wrong.
179 */
180static int
181#ifdef AUDIT_REVIEW_GROUP
182open_trail(const char *fname, uid_t uid, gid_t gid)
183#else
184open_trail(const char *fname)
185#endif
186{
187	int error, fd;
188
189	fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
190	if (fd < 0)
191		return (-1);
192#ifdef AUDIT_REVIEW_GROUP
193	if (fchown(fd, uid, gid) < 0) {
194		error = errno;
195		close(fd);
196		(void)unlink(fname);
197		errno = error;
198		return (-1);
199	}
200#endif
201	return (fd);
202}
203
204/*
205 * Create the new file name, swap with existing audit file.
206 */
207static int
208swap_audit_file(void)
209{
210	char timestr[2 * POSTFIX_LEN];
211	char *fn;
212	char TS[POSTFIX_LEN];
213	struct dir_ent *dirent;
214#ifdef AUDIT_REVIEW_GROUP
215	struct group *grp;
216	gid_t gid;
217	uid_t uid;
218#endif
219	int error, fd;
220
221	if (getTSstr(TS, POSTFIX_LEN) != 0)
222		return (-1);
223
224	strcpy(timestr, TS);
225	strcat(timestr, NOT_TERMINATED);
226
227#ifdef AUDIT_REVIEW_GROUP
228	/*
229	 * XXXRW: Currently, this code falls back to the daemon gid, which is
230	 * likely the wheel group.  Is there a better way to deal with this?
231	 */
232	grp = getgrnam(AUDIT_REVIEW_GROUP);
233	if (grp == NULL) {
234		syslog(LOG_INFO,
235		    "Audit review group '%s' not available, using daemon gid",
236		    AUDIT_REVIEW_GROUP);
237		gid = -1;
238	} else
239		gid = grp->gr_gid;
240	uid = getuid();
241#endif
242
243	/* Try until we succeed. */
244	while ((dirent = TAILQ_FIRST(&dir_q))) {
245		if ((fn = affixdir(timestr, dirent)) == NULL) {
246			syslog(LOG_INFO, "Failed to swap log at time %s",
247				timestr);
248			return (-1);
249		}
250
251		/*
252		 * Create and open the file; then close and pass to the
253		 * kernel if all went well.
254		 */
255		syslog(LOG_INFO, "New audit file is %s", fn);
256#ifdef AUDIT_REVIEW_GROUP
257		fd = open_trail(fn, uid, gid);
258#else
259		fd = open_trail(fn);
260#endif
261		if (fd < 0)
262			warn("open(%s)", fn);
263		if (fd >= 0) {
264			error = auditctl(fn);
265			if (error) {
266				syslog(LOG_ERR,
267				    "auditctl failed setting log file! : %s",
268				    strerror(errno));
269				close(fd);
270			} else {
271				/* Success. */
272				close_lastfile(TS);
273				lastfile = fn;
274				close(fd);
275				return (0);
276			}
277		}
278
279		/*
280		 * Tell the administrator about lack of permissions for dir.
281		 */
282		audit_warn_getacdir(dirent->dirname);
283
284		/* Try again with a different directory. */
285		TAILQ_REMOVE(&dir_q, dirent, dirs);
286		free(dirent->dirname);
287		free(dirent);
288	}
289	syslog(LOG_ERR, "Log directories exhausted\n");
290	return (-1);
291}
292
293/*
294 * Read the audit_control file contents.
295 */
296static int
297read_control_file(void)
298{
299	char cur_dir[MAXNAMLEN];
300	struct dir_ent *dirent;
301	au_qctrl_t qctrl;
302
303	/*
304	 * Clear old values.  Force a re-read of the file the next time.
305	 */
306	free_dir_q();
307	endac();
308
309	/*
310	 * Read the list of directories into a local linked list.
311	 *
312	 * XXX We should use the reentrant interfaces once they are
313	 * available.
314	 */
315	while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
316		dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
317		if (dirent == NULL)
318			return (-1);
319		dirent->softlim = 0;
320		dirent->dirname = (char *) malloc(MAXNAMLEN);
321		if (dirent->dirname == NULL) {
322			free(dirent);
323			return (-1);
324		}
325		strcpy(dirent->dirname, cur_dir);
326		TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
327	}
328
329	allhardcount = 0;
330	if (swap_audit_file() == -1) {
331		syslog(LOG_ERR, "Could not swap audit file");
332		/*
333		 * XXX Faulty directory listing? - user should be given
334		 * XXX an opportunity to change the audit_control file
335		 * XXX switch to a reduced mode of auditing?
336		 */
337		return (-1);
338	}
339
340	/*
341	 * XXX There are synchronization problems here
342 	 * XXX what should we do if a trigger for the earlier limit
343	 * XXX is generated here?
344	 */
345	if (0 == (ret = getacmin(&minval))) {
346		syslog(LOG_DEBUG, "min free = %d\n", minval);
347		if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
348			syslog(LOG_ERR,
349			    "could not get audit queue settings");
350				return (-1);
351		}
352		qctrl.aq_minfree = minval;
353		if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
354			syslog(LOG_ERR,
355			    "could not set audit queue settings");
356			return (-1);
357		}
358	}
359
360	return (0);
361}
362
363/*
364 * Close all log files, control files, and tell the audit system.
365 */
366static int
367close_all(void)
368{
369	int err_ret = 0;
370	char TS[POSTFIX_LEN];
371	int aufd;
372	token_t *tok;
373	long cond;
374
375	/* Generate an audit record. */
376	if ((aufd = au_open()) == -1)
377		syslog(LOG_ERR, "Could not create audit shutdown event.");
378	else {
379		if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
380			au_write(aufd, tok);
381		if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
382			syslog(LOG_ERR,
383			    "Could not close audit shutdown event.");
384	}
385
386	/* Flush contents. */
387	cond = AUC_DISABLED;
388	err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
389	if (err_ret != 0) {
390		syslog(LOG_ERR, "Disabling audit failed! : %s",
391		    strerror(errno));
392		err_ret = 1;
393	}
394	if (getTSstr(TS, POSTFIX_LEN) == 0)
395		close_lastfile(TS);
396	if (lastfile != NULL)
397		free(lastfile);
398
399	free_dir_q();
400	if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
401		syslog(LOG_ERR, "Could not unregister");
402		audit_warn_postsigterm();
403		return (1);
404	}
405	endac();
406
407	if (close(triggerfd) != 0)
408		syslog(LOG_ERR, "Error closing control file");
409	syslog(LOG_INFO, "Finished");
410	return (0);
411}
412
413/*
414 * When we get a signal, we are often not at a clean point.  So, little can
415 * be done in the signal handler itself.  Instead,  we send a message to the
416 * main servicing loop to do proper handling from a non-signal-handler
417 * context.
418 */
419static void
420relay_signal(int signal)
421{
422
423	if (signal == SIGHUP)
424		sighups++;
425	if (signal == SIGTERM)
426		sigterms++;
427	if (signal == SIGCHLD)
428		sigchlds++;
429}
430
431/*
432 * Registering the daemon.
433 */
434static int
435register_daemon(void)
436{
437	FILE * pidfile;
438	int fd;
439	pid_t pid;
440
441	/* Set up the signal hander. */
442	if (signal(SIGTERM, relay_signal) == SIG_ERR) {
443		syslog(LOG_ERR,
444		    "Could not set signal handler for SIGTERM");
445		fail_exit();
446	}
447	if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
448		syslog(LOG_ERR,
449		    "Could not set signal handler for SIGCHLD");
450		fail_exit();
451	}
452	if (signal(SIGHUP, relay_signal) == SIG_ERR) {
453		syslog(LOG_ERR,
454		    "Could not set signal handler for SIGHUP");
455		fail_exit();
456	}
457
458	if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
459		syslog(LOG_ERR, "Could not open PID file");
460		audit_warn_tmpfile();
461		return (-1);
462	}
463
464	/* Attempt to lock the pid file; if a lock is present, exit. */
465	fd = fileno(pidfile);
466	if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
467		syslog(LOG_ERR,
468		    "PID file is locked (is another auditd running?).");
469		audit_warn_ebusy();
470		return (-1);
471	}
472
473	pid = getpid();
474	ftruncate(fd, 0);
475	if (fprintf(pidfile, "%u\n", pid) < 0) {
476		/* Should not start the daemon. */
477		fail_exit();
478	}
479
480	fflush(pidfile);
481	return (0);
482}
483
484/*
485 * Suppress duplicate messages within a 30 second interval.   This should be
486 * enough to time to rotate log files without thrashing from soft warnings
487 * generated before the log is actually rotated.
488 */
489#define	DUPLICATE_INTERVAL	30
490static void
491handle_audit_trigger(int trigger)
492{
493	static int last_trigger;
494	static time_t last_time;
495	struct dir_ent *dirent;
496
497	/*
498	 * Suppres duplicate messages from the kernel within the specified
499	 * interval.
500	 */
501	struct timeval ts;
502	struct timezone tzp;
503	time_t tt;
504
505	if (gettimeofday(&ts, &tzp) == 0) {
506		tt = (time_t)ts.tv_sec;
507		if ((trigger == last_trigger) &&
508		    (tt < (last_time + DUPLICATE_INTERVAL)))
509			return;
510		last_trigger = trigger;
511		last_time = tt;
512	}
513
514	/*
515	 * Message processing is done here.
516 	 */
517	dirent = TAILQ_FIRST(&dir_q);
518	switch(trigger) {
519
520	case AUDIT_TRIGGER_LOW_SPACE:
521		syslog(LOG_INFO, "Got low space trigger");
522		if (dirent && (dirent->softlim != 1)) {
523			TAILQ_REMOVE(&dir_q, dirent, dirs);
524				/* Add this node to the end of the list. */
525				TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
526				audit_warn_soft(dirent->dirname);
527				dirent->softlim = 1;
528
529			if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
530			    swap_audit_file() == -1)
531				syslog(LOG_ERR, "Error swapping audit file");
532
533			/*
534			 * Check if the next dir has already reached its soft
535			 * limit.
536			 */
537			dirent = TAILQ_FIRST(&dir_q);
538			if (dirent->softlim == 1)  {
539				/* All dirs have reached their soft limit. */
540				audit_warn_allsoft();
541			}
542		} else {
543			/*
544			 * Continue auditing to the current file.  Also
545			 * generate  an allsoft warning.
546			 * XXX do we want to do this ?
547			 */
548			audit_warn_allsoft();
549		}
550		break;
551
552	case AUDIT_TRIGGER_NO_SPACE:
553		syslog(LOG_INFO, "Got no space trigger");
554
555		/* Delete current dir, go on to next. */
556		TAILQ_REMOVE(&dir_q, dirent, dirs);
557		audit_warn_hard(dirent->dirname);
558		free(dirent->dirname);
559		free(dirent);
560
561		if (swap_audit_file() == -1)
562			syslog(LOG_ERR, "Error swapping audit file");
563
564		/* We are out of log directories. */
565		audit_warn_allhard(++allhardcount);
566		break;
567
568	case AUDIT_TRIGGER_OPEN_NEW:
569		/*
570		 * Create a new file and swap with the one being used in
571		 * kernel
572		 */
573		syslog(LOG_INFO, "Got open new trigger");
574		if (swap_audit_file() == -1)
575			syslog(LOG_ERR, "Error swapping audit file");
576		break;
577
578	case AUDIT_TRIGGER_READ_FILE:
579		syslog(LOG_INFO, "Got read file trigger");
580		if (read_control_file() == -1)
581			syslog(LOG_ERR, "Error in audit control file");
582		if (config_audit_controls() == -1)
583			syslog(LOG_ERR, "Error setting audit controls");
584		break;
585
586	default:
587		syslog(LOG_ERR, "Got unknown trigger %d", trigger);
588		break;
589	}
590}
591
592static void
593handle_sighup(void)
594{
595
596	sighups_handled = sighups;
597	config_audit_controls();
598}
599
600/*
601 * Reap our children.
602 */
603static void
604reap_children(void)
605{
606	pid_t child;
607	int wstatus;
608
609	while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
610		if (!wstatus)
611			continue;
612		syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
613		    ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
614		    "exited as a result of signal"),
615		    ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
616		    WTERMSIG(wstatus)));
617	}
618}
619
620static void
621handle_sigchld(void)
622{
623
624	sigchlds_handled = sigchlds;
625	reap_children();
626}
627
628/*
629 * Read the control file for triggers/signals and handle appropriately.
630 */
631static int
632wait_for_events(void)
633{
634	int num;
635	unsigned int trigger;
636
637	for (;;) {
638		num = read(triggerfd, &trigger, sizeof(trigger));
639		if ((num == -1) && (errno != EINTR)) {
640			syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
641			return (-1);
642		}
643		if (sigterms != sigterms_handled) {
644			syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
645			break;
646		}
647		if (sigchlds != sigchlds_handled) {
648			syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__);
649			handle_sigchld();
650		}
651		if (sighups != sighups_handled) {
652			syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
653			handle_sighup();
654		}
655		if ((num == -1) && (errno == EINTR))
656			continue;
657		if (num == 0) {
658			syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
659			return (-1);
660		}
661		syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger);
662		if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
663			break;
664		else
665			handle_audit_trigger(trigger);
666	}
667	return (close_all());
668}
669
670/*
671 * Configure the audit controls in the kernel: the event to class mapping,
672 * kernel preselection mask, etc.
673 */
674static int
675config_audit_controls(void)
676{
677	au_event_ent_t ev, *evp;
678	au_evclass_map_t evc_map;
679	au_mask_t aumask;
680	int ctr = 0;
681	char naeventstr[NA_EVENT_STR_SIZE];
682
683	/*
684	 * Process the audit event file, obtaining a class mapping for each
685	 * event, and send that mapping into the kernel.
686	 * XXX There's a risk here that the BSM library will return NULL
687	 * for an event when it can't properly map it to a class. In that
688	 * case, we will not process any events beyond the one that failed,
689	 * but should. We need a way to get a count of the events.
690	*/
691	ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
692	ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
693	if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
694		syslog(LOG_ERR,
695		    "Memory allocation error when configuring audit controls.");
696		return (-1);
697	}
698	evp = &ev;
699	setauevent();
700	while ((evp = getauevent_r(evp)) != NULL) {
701		evc_map.ec_number = evp->ae_number;
702		evc_map.ec_class = evp->ae_class;
703		if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
704		    != 0)
705			syslog(LOG_ERR,
706				"Failed to register class mapping for event %s",
707				 evp->ae_name);
708		else
709			ctr++;
710	}
711	endauevent();
712	free(ev.ae_name);
713	free(ev.ae_desc);
714	if (ctr == 0)
715		syslog(LOG_ERR, "No events to class mappings registered.");
716	else
717		syslog(LOG_DEBUG, "Registered %d event to class mappings.",
718		    ctr);
719
720	/*
721	 * Get the non-attributable event string and set the kernel mask from
722	 * that.
723	 */
724	if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
725	    (getauditflagsbin(naeventstr, &aumask) == 0)) {
726		if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
727			syslog(LOG_ERR,
728			    "Failed to register non-attributable event mask.");
729		else
730			syslog(LOG_DEBUG,
731			    "Registered non-attributable event mask.");
732	} else
733		syslog(LOG_ERR,
734		    "Failed to obtain non-attributable event mask.");
735
736	/*
737	 * Set the audit policy flags based on passed in parameter values.
738	 */
739	if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags)))
740		syslog(LOG_ERR, "Failed to set audit policy.");
741
742	return (0);
743}
744
745static void
746setup(void)
747{
748	auditinfo_t auinfo;
749	int aufd;
750	token_t *tok;
751
752	if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
753		syslog(LOG_ERR, "Error opening trigger file");
754		fail_exit();
755	}
756
757	/*
758	 * To provide event feedback cycles and avoid auditd becoming
759	 * stalled if auditing is suspended, auditd and its children run
760	 * without their events being audited.  We allow the uid, tid, and
761	 * mask fields to be implicitly set to zero, but do set the pid.  We
762	 * run this after opening the trigger device to avoid configuring
763	 * audit state without audit present in the system.
764	 *
765	 * XXXRW: Is there more to it than this?
766	 */
767	bzero(&auinfo, sizeof(auinfo));
768	auinfo.ai_asid = getpid();
769	if (setaudit(&auinfo) == -1) {
770		syslog(LOG_ERR, "Error setting audit stat");
771		fail_exit();
772	}
773
774	TAILQ_INIT(&dir_q);
775	if (read_control_file() == -1) {
776		syslog(LOG_ERR, "Error reading control file");
777		fail_exit();
778	}
779
780	/* Generate an audit record. */
781	if ((aufd = au_open()) == -1)
782		syslog(LOG_ERR, "Could not create audit startup event.");
783	else {
784		if ((tok = au_to_text("auditd::Audit startup")) != NULL)
785			au_write(aufd, tok);
786		if (au_close(aufd, 1, AUE_audit_startup) == -1)
787			syslog(LOG_ERR,
788			    "Could not close audit startup event.");
789	}
790
791	if (config_audit_controls() == 0)
792		syslog(LOG_INFO, "Audit controls init successful");
793	else
794		syslog(LOG_ERR, "Audit controls init failed");
795}
796
797int
798main(int argc, char **argv)
799{
800	int ch;
801	int debug = 0;
802	int rc;
803
804	global_flags |= AUDIT_CNT;
805	while ((ch = getopt(argc, argv, "dhs")) != -1) {
806		switch(ch) {
807		case 'd':
808			/* Debug option. */
809			debug = 1;
810			break;
811
812		case 's':
813			/* Fail-stop option. */
814			global_flags &= ~(AUDIT_CNT);
815			break;
816
817		case 'h':
818			/* Halt-stop option. */
819			global_flags |= AUDIT_AHLT;
820			break;
821
822		case '?':
823		default:
824			(void)fprintf(stderr,
825			    "usage: auditd [-h | -s] [-d] \n");
826			exit(1);
827		}
828	}
829
830#ifdef LOG_SECURITY
831	openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY);
832#else
833	openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH);
834#endif
835	syslog(LOG_INFO, "starting...");
836
837	if (debug == 0 && daemon(0, 0) == -1) {
838		syslog(LOG_ERR, "Failed to daemonize");
839		exit(1);
840	}
841
842	if (register_daemon() == -1) {
843		syslog(LOG_ERR, "Could not register as daemon");
844		exit(1);
845	}
846
847	setup();
848
849	rc = wait_for_events();
850	syslog(LOG_INFO, "auditd exiting.");
851
852	exit(rc);
853}
854