1 /*-
2  * Copyright (c) 2008-2009 Apple Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <sys/param.h>
31 
32 #include <config/config.h>
33 
34 #include <sys/dirent.h>
35 #ifdef HAVE_FULL_QUEUE_H
36 #include <sys/queue.h>
37 #else /* !HAVE_FULL_QUEUE_H */
38 #include <compat/queue.h>
39 #endif /* !HAVE_FULL_QUEUE_H */
40 #include <sys/mount.h>
41 #include <sys/socket.h>
42 
43 #include <sys/stat.h>
44 #include <sys/time.h>
45 
46 #include <netinet/in.h>
47 
48 #include <bsm/audit.h>
49 #include <bsm/audit_uevents.h>
50 #include <bsm/auditd_lib.h>
51 #include <bsm/libbsm.h>
52 
53 #include <assert.h>
54 #include <dirent.h>
55 #include <err.h>
56 #include <errno.h>
57 #include <fcntl.h>
58 #include <stdio.h>
59 #include <string.h>
60 #include <stdlib.h>
61 #include <time.h>
62 #include <unistd.h>
63 #include <netdb.h>
64 
65 #ifdef __APPLE__
66 #include <notify.h>
67 #ifndef __BSM_INTERNAL_NOTIFY_KEY
68 #define	__BSM_INTERNAL_NOTIFY_KEY	"com.apple.audit.change"
69 #endif /* __BSM_INTERNAL_NOTIFY_KEY */
70 #endif /* __APPLE__ */
71 
72 /*
73  * XXX This is temporary until this is moved to <bsm/audit.h> and shared with
74  * the kernel.
75  */
76 #ifndef	AUDIT_HARD_LIMIT_FREE_BLOCKS
77 #define	AUDIT_HARD_LIMIT_FREE_BLOCKS	4
78 #endif
79 
80 /*
81  * Number of seconds to January 1, 2000
82  */
83 #define	JAN_01_2000	946598400
84 
85 struct dir_ent {
86 	char			*dirname;
87 	uint8_t			 softlim;
88 	uint8_t			 hardlim;
89 	TAILQ_ENTRY(dir_ent)	 dirs;
90 };
91 
92 static TAILQ_HEAD(, dir_ent)	dir_q;
93 
94 struct audit_trail {
95 	time_t			 at_time;
96 	char			*at_path;
97 	off_t			 at_size;
98 
99 	TAILQ_ENTRY(audit_trail) at_trls;
100 };
101 
102 static int auditd_minval = -1;
103 static int auditd_dist = 0;
104 
105 static char auditd_host[MAXHOSTNAMELEN];
106 static int auditd_hostlen = -1;
107 
108 static char *auditd_errmsg[] = {
109 	"no error",					/* ADE_NOERR	( 0) */
110 	"could not parse audit_control(5) file",	/* ADE_PARSE	( 1) */
111 	"auditon(2) failed",				/* ADE_AUDITON	( 2) */
112 	"malloc(3) failed",				/* ADE_NOMEM	( 3) */
113 	"all audit log directories over soft limit",	/* ADE_SOFTLIM	( 4) */
114 	"all audit log directories over hard limit",	/* ADE_HARDLIM	( 5) */
115 	"could not create file name string",		/* ADE_STRERR	( 6) */
116 	"could not open audit record",			/* ADE_AU_OPEN	( 7) */
117 	"could not close audit record",			/* ADE_AU_CLOSE	( 8) */
118 	"could not set active audit session state",	/* ADE_SETAUDIT	( 9) */
119 	"auditctl(2) failed (trail still swapped)",	/* ADE_ACTL	(10) */
120 	"auditctl(2) failed (trail not swapped)",	/* ADE_ACTLERR	(11) */
121 	"could not swap audit trail file",		/* ADE_SWAPERR	(12) */
122 	"could not rename crash recovery file",		/* ADE_RENAME	(13) */
123 	"could not read 'current' link file",		/* ADE_READLINK	(14) */
124 	"could not create 'current' link file",		/* ADE_SYMLINK	(15) */
125 	"invalid argument",				/* ADE_INVAL	(16) */
126 	"could not resolve hostname to address",	/* ADE_GETADDR	(17) */
127 	"address family not supported",			/* ADE_ADDRFAM	(18) */
128 	"error expiring audit trail files",		/* ADE_EXPIRE	(19) */
129 };
130 
131 #define	MAXERRCODE	(sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0]))
132 
133 #define	NA_EVENT_STR_SIZE	128
134 #define	POL_STR_SIZE		128
135 
136 
137 /*
138  * Look up and return the error string for the given audit error code.
139  */
140 const char *
141 auditd_strerror(int errcode)
142 {
143 	int idx = -errcode;
144 
145 	if (idx < 0 || idx > (int)MAXERRCODE)
146 		return ("Invalid auditd error code");
147 
148 	return (auditd_errmsg[idx]);
149 }
150 
151 
152 /*
153  * Free our local list of directory names and init list.
154  */
155 static void
156 free_dir_q(void)
157 {
158 	struct dir_ent *d1, *d2;
159 
160 	d1 = TAILQ_FIRST(&dir_q);
161 	while (d1 != NULL) {
162 		d2 = TAILQ_NEXT(d1, dirs);
163 		free(d1->dirname);
164 		free(d1);
165 		d1 = d2;
166 	}
167 	TAILQ_INIT(&dir_q);
168 }
169 
170 /*
171  * Concat the directory name to the given file name.
172  * XXX We should affix the hostname also
173  */
174 static char *
175 affixdir(char *name, struct dir_ent *dirent)
176 {
177 	char *fn = NULL;
178 
179 	/*
180 	 * Sanity check on file name.
181 	 */
182 	if (strlen(name) != FILENAME_LEN) {
183 		errno = EINVAL;
184 		return (NULL);
185 	}
186 
187 	/*
188 	 * If the host is set then also add the hostname to the filename.
189 	 */
190 	if (auditd_hostlen != -1)
191 		asprintf(&fn, "%s/%s.%s", dirent->dirname, name, auditd_host);
192 	else
193 		asprintf(&fn, "%s/%s", dirent->dirname, name);
194 	return (fn);
195 }
196 
197 /*
198  * Insert the directory entry in the list by the way they are ordered in
199  * audit_control(5).  Move the entries that are over the soft and hard limits
200  * toward the tail.
201  */
202 static void
203 insert_orderly(struct dir_ent *denew)
204 {
205 	struct dir_ent *dep;
206 
207 	TAILQ_FOREACH(dep, &dir_q, dirs) {
208 		if (dep->softlim == 1 && denew->softlim == 0) {
209 			TAILQ_INSERT_BEFORE(dep, denew, dirs);
210 			return;
211 		}
212 		if (dep->hardlim == 1 && denew->hardlim == 0) {
213 			TAILQ_INSERT_BEFORE(dep, denew, dirs);
214 			return;
215 		}
216 	}
217 	TAILQ_INSERT_TAIL(&dir_q, denew, dirs);
218 }
219 
220 /*
221  * Get the min percentage of free blocks from audit_control(5) and that
222  * value in the kernel.  Return:
223  *	ADE_NOERR	on success,
224  *	ADE_PARSE	error parsing audit_control(5),
225  */
226 int
227 auditd_set_dist(void)
228 {
229 	int ret;
230 
231 	ret = getacdist();
232 	if (ret < 0)
233 		return (ADE_PARSE);
234 
235 	auditd_dist = ret;
236 
237 	return (ADE_NOERR);
238 }
239 
240 /*
241  * Get the host from audit_control(5) and set it in the audit kernel
242  * information.  Return:
243  *	ADE_NOERR	on success.
244  *	ADE_PARSE	error parsing audit_control(5).
245  *	ADE_AUDITON	error getting/setting auditon(2) value.
246  *	ADE_GETADDR	error getting address info for host.
247  *	ADE_ADDRFAM	un-supported address family.
248  */
249 int
250 auditd_set_host(void)
251 {
252 	struct sockaddr_in6 *sin6;
253 	struct sockaddr_in *sin;
254 	struct addrinfo *res;
255 	struct auditinfo_addr aia;
256 	int error, ret = ADE_NOERR;
257 
258 	if (getachost(auditd_host, sizeof(auditd_host)) != 0) {
259 		ret = ADE_PARSE;
260 
261 		/*
262 		 * To maintain reverse compatability with older audit_control
263 		 * files, simply drop a warning if the host parameter has not
264 		 * been set.  However, we will explicitly disable the
265 		 * generation of extended audit header by passing in a zeroed
266 		 * termid structure.
267 		 */
268 		bzero(&aia, sizeof(aia));
269 		aia.ai_termid.at_type = AU_IPv4;
270 		error = audit_set_kaudit(&aia, sizeof(aia));
271 		if (error < 0 && errno != ENOSYS)
272 			ret = ADE_AUDITON;
273 		return (ret);
274 	}
275 	auditd_hostlen = strlen(auditd_host);
276 	error = getaddrinfo(auditd_host, NULL, NULL, &res);
277 	if (error)
278 		return (ADE_GETADDR);
279 	switch (res->ai_family) {
280 	case PF_INET6:
281 		sin6 = (struct sockaddr_in6 *) res->ai_addr;
282 		bcopy(&sin6->sin6_addr.s6_addr,
283 		    &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
284 		aia.ai_termid.at_type = AU_IPv6;
285 		break;
286 
287 	case PF_INET:
288 		sin = (struct sockaddr_in *) res->ai_addr;
289 		bcopy(&sin->sin_addr.s_addr,
290 		    &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
291 		aia.ai_termid.at_type = AU_IPv4;
292 		break;
293 
294 	default:
295 		/* Un-supported address family in host parameter. */
296 		errno = EAFNOSUPPORT;
297 		return (ADE_ADDRFAM);
298 	}
299 
300 	if (audit_set_kaudit(&aia, sizeof(aia)) < 0)
301 		ret = ADE_AUDITON;
302 
303 	return (ret);
304 }
305 
306 /*
307  * Get the min percentage of free blocks from audit_control(5) and that
308  * value in the kernel.  Return:
309  *	ADE_NOERR	on success,
310  *	ADE_PARSE	error parsing audit_control(5),
311  *	ADE_AUDITON	error getting/setting auditon(2) value.
312  */
313 int
314 auditd_set_minfree(void)
315 {
316 	au_qctrl_t qctrl;
317 
318 	if (getacmin(&auditd_minval) != 0)
319 		return (ADE_PARSE);
320 
321 	if (audit_get_qctrl(&qctrl, sizeof(qctrl)) != 0)
322 		return (ADE_AUDITON);
323 
324 	if (qctrl.aq_minfree != auditd_minval) {
325 		qctrl.aq_minfree = auditd_minval;
326 		if (audit_set_qctrl(&qctrl, sizeof(qctrl)) != 0)
327 			return (ADE_AUDITON);
328 	}
329 
330 	return (0);
331 }
332 
333 /*
334  * Convert a trailname into a timestamp (seconds).  Return 0 if the conversion
335  * was successful.
336  */
337 static int
338 trailname_to_tstamp(char *fn, time_t *tstamp)
339 {
340 	struct tm tm;
341 	char ts[TIMESTAMP_LEN + 1];
342 	char *p;
343 
344 	*tstamp = 0;
345 
346 	/*
347 	 * Get the ending time stamp.
348 	 */
349 	if ((p = strchr(fn, '.')) == NULL)
350 		return (1);
351 	strlcpy(ts, ++p, sizeof(ts));
352 	if (strlen(ts) != POSTFIX_LEN)
353 		return (1);
354 
355 	bzero(&tm, sizeof(tm));
356 
357 	/* seconds (0-60) */
358 	p = ts + POSTFIX_LEN - 2;
359 	tm.tm_sec = atol(p);
360 	if (tm.tm_sec < 0 || tm.tm_sec > 60)
361 		return (1);
362 
363 	/* minutes (0-59) */
364 	*p = '\0'; p -= 2;
365 	tm.tm_min = atol(p);
366 	if (tm.tm_min < 0 || tm.tm_min > 59)
367 		return (1);
368 
369 	/* hours (0 - 23) */
370 	*p = '\0'; p -= 2;
371 	tm.tm_hour = atol(p);
372 	if (tm.tm_hour < 0 || tm.tm_hour > 23)
373 		return (1);
374 
375 	/* day of month (1-31) */
376 	*p = '\0'; p -= 2;
377 	tm.tm_mday = atol(p);
378 	if (tm.tm_mday < 1 || tm.tm_mday > 31)
379 		return (1);
380 
381 	/* month (0 - 11) */
382 	*p = '\0'; p -= 2;
383 	tm.tm_mon = atol(p) - 1;
384 	if (tm.tm_mon < 0 || tm.tm_mon > 11)
385 		return (1);
386 
387 	/* year (year - 1900) */
388 	*p = '\0'; p -= 4;
389 	tm.tm_year = atol(p) - 1900;
390 	if (tm.tm_year < 0)
391 		return (1);
392 
393 	*tstamp = timegm(&tm);
394 
395 	return (0);
396 }
397 
398 /*
399  * Remove audit trails files according to the expiration conditions.  Returns:
400  *	ADE_NOERR	on success or there is nothing to do.
401  *	ADE_PARSE	if error parsing audit_control(5).
402  *	ADE_NOMEM	if could not allocate memory.
403  *	ADE_READLINK	if could not read link file.
404  *	ADE_EXPIRE	if there was an unexpected error.
405  */
406 int
407 auditd_expire_trails(int (*warn_expired)(char *))
408 {
409 	int andflg, len, ret = ADE_NOERR;
410 	size_t expire_size, total_size = 0L;
411 	time_t expire_age, oldest_time, current_time = time(NULL);
412 	struct dir_ent *traildir;
413 	struct audit_trail *at;
414 	char *afnp, *pn;
415 	TAILQ_HEAD(au_trls_head, audit_trail) head =
416 	    TAILQ_HEAD_INITIALIZER(head);
417 	struct stat stbuf;
418 	char activefn[MAXPATHLEN];
419 
420 	/*
421 	 * Read the expiration conditions.  If no conditions then return no
422 	 * error.
423 	 */
424 	if (getacexpire(&andflg, &expire_age, &expire_size) < 0)
425 		return (ADE_PARSE);
426 	if (!expire_age && !expire_size)
427 		return (ADE_NOERR);
428 
429 	/*
430 	 * Read the 'current' trail file name.  Trim off directory path.
431 	 */
432 	activefn[0] = '\0';
433 	len = readlink(AUDIT_CURRENT_LINK, activefn, MAXPATHLEN - 1);
434 	if (len < 0)
435 		return (ADE_READLINK);
436 	if ((afnp = strrchr(activefn, '/')) != NULL)
437 		afnp++;
438 
439 
440 	/*
441 	 * Build tail queue of the trail files.
442 	 */
443 	TAILQ_FOREACH(traildir, &dir_q, dirs) {
444 		DIR *dirp;
445 		struct dirent *dp;
446 
447 		dirp = opendir(traildir->dirname);
448 		while ((dp = readdir(dirp)) != NULL) {
449 			time_t tstamp = 0;
450 			struct audit_trail *new;
451 
452 			/*
453 			 * Quickly filter non-trail files.
454 			 */
455 			if (dp->d_namlen < FILENAME_LEN ||
456 			    dp->d_name[POSTFIX_LEN] != '.')
457 				continue;
458 
459 			if (asprintf(&pn, "%s/%s", traildir->dirname,
460 			    dp->d_name) < 0) {
461 				ret = ADE_NOMEM;
462 				break;
463 			}
464 
465 			if (stat(pn, &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
466 				free(pn);
467 				continue;
468 			}
469 
470 			total_size += stbuf.st_size;
471 
472 			/*
473 			 * If this is the 'current' audit trail then
474 			 * don't add it to the tail queue.
475 			 */
476 			if (NULL != afnp && strcmp(dp->d_name, afnp) == 0) {
477 				free(pn);
478 				continue;
479 			}
480 
481 			/*
482 			 * Get the ending time stamp encoded in the trail
483 			 * name.  If we can't read it or if it is older
484 			 * than Jan 1, 2000 then use the mtime.
485 			 */
486 			if (trailname_to_tstamp(dp->d_name, &tstamp) != 0 ||
487 			    tstamp < JAN_01_2000)
488 				tstamp = stbuf.st_mtime;
489 
490 			/*
491 			 * If the time stamp is older than Jan 1, 2000 then
492 			 * update the mtime of the trail file to the current
493 			 * time. This is so we don't prematurely remove a trail
494 			 * file that was created while the system clock reset
495 			 * to the * "beginning of time" but later the system
496 			 * clock is set to the correct current time.
497 			 */
498 			if (current_time >= JAN_01_2000 &&
499 			    tstamp < JAN_01_2000) {
500 				struct timeval tv[2];
501 
502 				tstamp = stbuf.st_mtime = current_time;
503 				TIMESPEC_TO_TIMEVAL(&tv[0],
504 				    &stbuf.st_atimespec);
505 				TIMESPEC_TO_TIMEVAL(&tv[1],
506 				    &stbuf.st_mtimespec);
507 				utimes(pn, tv);
508 			}
509 
510 			/*
511 			 * Allocate and populate the new entry.
512 			 */
513 			new = malloc(sizeof(*new));
514 			if (NULL == new) {
515 				free(pn);
516 				ret = ADE_NOMEM;
517 				break;
518 			}
519 			new->at_time = tstamp;
520 			new->at_size = stbuf.st_size;
521 			new->at_path = pn;
522 
523 			/*
524 			 * Check to see if we have a new head.  Otherwise,
525 			 * walk the tailq from the tail first and do a simple
526 			 * insertion sort.
527 			 */
528 			if (TAILQ_EMPTY(&head) ||
529 			    new->at_time <= TAILQ_FIRST(&head)->at_time) {
530 				TAILQ_INSERT_HEAD(&head, new, at_trls);
531 				continue;
532 			}
533 
534 			TAILQ_FOREACH_REVERSE(at, &head, au_trls_head, at_trls)
535 				if (new->at_time >= at->at_time) {
536 					TAILQ_INSERT_AFTER(&head, at, new,
537 					    at_trls);
538 					break;
539 				}
540 
541 		}
542 		closedir(dirp);
543 	}
544 
545 	oldest_time = current_time - expire_age;
546 
547 	/*
548 	 * Expire trail files, oldest (mtime) first, if the given
549 	 * conditions are met.
550 	 */
551 	at = TAILQ_FIRST(&head);
552 	while (NULL != at) {
553 		struct audit_trail *at_next = TAILQ_NEXT(at, at_trls);
554 
555 		if (andflg) {
556 			if ((expire_size && total_size > expire_size) &&
557 			    (expire_age && at->at_time < oldest_time)) {
558 				if (warn_expired)
559 					(*warn_expired)(at->at_path);
560 				if (unlink(at->at_path) < 0)
561 					ret = ADE_EXPIRE;
562 				total_size -= at->at_size;
563 			}
564 		} else {
565 			if ((expire_size && total_size > expire_size) ||
566 			    (expire_age && at->at_time < oldest_time)) {
567 				if (warn_expired)
568 					(*warn_expired)(at->at_path);
569 				if (unlink(at->at_path) < 0)
570 					ret = ADE_EXPIRE;
571 				total_size -= at->at_size;
572 			}
573 		}
574 
575 		free(at->at_path);
576 		free(at);
577 		at = at_next;
578 	}
579 
580 	return (ret);
581 }
582 
583 /*
584  * Parses the "dir" entry in audit_control(5) into an ordered list.  Also, will
585  * set the minfree and host values if not already set.  Arguments include
586  * function pointers to audit_warn functions for soft and hard limits. Returns:
587  *	ADE_NOERR	on success,
588  *	ADE_PARSE	error parsing audit_control(5),
589  *	ADE_AUDITON	error getting/setting auditon(2) value,
590  *	ADE_NOMEM	error allocating memory,
591  *	ADE_SOFTLIM	if all the directories are over the soft limit,
592  *	ADE_HARDLIM	if all the directories are over the hard limit,
593  */
594 int
595 auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *))
596 {
597 	char cur_dir[MAXNAMLEN];
598 	struct dir_ent *dirent;
599 	struct statfs sfs;
600 	int err;
601 	char soft, hard;
602 	int tcnt = 0;
603 	int scnt = 0;
604 	int hcnt = 0;
605 
606 	if (auditd_minval == -1 && (err = auditd_set_minfree()) != 0)
607 		return (err);
608 
609 	if (auditd_hostlen == -1)
610 		auditd_set_host();
611 
612 	/*
613 	 * Init directory q.  Force a re-read of the file the next time.
614 	 */
615 	free_dir_q();
616 	endac();
617 
618 	/*
619 	 * Read the list of directories into an ordered linked list
620 	 * admin's preference, then those over soft limit and, finally,
621 	 * those over the hard limit.
622 	 *
623 	 * XXX We should use the reentrant interfaces once they are
624 	 * available.
625 	 */
626 	while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
627 		if (statfs(cur_dir, &sfs) < 0)
628 			continue;  /* XXX should warn */
629 		soft = (sfs.f_bfree < (sfs.f_blocks * auditd_minval / 100 )) ?
630 		    1 : 0;
631 		hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0;
632 		if (soft) {
633 			if (warn_soft)
634 				(*warn_soft)(cur_dir);
635 			scnt++;
636 		}
637 		if (hard) {
638 			if (warn_hard)
639 				(*warn_hard)(cur_dir);
640 			hcnt++;
641 		}
642 		dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
643 		if (dirent == NULL)
644 			return (ADE_NOMEM);
645 		dirent->softlim = soft;
646 		dirent->hardlim = hard;
647 		dirent->dirname = (char *) malloc(MAXNAMLEN);
648 		if (dirent->dirname == NULL) {
649 			free(dirent);
650 			return (ADE_NOMEM);
651 		}
652 		strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
653 		insert_orderly(dirent);
654 		tcnt++;
655 	}
656 
657 	if (hcnt == tcnt)
658 		return (ADE_HARDLIM);
659 	if (scnt == tcnt)
660 		return (ADE_SOFTLIM);
661 	return (0);
662 }
663 
664 void
665 auditd_close_dirs(void)
666 {
667 	free_dir_q();
668 	auditd_minval = -1;
669 	auditd_hostlen = -1;
670 }
671 
672 
673 /*
674  * Process the audit event file, obtaining a class mapping for each event, and
675  * set that mapping into the kernel. Return:
676  *	 n	number of event mappings that were successfully processed,
677  *   ADE_NOMEM	if there was an error allocating memory.
678  */
679 int
680 auditd_set_evcmap(void)
681 {
682 	au_event_ent_t ev, *evp;
683 	au_evclass_map_t evc_map;
684 	int ctr = 0;
685 
686 	/*
687 	 * XXX There's a risk here that the BSM library will return NULL
688 	 * for an event when it can't properly map it to a class. In that
689 	 * case, we will not process any events beyond the one that failed,
690 	 * but should. We need a way to get a count of the events.
691 	 */
692 	ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
693 	ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
694 	if (ev.ae_name == NULL || ev.ae_desc == NULL) {
695 		if (ev.ae_name != NULL)
696 			free(ev.ae_name);
697 		return (ADE_NOMEM);
698 	}
699 
700 	/*
701 	 * XXXRW: Currently we have no way to remove mappings from the kernel
702 	 * when they are removed from the file-based mappings.
703 	 */
704 	evp = &ev;
705 	setauevent();
706 	while ((evp = getauevent_r(evp)) != NULL) {
707 		evc_map.ec_number = evp->ae_number;
708 		evc_map.ec_class = evp->ae_class;
709 		if (audit_set_class(&evc_map, sizeof(evc_map)) == 0)
710 			ctr++;
711 	}
712 	endauevent();
713 	free(ev.ae_name);
714 	free(ev.ae_desc);
715 
716 	return (ctr);
717 }
718 
719 /*
720  * Get the non-attributable event string and set the kernel mask.  Return:
721  *	ADE_NOERR	on success,
722  *	ADE_PARSE	error parsing audit_control(5),
723  *	ADE_AUDITON	error setting the mask using auditon(2).
724  */
725 int
726 auditd_set_namask(void)
727 {
728 	au_mask_t aumask;
729 	char naeventstr[NA_EVENT_STR_SIZE];
730 
731 	if (getacna(naeventstr, NA_EVENT_STR_SIZE) != 0 ||
732 	    getauditflagsbin(naeventstr, &aumask) != 0)
733 		return (ADE_PARSE);
734 
735 	if (audit_set_kmask(&aumask, sizeof(aumask)) != 0)
736 		return (ADE_AUDITON);
737 
738 	return (ADE_NOERR);
739 }
740 
741 /*
742  * Set the audit control policy if a policy is configured in audit_control(5),
743  * implement the policy. However, if one isn't defined or if there is an error
744  * parsing the control file, set AUDIT_CNT to avoid leaving the system in a
745  * fragile state.  Return:
746  *	ADE_NOERR	on success,
747  *	ADE_PARSE	error parsing audit_control(5),
748  *	ADE_AUDITON	error setting policy using auditon(2).
749  */
750 int
751 auditd_set_policy(void)
752 {
753 	int policy;
754 	char polstr[POL_STR_SIZE];
755 
756 	if (getacpol(polstr, POL_STR_SIZE) != 0 ||
757 	    au_strtopol(polstr, &policy) != 0) {
758 		policy = AUDIT_CNT;
759 		if (audit_set_policy(&policy) != 0)
760 			return (ADE_AUDITON);
761 		return (ADE_PARSE);
762 	}
763 
764 	if (audit_set_policy(&policy) != 0)
765 		return (ADE_AUDITON);
766 
767 	return (ADE_NOERR);
768 }
769 
770 /*
771  * Set trail rotation size.  Return:
772  *	ADE_NOERR	on success,
773  *	ADE_PARSE	error parsing audit_control(5),
774  *	ADE_AUDITON	error setting file size using auditon(2).
775  */
776 int
777 auditd_set_fsize(void)
778 {
779 	size_t filesz;
780 	au_fstat_t au_fstat;
781 
782 	/*
783 	 * Set trail rotation size.
784 	 */
785 	if (getacfilesz(&filesz) != 0)
786 		return (ADE_PARSE);
787 
788 	bzero(&au_fstat, sizeof(au_fstat));
789 	au_fstat.af_filesz = filesz;
790 	if (audit_set_fsize(&au_fstat, sizeof(au_fstat)) != 0)
791 		return (ADE_AUDITON);
792 
793 	return (ADE_NOERR);
794 }
795 
796 static void
797 inject_dist(const char *fromname, char *toname, size_t tonamesize)
798 {
799 	char *ptr;
800 
801 	ptr = strrchr(fromname, '/');
802 	assert(ptr != NULL);
803 	assert(ptr - fromname < (ssize_t)tonamesize);
804 	strlcpy(toname, fromname, ptr - fromname + 1);
805 	strlcat(toname, "/dist/", tonamesize);
806 	strlcat(toname, ptr + 1, tonamesize);
807 }
808 
809 static int
810 auditdist_link(const char *filename)
811 {
812 	char fname[MAXPATHLEN];
813 
814 	if (auditd_dist) {
815 		inject_dist(filename, fname, sizeof(fname));
816 		/* Ignore errors. */
817 		(void) link(filename, fname);
818 	}
819 
820 	return (0);
821 }
822 
823 int
824 auditd_rename(const char *fromname, const char *toname)
825 {
826 	char fname[MAXPATHLEN], tname[MAXPATHLEN];
827 
828 	if (auditd_dist) {
829 		inject_dist(fromname, fname, sizeof(fname));
830 		inject_dist(toname, tname, sizeof(tname));
831 		/* Ignore errors. */
832 		(void) rename(fname, tname);
833 	}
834 
835 	return (rename(fromname, toname));
836 }
837 
838 /*
839  * Create the new audit file with appropriate permissions and ownership.
840  * Call auditctl(2) for this file.
841  * Try to clean up if something goes wrong.
842  * *errorp is modified only on auditctl(2) failure.
843  */
844 static int
845 open_trail(char *fname, gid_t gid, int *errorp)
846 {
847 	int fd;
848 
849 	/* XXXPJD: What should we do if the file already exists? */
850 	fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR);
851 	if (fd < 0)
852 		return (-1);
853 	if (fchown(fd, -1, gid) < 0 || fchmod(fd, S_IRUSR | S_IRGRP) < 0) {
854 		(void) close(fd);
855 		(void) unlink(fname);
856 		return (-1);
857 	}
858 	(void) close(fd);
859 	if (auditctl(fname) < 0) {
860 		*errorp = errno;
861 		(void) unlink(fname);
862 		return (-1);
863 	}
864 	(void) auditdist_link(fname);
865 	return (0);
866 }
867 
868 /*
869  * Create the new audit trail file, swap with existing audit file.  Arguments
870  * include timestamp for the filename, a pointer to a string for returning the
871  * new file name, GID for trail file, and audit_warn function pointer for
872  * 'getacdir()' errors.  Returns:
873  *	ADE_NOERR	on success,
874  *	ADE_STRERR	if the file name string could not be created,
875  *	ADE_SWAPERR	if the audit trail file could not be swapped,
876  *	ADE_ACTL	if the auditctl(2) call failed but file swap still
877  *			successful.
878  *	ADE_ACTLERR	if the auditctl(2) call failed and file swap failed.
879  *	ADE_SYMLINK	if symlink(2) failed updating the current link.
880  */
881 int
882 auditd_swap_trail(char *TS, char **newfile, gid_t gid,
883     int (*warn_getacdir)(char *))
884 {
885 	char timestr[FILENAME_LEN + 1];
886 	char *fn;
887 	struct dir_ent *dirent;
888 	int saverrno = 0;
889 
890 	if (strlen(TS) != TIMESTAMP_LEN ||
891 	    snprintf(timestr, sizeof(timestr), "%s.%s", TS,
892 	    NOT_TERMINATED) < 0) {
893 		errno = EINVAL;
894 		return (ADE_STRERR);
895 	}
896 
897 	/* Try until we succeed. */
898 	TAILQ_FOREACH(dirent, &dir_q, dirs) {
899 		if (dirent->hardlim)
900 			continue;
901 		if ((fn = affixdir(timestr, dirent)) == NULL)
902 			return (ADE_STRERR);
903 
904 		/*
905 		 * Create the file and pass to the kernel if all went well.
906 		 */
907 		if (open_trail(fn, gid, &saverrno) == 0) {
908 			/* Success. */
909 			*newfile = fn;
910 			if (saverrno) {
911 				/*
912 				 * auditctl() failed but still
913 				 * successful. Return errno and "soft"
914 				 * error.
915 				 */
916 				errno = saverrno;
917 				return (ADE_ACTL);
918 			}
919 			return (ADE_NOERR);
920 		}
921 		/*
922 		 * auditctl failed setting log file. Try again.
923 		 */
924 		/*
925 		 * Tell the administrator about lack of permissions for dir.
926 		 */
927 		if (warn_getacdir != NULL)
928 			(*warn_getacdir)(dirent->dirname);
929 	}
930 	if (saverrno) {
931 		errno = saverrno;
932 		return (ADE_ACTLERR);
933 	} else
934 		return (ADE_SWAPERR);
935 }
936 
937 /*
938  * Mask calling process from being audited. Returns:
939  *	ADE_NOERR	on success,
940  *	ADE_SETAUDIT	if setaudit(2) fails.
941  */
942 #ifdef __APPLE__
943 int
944 auditd_prevent_audit(void)
945 {
946 	auditinfo_addr_t aia;
947 
948 	/*
949 	 * To prevent event feedback cycles and avoid audit becoming stalled if
950 	 * auditing is suspended we mask this processes events from being
951 	 * audited.  We allow the uid, tid, and mask fields to be implicitly
952 	 * set to zero, but do set the audit session ID to the PID.
953 	 *
954 	 * XXXRW: Is there more to it than this?
955 	 */
956 	bzero(&aia, sizeof(aia));
957 	aia.ai_asid = AU_ASSIGN_ASID;
958 	aia.ai_termid.at_type = AU_IPv4;
959 	if (setaudit_addr(&aia, sizeof(aia)) != 0)
960 		return (ADE_SETAUDIT);
961 	return (ADE_NOERR);
962 }
963 #else
964 int
965 auditd_prevent_audit(void)
966 {
967 	auditinfo_t ai;
968 
969 	/*
970 	 * To prevent event feedback cycles and avoid audit becoming stalled if
971 	 * auditing is suspended we mask this processes events from being
972 	 * audited.  We allow the uid, tid, and mask fields to be implicitly
973 	 * set to zero, but do set the audit session ID to the PID.
974 	 *
975 	 * XXXRW: Is there more to it than this?
976 	 */
977 	bzero(&ai, sizeof(ai));
978 	ai.ai_asid = getpid();
979 	if (setaudit(&ai) != 0)
980 		return (ADE_SETAUDIT);
981 	return (ADE_NOERR);
982 }
983 #endif /* !__APPLE__ */
984 
985 /*
986  * Generate and submit audit record for audit startup or shutdown.  The event
987  * argument can be AUE_audit_recovery, AUE_audit_startup or
988  * AUE_audit_shutdown. The path argument will add a path token, if not NULL.
989  * Returns:
990  *	AUE_NOERR	on success,
991  *	ADE_NOMEM	if memory allocation fails,
992  *	ADE_AU_OPEN	if au_open(3) fails,
993  *	ADE_AU_CLOSE	if au_close(3) fails.
994  */
995 int
996 auditd_gen_record(int event, char *path)
997 {
998 	int aufd;
999 	uid_t uid;
1000 	pid_t pid;
1001 	char *autext = NULL;
1002 	token_t *tok;
1003 	struct auditinfo_addr aia;
1004 
1005 	if (event == AUE_audit_startup)
1006 		asprintf(&autext, "%s::Audit startup", getprogname());
1007 	else if (event == AUE_audit_shutdown)
1008 		asprintf(&autext, "%s::Audit shutdown", getprogname());
1009 	else if (event == AUE_audit_recovery)
1010 		asprintf(&autext, "%s::Audit recovery", getprogname());
1011 	else
1012 		return (ADE_INVAL);
1013 	if (autext == NULL)
1014 		return (ADE_NOMEM);
1015 
1016 	if ((aufd = au_open()) == -1) {
1017 		free(autext);
1018 		return (ADE_AU_OPEN);
1019 	}
1020 	bzero(&aia, sizeof(aia));
1021 	uid = getuid(); pid = getpid();
1022 	if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, getgid(),
1023 	    pid, pid, &aia.ai_termid)) != NULL)
1024 		au_write(aufd, tok);
1025 	if ((tok = au_to_text(autext)) != NULL)
1026 		au_write(aufd, tok);
1027 	free(autext);
1028 	if (path != NULL && (tok = au_to_path(path)) != NULL)
1029 		au_write(aufd, tok);
1030 	if ((tok = au_to_return32(0, 0)) != NULL)
1031 		au_write(aufd, tok);
1032 	if (au_close(aufd, 1, event) == -1)
1033 		return (ADE_AU_CLOSE);
1034 
1035 	return (ADE_NOERR);
1036 }
1037 
1038 /*
1039  * Check for a 'current' symlink and do crash recovery, if needed. Create a new
1040  * 'current' symlink. The argument 'curfile' is the file the 'current' symlink
1041  * should point to.  Returns:
1042  *	ADE_NOERR	on success,
1043  *	ADE_AU_OPEN	if au_open(3) fails,
1044  *	ADE_AU_CLOSE	if au_close(3) fails.
1045  *	ADE_RENAME	if error renaming audit trail file,
1046  *	ADE_READLINK	if error reading the 'current' link,
1047  *	ADE_SYMLINK	if error creating 'current' link.
1048  */
1049 int
1050 auditd_new_curlink(char *curfile)
1051 {
1052 	int len, err;
1053 	char *ptr;
1054 	char *path = NULL;
1055 	struct stat sb;
1056 	char recoveredname[MAXPATHLEN];
1057 	char newname[MAXPATHLEN];
1058 
1059 	/*
1060 	 * Check to see if audit was shutdown properly.  If not, clean up,
1061 	 * recover previous audit trail file, and generate audit record.
1062 	 */
1063 	len = readlink(AUDIT_CURRENT_LINK, recoveredname,
1064 	    sizeof(recoveredname) - 1);
1065 	if (len > 0) {
1066 		/* 'current' exist but is it pointing at a valid file?  */
1067 		recoveredname[len++] = '\0';
1068 		if (stat(recoveredname, &sb) == 0) {
1069 			/* Yes, rename it to a crash recovery file. */
1070 			strlcpy(newname, recoveredname, sizeof(newname));
1071 
1072 			if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
1073 				memcpy(ptr, CRASH_RECOVERY, POSTFIX_LEN);
1074 				if (auditd_rename(recoveredname, newname) != 0)
1075 					return (ADE_RENAME);
1076 			} else
1077 				return (ADE_STRERR);
1078 
1079 			path = newname;
1080 		}
1081 
1082 		/* 'current' symlink is (now) invalid so remove it. */
1083 		(void) unlink(AUDIT_CURRENT_LINK);
1084 
1085 		/* Note the crash recovery in current audit trail */
1086 		err = auditd_gen_record(AUE_audit_recovery, path);
1087 		if (err)
1088 			return (err);
1089 	}
1090 
1091 	if (len < 0 && errno != ENOENT)
1092 		return (ADE_READLINK);
1093 
1094 	if (symlink(curfile, AUDIT_CURRENT_LINK) != 0)
1095 		return (ADE_SYMLINK);
1096 
1097 	return (0);
1098 }
1099 
1100 /*
1101  * Do just what we need to quickly start auditing.  Assume no system logging or
1102  * notify.  Return:
1103  *   0	 on success,
1104  *  -1   on failure.
1105  */
1106 int
1107 audit_quick_start(void)
1108 {
1109 	int err;
1110 	char *newfile = NULL;
1111 	time_t tt;
1112 	char TS[TIMESTAMP_LEN + 1];
1113 	int ret = 0;
1114 
1115 	/*
1116 	 * Mask auditing of this process.
1117 	 */
1118 	if (auditd_prevent_audit() != 0)
1119 		return (-1);
1120 
1121 	/*
1122 	 * Read audit_control and get log directories.
1123 	 */
1124 	err = auditd_read_dirs(NULL, NULL);
1125 	if (err != ADE_NOERR && err != ADE_SOFTLIM)
1126 		return (-1);
1127 
1128 	/*
1129 	 * Setup trail file distribution.
1130 	 */
1131 	(void) auditd_set_dist();
1132 
1133 	/*
1134 	 *  Create a new audit trail log.
1135 	 */
1136 	if (getTSstr(tt, TS, sizeof(TS)) != 0)
1137 		return (-1);
1138 	err = auditd_swap_trail(TS, &newfile, getgid(), NULL);
1139 	if (err != ADE_NOERR && err != ADE_ACTL) {
1140 		ret = -1;
1141 		goto out;
1142 	}
1143 
1144 	/*
1145 	 * Add the current symlink and recover from crash, if needed.
1146 	 */
1147 	if (auditd_new_curlink(newfile) != 0) {
1148 		ret = -1;
1149 		goto out;
1150 	}
1151 
1152 	/*
1153 	 * At this point auditing has started so generate audit start-up record.
1154 	 */
1155 	if (auditd_gen_record(AUE_audit_startup, NULL) != 0) {
1156 		ret = -1;
1157 		goto out;
1158 	}
1159 
1160 	/*
1161 	 *  Configure the audit controls.
1162 	 */
1163 	(void) auditd_set_evcmap();
1164 	(void) auditd_set_namask();
1165 	(void) auditd_set_policy();
1166 	(void) auditd_set_fsize();
1167 	(void) auditd_set_minfree();
1168 	(void) auditd_set_host();
1169 
1170 out:
1171 	if (newfile != NULL)
1172 		free(newfile);
1173 
1174 	return (ret);
1175 }
1176 
1177 /*
1178  * Shut down auditing quickly.  Assumes that is only called on system shutdown.
1179  * Returns:
1180  *	 0	on success,
1181  *	-1	on failure.
1182  */
1183 int
1184 audit_quick_stop(void)
1185 {
1186 	int len;
1187 	int cond;
1188 	char *ptr;
1189 	time_t tt;
1190 	char oldname[MAXPATHLEN];
1191 	char newname[MAXPATHLEN];
1192 	char TS[TIMESTAMP_LEN + 1];
1193 
1194 	/*
1195 	 * Auditing already disabled?
1196 	 */
1197 	if (audit_get_cond(&cond) != 0)
1198 		return (-1);
1199 	if (cond == AUC_NOAUDIT)
1200 		return (0);
1201 
1202 	/*
1203 	 *  Generate audit shutdown record.
1204 	 */
1205 	(void) auditd_gen_record(AUE_audit_shutdown, NULL);
1206 
1207 	/*
1208 	 * Shutdown auditing in the kernel.
1209 	 */
1210 	cond = AUC_DISABLED;
1211 	if (audit_set_cond(&cond) != 0)
1212 		return (-1);
1213 #ifdef	__BSM_INTERNAL_NOTIFY_KEY
1214 	notify_post(__BSM_INTERNAL_NOTIFY_KEY);
1215 #endif
1216 
1217 	/*
1218 	 * Rename last audit trail and remove 'current' link.
1219 	 */
1220 	len = readlink(AUDIT_CURRENT_LINK, oldname, sizeof(oldname) - 1);
1221 	if (len < 0)
1222 		return (-1);
1223 	oldname[len++] = '\0';
1224 
1225 	if (getTSstr(tt, TS, sizeof(TS)) != 0)
1226 		return (-1);
1227 
1228 	strlcpy(newname, oldname, sizeof(newname));
1229 
1230 	if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
1231 		memcpy(ptr, TS, POSTFIX_LEN);
1232 		if (auditd_rename(oldname, newname) != 0)
1233 			return (-1);
1234 	} else
1235 		return (-1);
1236 
1237 	(void) unlink(AUDIT_CURRENT_LINK);
1238 
1239 	return (0);
1240 }
1241