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