xref: /freebsd/contrib/openbsm/bin/auditd/auditd.c (revision 8847579c57d6aff2b3371c707dce7a2cee8389aa)
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#16 $
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 
63 static int	 ret, minval;
64 static char	*lastfile = NULL;
65 static int	 allhardcount = 0;
66 static int	 triggerfd = 0;
67 static int	 sigchlds, sigchlds_handled;
68 static int	 sighups, sighups_handled;
69 static int	 sigterms, sigterms_handled;
70 static long	 global_flags;
71 
72 static TAILQ_HEAD(, dir_ent)	dir_q;
73 
74 static int	config_audit_controls(void);
75 
76 /*
77  * Error starting auditd
78  */
79 static void
80 fail_exit(void)
81 {
82 
83 	audit_warn_nostart();
84 	exit(1);
85 }
86 
87 /*
88  * Free our local list of directory names.
89  */
90 static void
91 free_dir_q()
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  */
105 static int
106 getTSstr(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  */
124 static char *
125 affixdir(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  */
146 static int
147 close_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  */
180 static int
181 #ifdef AUDIT_REVIEW_GROUP
182 open_trail(const char *fname, uid_t uid, gid_t gid)
183 #else
184 open_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  */
207 static int
208 swap_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  */
296 static int
297 read_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  */
366 static int
367 close_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  */
419 static void
420 relay_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  */
434 static int
435 register_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
490 static void
491 handle_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 
592 static void
593 handle_sighup(void)
594 {
595 
596 	sighups_handled = sighups;
597 	config_audit_controls();
598 }
599 
600 /*
601  * Reap our children.
602  */
603 static void
604 reap_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 
620 static void
621 handle_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  */
631 static int
632 wait_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  */
674 static int
675 config_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 
745 static void
746 setup(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 
797 int
798 main(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