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