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