2 * Copyright (c) 2008-2009 Apple Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#18 $
32 #include <sys/param.h>
34 #include <config/config.h>
36 #include <sys/dirent.h>
37 #ifdef HAVE_FULL_QUEUE_H
38 #include <sys/queue.h>
39 #else /* !HAVE_FULL_QUEUE_H */
40 #include <compat/queue.h>
41 #endif /* !HAVE_FULL_QUEUE_H */
42 #include <sys/mount.h>
43 #include <sys/socket.h>
48 #include <netinet/in.h>
50 #include <bsm/audit.h>
51 #include <bsm/audit_uevents.h>
52 #include <bsm/auditd_lib.h>
53 #include <bsm/libbsm.h>
69 #ifndef __BSM_INTERNAL_NOTIFY_KEY
70 #define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
71 #endif /* __BSM_INTERNAL_NOTIFY_KEY */
72 #endif /* __APPLE__ */
75 * XXX This is temporary until this is moved to <bsm/audit.h> and shared with
78 #ifndef AUDIT_HARD_LIMIT_FREE_BLOCKS
79 #define AUDIT_HARD_LIMIT_FREE_BLOCKS 4
83 * Number of seconds to January 1, 2000
85 #define JAN_01_2000 946598400
91 TAILQ_ENTRY(dir_ent) dirs;
94 static TAILQ_HEAD(, dir_ent) dir_q;
101 TAILQ_ENTRY(audit_trail) at_trls;
104 static int auditd_minval = -1;
105 static int auditd_dist = 0;
107 static char auditd_host[MAXHOSTNAMELEN];
108 static int auditd_hostlen = -1;
110 static char *auditd_errmsg[] = {
111 "no error", /* ADE_NOERR ( 0) */
112 "could not parse audit_control(5) file", /* ADE_PARSE ( 1) */
113 "auditon(2) failed", /* ADE_AUDITON ( 2) */
114 "malloc(3) failed", /* ADE_NOMEM ( 3) */
115 "all audit log directories over soft limit", /* ADE_SOFTLIM ( 4) */
116 "all audit log directories over hard limit", /* ADE_HARDLIM ( 5) */
117 "could not create file name string", /* ADE_STRERR ( 6) */
118 "could not open audit record", /* ADE_AU_OPEN ( 7) */
119 "could not close audit record", /* ADE_AU_CLOSE ( 8) */
120 "could not set active audit session state", /* ADE_SETAUDIT ( 9) */
121 "auditctl(2) failed (trail still swapped)", /* ADE_ACTL (10) */
122 "auditctl(2) failed (trail not swapped)", /* ADE_ACTLERR (11) */
123 "could not swap audit trail file", /* ADE_SWAPERR (12) */
124 "could not rename crash recovery file", /* ADE_RENAME (13) */
125 "could not read 'current' link file", /* ADE_READLINK (14) */
126 "could not create 'current' link file", /* ADE_SYMLINK (15) */
127 "invalid argument", /* ADE_INVAL (16) */
128 "could not resolve hostname to address", /* ADE_GETADDR (17) */
129 "address family not supported", /* ADE_ADDRFAM (18) */
130 "error expiring audit trail files", /* ADE_EXPIRE (19) */
133 #define MAXERRCODE (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0]))
135 #define NA_EVENT_STR_SIZE 128
136 #define POL_STR_SIZE 128
140 * Look up and return the error string for the given audit error code.
143 auditd_strerror(int errcode)
147 if (idx < 0 || idx > (int)MAXERRCODE)
148 return ("Invalid auditd error code");
150 return (auditd_errmsg[idx]);
155 * Free our local list of directory names and init list.
160 struct dir_ent *d1, *d2;
162 d1 = TAILQ_FIRST(&dir_q);
164 d2 = TAILQ_NEXT(d1, dirs);
173 * Concat the directory name to the given file name.
174 * XXX We should affix the hostname also
177 affixdir(char *name, struct dir_ent *dirent)
182 * Sanity check on file name.
184 if (strlen(name) != FILENAME_LEN) {
190 * If the host is set then also add the hostname to the filename.
192 if (auditd_hostlen != -1)
193 asprintf(&fn, "%s/%s.%s", dirent->dirname, name, auditd_host);
195 asprintf(&fn, "%s/%s", dirent->dirname, name);
200 * Insert the directory entry in the list by the way they are ordered in
201 * audit_control(5). Move the entries that are over the soft and hard limits
205 insert_orderly(struct dir_ent *denew)
209 TAILQ_FOREACH(dep, &dir_q, dirs) {
210 if (dep->softlim == 1 && denew->softlim == 0) {
211 TAILQ_INSERT_BEFORE(dep, denew, dirs);
214 if (dep->hardlim == 1 && denew->hardlim == 0) {
215 TAILQ_INSERT_BEFORE(dep, denew, dirs);
219 TAILQ_INSERT_TAIL(&dir_q, denew, dirs);
223 * Get the min percentage of free blocks from audit_control(5) and that
224 * value in the kernel. Return:
225 * ADE_NOERR on success,
226 * ADE_PARSE error parsing audit_control(5),
229 auditd_set_dist(void)
243 * Get the host from audit_control(5) and set it in the audit kernel
244 * information. Return:
245 * ADE_NOERR on success.
246 * ADE_PARSE error parsing audit_control(5).
247 * ADE_AUDITON error getting/setting auditon(2) value.
248 * ADE_GETADDR error getting address info for host.
249 * ADE_ADDRFAM un-supported address family.
252 auditd_set_host(void)
254 struct sockaddr_in6 *sin6;
255 struct sockaddr_in *sin;
256 struct addrinfo *res;
257 struct auditinfo_addr aia;
258 int error, ret = ADE_NOERR;
260 if (getachost(auditd_host, sizeof(auditd_host)) != 0) {
264 * To maintain reverse compatability with older audit_control
265 * files, simply drop a warning if the host parameter has not
266 * been set. However, we will explicitly disable the
267 * generation of extended audit header by passing in a zeroed
270 bzero(&aia, sizeof(aia));
271 aia.ai_termid.at_type = AU_IPv4;
272 error = audit_set_kaudit(&aia, sizeof(aia));
273 if (error < 0 && errno != ENOSYS)
277 auditd_hostlen = strlen(auditd_host);
278 error = getaddrinfo(auditd_host, NULL, NULL, &res);
280 return (ADE_GETADDR);
281 switch (res->ai_family) {
283 sin6 = (struct sockaddr_in6 *) res->ai_addr;
284 bcopy(&sin6->sin6_addr.s6_addr,
285 &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
286 aia.ai_termid.at_type = AU_IPv6;
290 sin = (struct sockaddr_in *) res->ai_addr;
291 bcopy(&sin->sin_addr.s_addr,
292 &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
293 aia.ai_termid.at_type = AU_IPv4;
297 /* Un-supported address family in host parameter. */
298 errno = EAFNOSUPPORT;
299 return (ADE_ADDRFAM);
302 if (audit_set_kaudit(&aia, sizeof(aia)) < 0)
309 * Get the min percentage of free blocks from audit_control(5) and that
310 * value in the kernel. Return:
311 * ADE_NOERR on success,
312 * ADE_PARSE error parsing audit_control(5),
313 * ADE_AUDITON error getting/setting auditon(2) value.
316 auditd_set_minfree(void)
320 if (getacmin(&auditd_minval) != 0)
323 if (audit_get_qctrl(&qctrl, sizeof(qctrl)) != 0)
324 return (ADE_AUDITON);
326 if (qctrl.aq_minfree != auditd_minval) {
327 qctrl.aq_minfree = auditd_minval;
328 if (audit_set_qctrl(&qctrl, sizeof(qctrl)) != 0)
329 return (ADE_AUDITON);
336 * Convert a trailname into a timestamp (seconds). Return 0 if the conversion
340 trailname_to_tstamp(char *fn, time_t *tstamp)
343 char ts[TIMESTAMP_LEN + 1];
349 * Get the ending time stamp.
351 if ((p = strchr(fn, '.')) == NULL)
353 strlcpy(ts, ++p, sizeof(ts));
354 if (strlen(ts) != POSTFIX_LEN)
357 bzero(&tm, sizeof(tm));
360 p = ts + POSTFIX_LEN - 2;
362 if (tm.tm_sec < 0 || tm.tm_sec > 60)
368 if (tm.tm_min < 0 || tm.tm_min > 59)
373 tm.tm_hour = atol(p);
374 if (tm.tm_hour < 0 || tm.tm_hour > 23)
377 /* day of month (1-31) */
379 tm.tm_mday = atol(p);
380 if (tm.tm_mday < 1 || tm.tm_mday > 31)
385 tm.tm_mon = atol(p) - 1;
386 if (tm.tm_mon < 0 || tm.tm_mon > 11)
389 /* year (year - 1900) */
391 tm.tm_year = atol(p) - 1900;
395 *tstamp = timegm(&tm);
401 * Remove audit trails files according to the expiration conditions. Returns:
402 * ADE_NOERR on success or there is nothing to do.
403 * ADE_PARSE if error parsing audit_control(5).
404 * ADE_NOMEM if could not allocate memory.
405 * ADE_EXPIRE if there was an unespected error.
408 auditd_expire_trails(int (*warn_expired)(char *))
410 int andflg, ret = ADE_NOERR;
411 size_t expire_size, total_size = 0L;
412 time_t expire_age, oldest_time, current_time = time(NULL);
413 struct dir_ent *traildir;
414 struct audit_trail *at;
416 TAILQ_HEAD(au_trls_head, audit_trail) head =
417 TAILQ_HEAD_INITIALIZER(head);
419 char activefn[MAXPATHLEN];
422 * Read the expiration conditions. If no conditions then return no
425 if (getacexpire(&andflg, &expire_age, &expire_size) < 0)
427 if (!expire_age && !expire_size)
431 * Read the 'current' trail file name. Trim off directory path.
434 readlink(AUDIT_CURRENT_LINK, activefn, MAXPATHLEN - 1);
435 if ((afnp = strrchr(activefn, '/')) != NULL)
440 * Build tail queue of the trail files.
442 TAILQ_FOREACH(traildir, &dir_q, dirs) {
446 dirp = opendir(traildir->dirname);
447 while ((dp = readdir(dirp)) != NULL) {
449 struct audit_trail *new;
452 * Quickly filter non-trail files.
454 if (dp->d_namlen < FILENAME_LEN ||
455 dp->d_name[POSTFIX_LEN] != '.')
458 if (asprintf(&pn, "%s/%s", traildir->dirname,
464 if (stat(pn, &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
469 total_size += stbuf.st_size;
472 * If this is the 'current' audit trail then
473 * don't add it to the tail queue.
475 if (NULL != afnp && strcmp(dp->d_name, afnp) == 0) {
481 * Get the ending time stamp encoded in the trail
482 * name. If we can't read it or if it is older
483 * than Jan 1, 2000 then use the mtime.
485 if (trailname_to_tstamp(dp->d_name, &tstamp) != 0 ||
486 tstamp < JAN_01_2000)
487 tstamp = stbuf.st_mtime;
490 * If the time stamp is older than Jan 1, 2000 then
491 * update the mtime of the trail file to the current
492 * time. This is so we don't prematurely remove a trail
493 * file that was created while the system clock reset
494 * to the * "beginning of time" but later the system
495 * clock is set to the correct current time.
497 if (current_time >= JAN_01_2000 &&
498 tstamp < JAN_01_2000) {
499 struct timeval tv[2];
501 tstamp = stbuf.st_mtime = current_time;
502 TIMESPEC_TO_TIMEVAL(&tv[0],
503 &stbuf.st_atimespec);
504 TIMESPEC_TO_TIMEVAL(&tv[1],
505 &stbuf.st_mtimespec);
510 * Allocate and populate the new entry.
512 new = malloc(sizeof(*new));
518 new->at_time = tstamp;
519 new->at_size = stbuf.st_size;
523 * Check to see if we have a new head. Otherwise,
524 * walk the tailq from the tail first and do a simple
527 if (TAILQ_EMPTY(&head) ||
528 new->at_time <= TAILQ_FIRST(&head)->at_time) {
529 TAILQ_INSERT_HEAD(&head, new, at_trls);
533 TAILQ_FOREACH_REVERSE(at, &head, au_trls_head, at_trls)
534 if (new->at_time >= at->at_time) {
535 TAILQ_INSERT_AFTER(&head, at, new,
544 oldest_time = current_time - expire_age;
547 * Expire trail files, oldest (mtime) first, if the given
548 * conditions are met.
550 at = TAILQ_FIRST(&head);
552 struct audit_trail *at_next = TAILQ_NEXT(at, at_trls);
555 if ((expire_size && total_size > expire_size) &&
556 (expire_age && at->at_time < oldest_time)) {
558 (*warn_expired)(at->at_path);
559 if (unlink(at->at_path) < 0)
561 total_size -= at->at_size;
564 if ((expire_size && total_size > expire_size) ||
565 (expire_age && at->at_time < oldest_time)) {
567 (*warn_expired)(at->at_path);
568 if (unlink(at->at_path) < 0)
570 total_size -= at->at_size;
583 * Parses the "dir" entry in audit_control(5) into an ordered list. Also, will
584 * set the minfree and host values if not already set. Arguments include
585 * function pointers to audit_warn functions for soft and hard limits. Returns:
586 * ADE_NOERR on success,
587 * ADE_PARSE error parsing audit_control(5),
588 * ADE_AUDITON error getting/setting auditon(2) value,
589 * ADE_NOMEM error allocating memory,
590 * ADE_SOFTLIM if all the directories are over the soft limit,
591 * ADE_HARDLIM if all the directories are over the hard limit,
594 auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *))
596 char cur_dir[MAXNAMLEN];
597 struct dir_ent *dirent;
605 if (auditd_minval == -1 && (err = auditd_set_minfree()) != 0)
608 if (auditd_hostlen == -1)
612 * Init directory q. Force a re-read of the file the next time.
618 * Read the list of directories into an ordered linked list
619 * admin's preference, then those over soft limit and, finally,
620 * those over the hard limit.
622 * XXX We should use the reentrant interfaces once they are
625 while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
626 if (statfs(cur_dir, &sfs) < 0)
627 continue; /* XXX should warn */
628 soft = (sfs.f_bfree < (sfs.f_blocks * auditd_minval / 100 )) ?
630 hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0;
633 (*warn_soft)(cur_dir);
638 (*warn_hard)(cur_dir);
641 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
644 dirent->softlim = soft;
645 dirent->hardlim = hard;
646 dirent->dirname = (char *) malloc(MAXNAMLEN);
647 if (dirent->dirname == NULL) {
651 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
652 insert_orderly(dirent);
657 return (ADE_HARDLIM);
659 return (ADE_SOFTLIM);
664 auditd_close_dirs(void)
673 * Process the audit event file, obtaining a class mapping for each event, and
674 * set that mapping into the kernel. Return:
675 * n number of event mappings that were successfully processed,
676 * ADE_NOMEM if there was an error allocating memory.
679 auditd_set_evcmap(void)
681 au_event_ent_t ev, *evp;
682 au_evclass_map_t evc_map;
686 * XXX There's a risk here that the BSM library will return NULL
687 * for an event when it can't properly map it to a class. In that
688 * case, we will not process any events beyond the one that failed,
689 * but should. We need a way to get a count of the events.
691 ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
692 ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
693 if (ev.ae_name == NULL || ev.ae_desc == NULL) {
694 if (ev.ae_name != NULL)
700 * XXXRW: Currently we have no way to remove mappings from the kernel
701 * when they are removed from the file-based mappings.
705 while ((evp = getauevent_r(evp)) != NULL) {
706 evc_map.ec_number = evp->ae_number;
707 evc_map.ec_class = evp->ae_class;
708 if (audit_set_class(&evc_map, sizeof(evc_map)) == 0)
719 * Get the non-attributable event string and set the kernel mask. Return:
720 * ADE_NOERR on success,
721 * ADE_PARSE error parsing audit_control(5),
722 * ADE_AUDITON error setting the mask using auditon(2).
725 auditd_set_namask(void)
728 char naeventstr[NA_EVENT_STR_SIZE];
730 if (getacna(naeventstr, NA_EVENT_STR_SIZE) != 0 ||
731 getauditflagsbin(naeventstr, &aumask) != 0)
734 if (audit_set_kmask(&aumask, sizeof(aumask)) != 0)
735 return (ADE_AUDITON);
741 * Set the audit control policy if a policy is configured in audit_control(5),
742 * implement the policy. However, if one isn't defined or if there is an error
743 * parsing the control file, set AUDIT_CNT to avoid leaving the system in a
744 * fragile state. Return:
745 * ADE_NOERR on success,
746 * ADE_PARSE error parsing audit_control(5),
747 * ADE_AUDITON error setting policy using auditon(2).
750 auditd_set_policy(void)
753 char polstr[POL_STR_SIZE];
755 if (getacpol(polstr, POL_STR_SIZE) != 0 ||
756 au_strtopol(polstr, &policy) != 0) {
758 if (audit_set_policy(&policy) != 0)
759 return (ADE_AUDITON);
763 if (audit_set_policy(&policy) != 0)
764 return (ADE_AUDITON);
770 * Set trail rotation size. Return:
771 * ADE_NOERR on success,
772 * ADE_PARSE error parsing audit_control(5),
773 * ADE_AUDITON error setting file size using auditon(2).
776 auditd_set_fsize(void)
782 * Set trail rotation size.
784 if (getacfilesz(&filesz) != 0)
787 bzero(&au_fstat, sizeof(au_fstat));
788 au_fstat.af_filesz = filesz;
789 if (audit_set_fsize(&au_fstat, sizeof(au_fstat)) != 0)
790 return (ADE_AUDITON);
796 inject_dist(const char *fromname, char *toname, size_t tonamesize)
800 ptr = strrchr(fromname, '/');
802 assert(ptr - fromname < (ssize_t)tonamesize);
803 strlcpy(toname, fromname, ptr - fromname + 1);
804 strlcat(toname, "/dist/", tonamesize);
805 strlcat(toname, ptr + 1, tonamesize);
809 auditdist_link(const char *filename)
811 char fname[MAXPATHLEN];
814 inject_dist(filename, fname, sizeof(fname));
816 (void) link(filename, fname);
823 auditd_rename(const char *fromname, const char *toname)
825 char fname[MAXPATHLEN], tname[MAXPATHLEN];
828 inject_dist(fromname, fname, sizeof(fname));
829 inject_dist(toname, tname, sizeof(tname));
831 (void) rename(fname, tname);
834 return (rename(fromname, toname));
838 * Create the new audit file with appropriate permissions and ownership.
839 * Call auditctl(2) for this file.
840 * Try to clean up if something goes wrong.
841 * *errorp is modified only on auditctl(2) failure.
844 open_trail(char *fname, gid_t gid, int *errorp)
848 /* XXXPJD: What should we do if the file already exists? */
849 fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR);
852 if (fchown(fd, -1, gid) < 0 || fchmod(fd, S_IRUSR | S_IRGRP) < 0) {
854 (void) unlink(fname);
858 if (auditctl(fname) < 0) {
860 (void) unlink(fname);
863 (void) auditdist_link(fname);
868 * Create the new audit trail file, swap with existing audit file. Arguments
869 * include timestamp for the filename, a pointer to a string for returning the
870 * new file name, GID for trail file, and audit_warn function pointer for
871 * 'getacdir()' errors. Returns:
872 * ADE_NOERR on success,
873 * ADE_STRERR if the file name string could not be created,
874 * ADE_SWAPERR if the audit trail file could not be swapped,
875 * ADE_ACTL if the auditctl(2) call failed but file swap still
877 * ADE_ACTLERR if the auditctl(2) call failed and file swap failed.
878 * ADE_SYMLINK if symlink(2) failed updating the current link.
881 auditd_swap_trail(char *TS, char **newfile, gid_t gid,
882 int (*warn_getacdir)(char *))
884 char timestr[FILENAME_LEN + 1];
886 struct dir_ent *dirent;
889 if (strlen(TS) != TIMESTAMP_LEN ||
890 snprintf(timestr, sizeof(timestr), "%s.%s", TS,
891 NOT_TERMINATED) < 0) {
896 /* Try until we succeed. */
897 TAILQ_FOREACH(dirent, &dir_q, dirs) {
900 if ((fn = affixdir(timestr, dirent)) == NULL)
904 * Create the file and pass to the kernel if all went well.
906 if (open_trail(fn, gid, &saverrno) == 0) {
911 * auditctl() failed but still
912 * successful. Return errno and "soft"
921 * auditctl failed setting log file. Try again.
924 * Tell the administrator about lack of permissions for dir.
926 if (warn_getacdir != NULL)
927 (*warn_getacdir)(dirent->dirname);
931 return (ADE_ACTLERR);
933 return (ADE_SWAPERR);
937 * Mask calling process from being audited. Returns:
938 * ADE_NOERR on success,
939 * ADE_SETAUDIT if setaudit(2) fails.
943 auditd_prevent_audit(void)
945 auditinfo_addr_t aia;
948 * To prevent event feedback cycles and avoid audit becoming stalled if
949 * auditing is suspended we mask this processes events from being
950 * audited. We allow the uid, tid, and mask fields to be implicitly
951 * set to zero, but do set the audit session ID to the PID.
953 * XXXRW: Is there more to it than this?
955 bzero(&aia, sizeof(aia));
956 aia.ai_asid = AU_ASSIGN_ASID;
957 aia.ai_termid.at_type = AU_IPv4;
958 if (setaudit_addr(&aia, sizeof(aia)) != 0)
959 return (ADE_SETAUDIT);
964 auditd_prevent_audit(void)
969 * To prevent event feedback cycles and avoid audit becoming stalled if
970 * auditing is suspended we mask this processes events from being
971 * audited. We allow the uid, tid, and mask fields to be implicitly
972 * set to zero, but do set the audit session ID to the PID.
974 * XXXRW: Is there more to it than this?
976 bzero(&ai, sizeof(ai));
977 ai.ai_asid = getpid();
978 if (setaudit(&ai) != 0)
979 return (ADE_SETAUDIT);
982 #endif /* !__APPLE__ */
985 * Generate and submit audit record for audit startup or shutdown. The event
986 * argument can be AUE_audit_recovery, AUE_audit_startup or
987 * AUE_audit_shutdown. The path argument will add a path token, if not NULL.
989 * AUE_NOERR on success,
990 * ADE_NOMEM if memory allocation fails,
991 * ADE_AU_OPEN if au_open(3) fails,
992 * ADE_AU_CLOSE if au_close(3) fails.
995 auditd_gen_record(int event, char *path)
1000 char *autext = NULL;
1002 struct auditinfo_addr aia;
1004 if (event == AUE_audit_startup)
1005 asprintf(&autext, "%s::Audit startup", getprogname());
1006 else if (event == AUE_audit_shutdown)
1007 asprintf(&autext, "%s::Audit shutdown", getprogname());
1008 else if (event == AUE_audit_recovery)
1009 asprintf(&autext, "%s::Audit recovery", getprogname());
1015 if ((aufd = au_open()) == -1) {
1017 return (ADE_AU_OPEN);
1019 bzero(&aia, sizeof(aia));
1020 uid = getuid(); pid = getpid();
1021 if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, getgid(),
1022 pid, pid, &aia.ai_termid)) != NULL)
1023 au_write(aufd, tok);
1024 if ((tok = au_to_text(autext)) != NULL)
1025 au_write(aufd, tok);
1027 if (path != NULL && (tok = au_to_path(path)) != NULL)
1028 au_write(aufd, tok);
1029 if ((tok = au_to_return32(0, 0)) != NULL)
1030 au_write(aufd, tok);
1031 if (au_close(aufd, 1, event) == -1)
1032 return (ADE_AU_CLOSE);
1038 * Check for a 'current' symlink and do crash recovery, if needed. Create a new
1039 * 'current' symlink. The argument 'curfile' is the file the 'current' symlink
1040 * should point to. Returns:
1041 * ADE_NOERR on success,
1042 * ADE_AU_OPEN if au_open(3) fails,
1043 * ADE_AU_CLOSE if au_close(3) fails.
1044 * ADE_RENAME if error renaming audit trail file,
1045 * ADE_READLINK if error reading the 'current' link,
1046 * ADE_SYMLINK if error creating 'current' link.
1049 auditd_new_curlink(char *curfile)
1055 char recoveredname[MAXPATHLEN];
1056 char newname[MAXPATHLEN];
1059 * Check to see if audit was shutdown properly. If not, clean up,
1060 * recover previous audit trail file, and generate audit record.
1062 len = readlink(AUDIT_CURRENT_LINK, recoveredname,
1063 sizeof(recoveredname) - 1);
1065 /* 'current' exist but is it pointing at a valid file? */
1066 recoveredname[len++] = '\0';
1067 if (stat(recoveredname, &sb) == 0) {
1068 /* Yes, rename it to a crash recovery file. */
1069 strlcpy(newname, recoveredname, sizeof(newname));
1071 if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
1072 memcpy(ptr, CRASH_RECOVERY, POSTFIX_LEN);
1073 if (auditd_rename(recoveredname, newname) != 0)
1074 return (ADE_RENAME);
1076 return (ADE_STRERR);
1081 /* 'current' symlink is (now) invalid so remove it. */
1082 (void) unlink(AUDIT_CURRENT_LINK);
1084 /* Note the crash recovery in current audit trail */
1085 err = auditd_gen_record(AUE_audit_recovery, path);
1090 if (len < 0 && errno != ENOENT)
1091 return (ADE_READLINK);
1093 if (symlink(curfile, AUDIT_CURRENT_LINK) != 0)
1094 return (ADE_SYMLINK);
1100 * Do just what we need to quickly start auditing. Assume no system logging or
1106 audit_quick_start(void)
1109 char *newfile = NULL;
1111 char TS[TIMESTAMP_LEN + 1];
1115 * Mask auditing of this process.
1117 if (auditd_prevent_audit() != 0)
1121 * Read audit_control and get log directories.
1123 err = auditd_read_dirs(NULL, NULL);
1124 if (err != ADE_NOERR && err != ADE_SOFTLIM)
1128 * Setup trail file distribution.
1130 (void) auditd_set_dist();
1133 * Create a new audit trail log.
1135 if (getTSstr(tt, TS, sizeof(TS)) != 0)
1137 err = auditd_swap_trail(TS, &newfile, getgid(), NULL);
1138 if (err != ADE_NOERR && err != ADE_ACTL) {
1144 * Add the current symlink and recover from crash, if needed.
1146 if (auditd_new_curlink(newfile) != 0) {
1152 * At this point auditing has started so generate audit start-up record.
1154 if (auditd_gen_record(AUE_audit_startup, NULL) != 0) {
1160 * Configure the audit controls.
1162 (void) auditd_set_evcmap();
1163 (void) auditd_set_namask();
1164 (void) auditd_set_policy();
1165 (void) auditd_set_fsize();
1166 (void) auditd_set_minfree();
1167 (void) auditd_set_host();
1170 if (newfile != NULL)
1177 * Shut down auditing quickly. Assumes that is only called on system shutdown.
1183 audit_quick_stop(void)
1189 char oldname[MAXPATHLEN];
1190 char newname[MAXPATHLEN];
1191 char TS[TIMESTAMP_LEN + 1];
1194 * Auditing already disabled?
1196 if (audit_get_cond(&cond) != 0)
1198 if (cond == AUC_NOAUDIT)
1202 * Generate audit shutdown record.
1204 (void) auditd_gen_record(AUE_audit_shutdown, NULL);
1207 * Shutdown auditing in the kernel.
1209 cond = AUC_DISABLED;
1210 if (audit_set_cond(&cond) != 0)
1212 #ifdef __BSM_INTERNAL_NOTIFY_KEY
1213 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
1217 * Rename last audit trail and remove 'current' link.
1219 len = readlink(AUDIT_CURRENT_LINK, oldname, sizeof(oldname) - 1);
1222 oldname[len++] = '\0';
1224 if (getTSstr(tt, TS, sizeof(TS)) != 0)
1227 strlcpy(newname, oldname, sizeof(newname));
1229 if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
1230 memcpy(ptr, TS, POSTFIX_LEN);
1231 if (auditd_rename(oldname, newname) != 0)
1236 (void) unlink(AUDIT_CURRENT_LINK);