]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/openbsm/libauditd/auditd_lib.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / openbsm / libauditd / auditd_lib.c
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  * $P4: //depot/projects/trustedbsd/openbsm/libauditd/auditd_lib.c#18 $
30  */
31
32 #include <sys/param.h>
33
34 #include <config/config.h>
35
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>
44
45 #include <sys/stat.h>
46 #include <sys/time.h>
47
48 #include <netinet/in.h>
49
50 #include <bsm/audit.h>
51 #include <bsm/audit_uevents.h>
52 #include <bsm/auditd_lib.h>
53 #include <bsm/libbsm.h>
54
55 #include <assert.h>
56 #include <dirent.h>
57 #include <err.h>
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <stdio.h>
61 #include <string.h>
62 #include <stdlib.h>
63 #include <time.h>
64 #include <unistd.h>
65 #include <netdb.h>
66
67 #ifdef __APPLE__
68 #include <notify.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__ */
73
74 /*
75  * XXX This is temporary until this is moved to <bsm/audit.h> and shared with
76  * the kernel.
77  */
78 #ifndef AUDIT_HARD_LIMIT_FREE_BLOCKS
79 #define AUDIT_HARD_LIMIT_FREE_BLOCKS    4
80 #endif
81
82 /*
83  * Number of seconds to January 1, 2000
84  */
85 #define JAN_01_2000     946598400
86
87 struct dir_ent {
88         char                    *dirname;
89         uint8_t                  softlim;
90         uint8_t                  hardlim;
91         TAILQ_ENTRY(dir_ent)     dirs;
92 };
93
94 static TAILQ_HEAD(, dir_ent)    dir_q;
95
96 struct audit_trail {
97         time_t                   at_time;
98         char                    *at_path;
99         off_t                    at_size;
100
101         TAILQ_ENTRY(audit_trail) at_trls;
102 };
103
104 static int auditd_minval = -1;
105 static int auditd_dist = 0;
106
107 static char auditd_host[MAXHOSTNAMELEN];
108 static int auditd_hostlen = -1;
109
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) */
131 };
132
133 #define MAXERRCODE      (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0]))
134
135 #define NA_EVENT_STR_SIZE       128
136 #define POL_STR_SIZE            128
137
138
139 /*
140  * Look up and return the error string for the given audit error code.
141  */
142 const char *
143 auditd_strerror(int errcode)
144 {
145         int idx = -errcode;
146
147         if (idx < 0 || idx > (int)MAXERRCODE)
148                 return ("Invalid auditd error code");
149
150         return (auditd_errmsg[idx]);
151 }
152
153
154 /*
155  * Free our local list of directory names and init list.
156  */
157 static void
158 free_dir_q(void)
159 {
160         struct dir_ent *d1, *d2;
161
162         d1 = TAILQ_FIRST(&dir_q);
163         while (d1 != NULL) {
164                 d2 = TAILQ_NEXT(d1, dirs);
165                 free(d1->dirname);
166                 free(d1);
167                 d1 = d2;
168         }
169         TAILQ_INIT(&dir_q);
170 }
171
172 /*
173  * Concat the directory name to the given file name.
174  * XXX We should affix the hostname also
175  */
176 static char *
177 affixdir(char *name, struct dir_ent *dirent)
178 {
179         char *fn = NULL;
180
181         /*
182          * Sanity check on file name.
183          */
184         if (strlen(name) != FILENAME_LEN) {
185                 errno = EINVAL;
186                 return (NULL);
187         }
188
189         /*
190          * If the host is set then also add the hostname to the filename.
191          */
192         if (auditd_hostlen != -1)
193                 asprintf(&fn, "%s/%s.%s", dirent->dirname, name, auditd_host);
194         else
195                 asprintf(&fn, "%s/%s", dirent->dirname, name);
196         return (fn);
197 }
198
199 /*
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
202  * toward the tail.
203  */
204 static void
205 insert_orderly(struct dir_ent *denew)
206 {
207         struct dir_ent *dep;
208
209         TAILQ_FOREACH(dep, &dir_q, dirs) {
210                 if (dep->softlim == 1 && denew->softlim == 0) {
211                         TAILQ_INSERT_BEFORE(dep, denew, dirs);
212                         return;
213                 }
214                 if (dep->hardlim == 1 && denew->hardlim == 0) {
215                         TAILQ_INSERT_BEFORE(dep, denew, dirs);
216                         return;
217                 }
218         }
219         TAILQ_INSERT_TAIL(&dir_q, denew, dirs);
220 }
221
222 /*
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),
227  */
228 int
229 auditd_set_dist(void)
230 {
231         int ret;
232
233         ret = getacdist();
234         if (ret < 0)
235                 return (ADE_PARSE);
236
237         auditd_dist = ret;
238
239         return (ADE_NOERR);
240 }
241
242 /*
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.
250  */
251 int
252 auditd_set_host(void)
253 {
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;
259
260         if (getachost(auditd_host, sizeof(auditd_host)) != 0) {
261                 ret = ADE_PARSE;
262
263                 /*
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
268                  * termid structure.
269                  */
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)
274                         ret = ADE_AUDITON;
275                 return (ret);
276         }
277         auditd_hostlen = strlen(auditd_host);
278         error = getaddrinfo(auditd_host, NULL, NULL, &res);
279         if (error)
280                 return (ADE_GETADDR);
281         switch (res->ai_family) {
282         case PF_INET6:
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;
287                 break;
288
289         case PF_INET:
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;
294                 break;
295
296         default:
297                 /* Un-supported address family in host parameter. */
298                 errno = EAFNOSUPPORT;
299                 return (ADE_ADDRFAM);
300         }
301
302         if (audit_set_kaudit(&aia, sizeof(aia)) < 0)
303                 ret = ADE_AUDITON;
304
305         return (ret);
306 }
307
308 /*
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.
314  */
315 int
316 auditd_set_minfree(void)
317 {
318         au_qctrl_t qctrl;
319
320         if (getacmin(&auditd_minval) != 0)
321                 return (ADE_PARSE);
322
323         if (audit_get_qctrl(&qctrl, sizeof(qctrl)) != 0)
324                 return (ADE_AUDITON);
325
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);
330         }
331
332         return (0);
333 }
334
335 /*
336  * Convert a trailname into a timestamp (seconds).  Return 0 if the conversion
337  * was successful.
338  */
339 static int
340 trailname_to_tstamp(char *fn, time_t *tstamp)
341 {
342         struct tm tm;
343         char ts[TIMESTAMP_LEN + 1];
344         char *p;
345
346         *tstamp = 0;
347
348         /*
349          * Get the ending time stamp.
350          */
351         if ((p = strchr(fn, '.')) == NULL)
352                 return (1);
353         strlcpy(ts, ++p, sizeof(ts));
354         if (strlen(ts) != POSTFIX_LEN)
355                 return (1);
356
357         bzero(&tm, sizeof(tm));
358
359         /* seconds (0-60) */
360         p = ts + POSTFIX_LEN - 2;
361         tm.tm_sec = atol(p);
362         if (tm.tm_sec < 0 || tm.tm_sec > 60)
363                 return (1);
364
365         /* minutes (0-59) */
366         *p = '\0'; p -= 2;
367         tm.tm_min = atol(p);
368         if (tm.tm_min < 0 || tm.tm_min > 59)
369                 return (1);
370
371         /* hours (0 - 23) */
372         *p = '\0'; p -= 2;
373         tm.tm_hour = atol(p);
374         if (tm.tm_hour < 0 || tm.tm_hour > 23)
375                 return (1);
376
377         /* day of month (1-31) */
378         *p = '\0'; p -= 2;
379         tm.tm_mday = atol(p);
380         if (tm.tm_mday < 1 || tm.tm_mday > 31)
381                 return (1);
382
383         /* month (0 - 11) */
384         *p = '\0'; p -= 2;
385         tm.tm_mon = atol(p) - 1;
386         if (tm.tm_mon < 0 || tm.tm_mon > 11)
387                 return (1);
388
389         /* year (year - 1900) */
390         *p = '\0'; p -= 4;
391         tm.tm_year = atol(p) - 1900;
392         if (tm.tm_year < 0)
393                 return (1);
394
395         *tstamp = timegm(&tm);
396
397         return (0);
398 }
399
400 /*
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.
406  */
407 int
408 auditd_expire_trails(int (*warn_expired)(char *))
409 {
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;
415         char *afnp, *pn;
416         TAILQ_HEAD(au_trls_head, audit_trail) head =
417             TAILQ_HEAD_INITIALIZER(head);
418         struct stat stbuf;
419         char activefn[MAXPATHLEN];
420
421         /*
422          * Read the expiration conditions.  If no conditions then return no
423          * error.
424          */
425         if (getacexpire(&andflg, &expire_age, &expire_size) < 0)
426                 return (ADE_PARSE);
427         if (!expire_age && !expire_size)
428                 return (ADE_NOERR);
429
430         /*
431          * Read the 'current' trail file name.  Trim off directory path.
432          */
433         activefn[0] = '\0';
434         readlink(AUDIT_CURRENT_LINK, activefn, MAXPATHLEN - 1);
435         if ((afnp = strrchr(activefn, '/')) != NULL)
436                 afnp++;
437
438
439         /*
440          * Build tail queue of the trail files.
441          */
442         TAILQ_FOREACH(traildir, &dir_q, dirs) {
443                 DIR *dirp;
444                 struct dirent *dp;
445
446                 dirp = opendir(traildir->dirname);
447                 while ((dp = readdir(dirp)) != NULL) {
448                         time_t tstamp = 0;
449                         struct audit_trail *new;
450
451                         /*
452                          * Quickly filter non-trail files.
453                          */
454                         if (dp->d_namlen < FILENAME_LEN ||
455                             dp->d_name[POSTFIX_LEN] != '.')
456                                 continue;
457
458                         if (asprintf(&pn, "%s/%s", traildir->dirname,
459                             dp->d_name) < 0) {
460                                 ret = ADE_NOMEM;
461                                 break;
462                         }
463
464                         if (stat(pn, &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) {
465                                 free(pn);
466                                 continue;
467                         }
468
469                         total_size += stbuf.st_size;
470
471                         /*
472                          * If this is the 'current' audit trail then
473                          * don't add it to the tail queue.
474                          */
475                         if (NULL != afnp && strcmp(dp->d_name, afnp) == 0) {
476                                 free(pn);
477                                 continue;
478                         }
479
480                         /*
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.
484                          */
485                         if (trailname_to_tstamp(dp->d_name, &tstamp) != 0 ||
486                             tstamp < JAN_01_2000)
487                                 tstamp = stbuf.st_mtime;
488
489                         /*
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.
496                          */
497                         if (current_time >= JAN_01_2000 &&
498                             tstamp < JAN_01_2000) {
499                                 struct timeval tv[2];
500
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);
506                                 utimes(pn, tv);
507                         }
508
509                         /*
510                          * Allocate and populate the new entry.
511                          */
512                         new = malloc(sizeof(*new));
513                         if (NULL == new) {
514                                 free(pn);
515                                 ret = ADE_NOMEM;
516                                 break;
517                         }
518                         new->at_time = tstamp;
519                         new->at_size = stbuf.st_size;
520                         new->at_path = pn;
521
522                         /*
523                          * Check to see if we have a new head.  Otherwise,
524                          * walk the tailq from the tail first and do a simple
525                          * insertion sort.
526                          */
527                         if (TAILQ_EMPTY(&head) ||
528                             new->at_time <= TAILQ_FIRST(&head)->at_time) {
529                                 TAILQ_INSERT_HEAD(&head, new, at_trls);
530                                 continue;
531                         }
532
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,
536                                             at_trls);
537                                         break;
538                                 }
539
540                 }
541                 closedir(dirp);
542         }
543
544         oldest_time = current_time - expire_age;
545
546         /*
547          * Expire trail files, oldest (mtime) first, if the given
548          * conditions are met.
549          */
550         at = TAILQ_FIRST(&head);
551         while (NULL != at) {
552                 struct audit_trail *at_next = TAILQ_NEXT(at, at_trls);
553
554                 if (andflg) {
555                         if ((expire_size && total_size > expire_size) &&
556                             (expire_age && at->at_time < oldest_time)) {
557                                 if (warn_expired)
558                                         (*warn_expired)(at->at_path);
559                                 if (unlink(at->at_path) < 0)
560                                         ret = ADE_EXPIRE;
561                                 total_size -= at->at_size;
562                         }
563                 } else {
564                         if ((expire_size && total_size > expire_size) ||
565                             (expire_age && at->at_time < oldest_time)) {
566                                 if (warn_expired)
567                                         (*warn_expired)(at->at_path);
568                                 if (unlink(at->at_path) < 0)
569                                         ret = ADE_EXPIRE;
570                                 total_size -= at->at_size;
571                         }
572                 }
573
574                 free(at->at_path);
575                 free(at);
576                 at = at_next;
577         }
578
579         return (ret);
580 }
581
582 /*
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,
592  */
593 int
594 auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *))
595 {
596         char cur_dir[MAXNAMLEN];
597         struct dir_ent *dirent;
598         struct statfs sfs;
599         int err;
600         char soft, hard;
601         int tcnt = 0;
602         int scnt = 0;
603         int hcnt = 0;
604
605         if (auditd_minval == -1 && (err = auditd_set_minfree()) != 0)
606                 return (err);
607
608         if (auditd_hostlen == -1)
609                 auditd_set_host();
610
611         /*
612          * Init directory q.  Force a re-read of the file the next time.
613          */
614         free_dir_q();
615         endac();
616
617         /*
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.
621          *
622          * XXX We should use the reentrant interfaces once they are
623          * available.
624          */
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 )) ?
629                     1 : 0;
630                 hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0;
631                 if (soft) {
632                         if (warn_soft)
633                                 (*warn_soft)(cur_dir);
634                         scnt++;
635                 }
636                 if (hard) {
637                         if (warn_hard)
638                                 (*warn_hard)(cur_dir);
639                         hcnt++;
640                 }
641                 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
642                 if (dirent == NULL)
643                         return (ADE_NOMEM);
644                 dirent->softlim = soft;
645                 dirent->hardlim = hard;
646                 dirent->dirname = (char *) malloc(MAXNAMLEN);
647                 if (dirent->dirname == NULL) {
648                         free(dirent);
649                         return (ADE_NOMEM);
650                 }
651                 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
652                 insert_orderly(dirent);
653                 tcnt++;
654         }
655
656         if (hcnt == tcnt)
657                 return (ADE_HARDLIM);
658         if (scnt == tcnt)
659                 return (ADE_SOFTLIM);
660         return (0);
661 }
662
663 void
664 auditd_close_dirs(void)
665 {
666         free_dir_q();
667         auditd_minval = -1;
668         auditd_hostlen = -1;
669 }
670
671
672 /*
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.
677  */
678 int
679 auditd_set_evcmap(void)
680 {
681         au_event_ent_t ev, *evp;
682         au_evclass_map_t evc_map;
683         int ctr = 0;
684
685         /*
686          * XXX There's a risk here that the BSM library will return NULL
687          * for an event when it can't properly map it to a class. In that
688          * case, we will not process any events beyond the one that failed,
689          * but should. We need a way to get a count of the events.
690          */
691         ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
692         ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
693         if (ev.ae_name == NULL || ev.ae_desc == NULL) {
694                 if (ev.ae_name != NULL)
695                         free(ev.ae_name);
696                 return (ADE_NOMEM);
697         }
698
699         /*
700          * XXXRW: Currently we have no way to remove mappings from the kernel
701          * when they are removed from the file-based mappings.
702          */
703         evp = &ev;
704         setauevent();
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)
709                         ctr++;
710         }
711         endauevent();
712         free(ev.ae_name);
713         free(ev.ae_desc);
714
715         return (ctr);
716 }
717
718 /*
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).
723  */
724 int
725 auditd_set_namask(void)
726 {
727         au_mask_t aumask;
728         char naeventstr[NA_EVENT_STR_SIZE];
729
730         if (getacna(naeventstr, NA_EVENT_STR_SIZE) != 0 ||
731             getauditflagsbin(naeventstr, &aumask) != 0)
732                 return (ADE_PARSE);
733
734         if (audit_set_kmask(&aumask, sizeof(aumask)) != 0)
735                 return (ADE_AUDITON);
736
737         return (ADE_NOERR);
738 }
739
740 /*
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).
748  */
749 int
750 auditd_set_policy(void)
751 {
752         int policy;
753         char polstr[POL_STR_SIZE];
754
755         if (getacpol(polstr, POL_STR_SIZE) != 0 ||
756             au_strtopol(polstr, &policy) != 0) {
757                 policy = AUDIT_CNT;
758                 if (audit_set_policy(&policy) != 0)
759                         return (ADE_AUDITON);
760                 return (ADE_PARSE);
761         }
762
763         if (audit_set_policy(&policy) != 0)
764                 return (ADE_AUDITON);
765
766         return (ADE_NOERR);
767 }
768
769 /*
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).
774  */
775 int
776 auditd_set_fsize(void)
777 {
778         size_t filesz;
779         au_fstat_t au_fstat;
780
781         /*
782          * Set trail rotation size.
783          */
784         if (getacfilesz(&filesz) != 0)
785                 return (ADE_PARSE);
786
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);
791
792         return (ADE_NOERR);
793 }
794
795 static void
796 inject_dist(const char *fromname, char *toname, size_t tonamesize)
797 {
798         char *ptr;
799
800         ptr = strrchr(fromname, '/');
801         assert(ptr != NULL);
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);
806 }
807
808 static int
809 auditdist_link(const char *filename)
810 {
811         char fname[MAXPATHLEN];
812
813         if (auditd_dist) {
814                 inject_dist(filename, fname, sizeof(fname));
815                 /* Ignore errors. */
816                 (void) link(filename, fname);
817         }
818
819         return (0);
820 }
821
822 int
823 auditd_rename(const char *fromname, const char *toname)
824 {
825         char fname[MAXPATHLEN], tname[MAXPATHLEN];
826
827         if (auditd_dist) {
828                 inject_dist(fromname, fname, sizeof(fname));
829                 inject_dist(toname, tname, sizeof(tname));
830                 /* Ignore errors. */
831                 (void) rename(fname, tname);
832         }
833
834         return (rename(fromname, toname));
835 }
836
837 /*
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.
842  */
843 static int
844 open_trail(char *fname, gid_t gid, int *errorp)
845 {
846         int fd;
847
848         /* XXXPJD: What should we do if the file already exists? */
849         fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR);
850         if (fd < 0)
851                 return (-1);
852         if (fchown(fd, -1, gid) < 0 || fchmod(fd, S_IRUSR | S_IRGRP) < 0) {
853                 (void) close(fd);
854                 (void) unlink(fname);
855                 return (-1);
856         }
857         (void) close(fd);
858         if (auditctl(fname) < 0) {
859                 *errorp = errno;
860                 (void) unlink(fname);
861                 return (-1);
862         }
863         (void) auditdist_link(fname);
864         return (0);
865 }
866
867 /*
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
876  *                      successful.
877  *      ADE_ACTLERR     if the auditctl(2) call failed and file swap failed.
878  *      ADE_SYMLINK     if symlink(2) failed updating the current link.
879  */
880 int
881 auditd_swap_trail(char *TS, char **newfile, gid_t gid,
882     int (*warn_getacdir)(char *))
883 {
884         char timestr[FILENAME_LEN + 1];
885         char *fn;
886         struct dir_ent *dirent;
887         int saverrno = 0;
888
889         if (strlen(TS) != TIMESTAMP_LEN ||
890             snprintf(timestr, sizeof(timestr), "%s.%s", TS,
891             NOT_TERMINATED) < 0) {
892                 errno = EINVAL;
893                 return (ADE_STRERR);
894         }
895
896         /* Try until we succeed. */
897         TAILQ_FOREACH(dirent, &dir_q, dirs) {
898                 if (dirent->hardlim)
899                         continue;
900                 if ((fn = affixdir(timestr, dirent)) == NULL)
901                         return (ADE_STRERR);
902
903                 /*
904                  * Create the file and pass to the kernel if all went well.
905                  */
906                 if (open_trail(fn, gid, &saverrno) == 0) {
907                         /* Success. */
908                         *newfile = fn;
909                         if (saverrno) {
910                                 /*
911                                  * auditctl() failed but still
912                                  * successful. Return errno and "soft"
913                                  * error.
914                                  */
915                                 errno = saverrno;
916                                 return (ADE_ACTL);
917                         }
918                         return (ADE_NOERR);
919                 }
920                 /*
921                  * auditctl failed setting log file. Try again.
922                  */
923                 /*
924                  * Tell the administrator about lack of permissions for dir.
925                  */
926                 if (warn_getacdir != NULL)
927                         (*warn_getacdir)(dirent->dirname);
928         }
929         if (saverrno) {
930                 errno = saverrno;
931                 return (ADE_ACTLERR);
932         } else
933                 return (ADE_SWAPERR);
934 }
935
936 /*
937  * Mask calling process from being audited. Returns:
938  *      ADE_NOERR       on success,
939  *      ADE_SETAUDIT    if setaudit(2) fails.
940  */
941 #ifdef __APPLE__
942 int
943 auditd_prevent_audit(void)
944 {
945         auditinfo_addr_t aia;
946
947         /*
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.
952          *
953          * XXXRW: Is there more to it than this?
954          */
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);
960         return (ADE_NOERR);
961 }
962 #else
963 int
964 auditd_prevent_audit(void)
965 {
966         auditinfo_t ai;
967
968         /*
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.
973          *
974          * XXXRW: Is there more to it than this?
975          */
976         bzero(&ai, sizeof(ai));
977         ai.ai_asid = getpid();
978         if (setaudit(&ai) != 0)
979                 return (ADE_SETAUDIT);
980         return (ADE_NOERR);
981 }
982 #endif /* !__APPLE__ */
983
984 /*
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.
988  * Returns:
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.
993  */
994 int
995 auditd_gen_record(int event, char *path)
996 {
997         int aufd;
998         uid_t uid;
999         pid_t pid;
1000         char *autext = NULL;
1001         token_t *tok;
1002         struct auditinfo_addr aia;
1003
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());
1010         else
1011                 return (ADE_INVAL);
1012         if (autext == NULL)
1013                 return (ADE_NOMEM);
1014
1015         if ((aufd = au_open()) == -1) {
1016                 free(autext);
1017                 return (ADE_AU_OPEN);
1018         }
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);
1026         free(autext);
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);
1033
1034         return (ADE_NOERR);
1035 }
1036
1037 /*
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.
1047  */
1048 int
1049 auditd_new_curlink(char *curfile)
1050 {
1051         int len, err;
1052         char *ptr;
1053         char *path = NULL;
1054         struct stat sb;
1055         char recoveredname[MAXPATHLEN];
1056         char newname[MAXPATHLEN];
1057
1058         /*
1059          * Check to see if audit was shutdown properly.  If not, clean up,
1060          * recover previous audit trail file, and generate audit record.
1061          */
1062         len = readlink(AUDIT_CURRENT_LINK, recoveredname,
1063             sizeof(recoveredname) - 1);
1064         if (len > 0) {
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));
1070
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);
1075                         } else
1076                                 return (ADE_STRERR);
1077
1078                         path = newname;
1079                 }
1080
1081                 /* 'current' symlink is (now) invalid so remove it. */
1082                 (void) unlink(AUDIT_CURRENT_LINK);
1083
1084                 /* Note the crash recovery in current audit trail */
1085                 err = auditd_gen_record(AUE_audit_recovery, path);
1086                 if (err)
1087                         return (err);
1088         }
1089
1090         if (len < 0 && errno != ENOENT)
1091                 return (ADE_READLINK);
1092
1093         if (symlink(curfile, AUDIT_CURRENT_LINK) != 0)
1094                 return (ADE_SYMLINK);
1095
1096         return (0);
1097 }
1098
1099 /*
1100  * Do just what we need to quickly start auditing.  Assume no system logging or
1101  * notify.  Return:
1102  *   0   on success,
1103  *  -1   on failure.
1104  */
1105 int
1106 audit_quick_start(void)
1107 {
1108         int err;
1109         char *newfile = NULL;
1110         time_t tt;
1111         char TS[TIMESTAMP_LEN + 1];
1112         int ret = 0;
1113
1114         /*
1115          * Mask auditing of this process.
1116          */
1117         if (auditd_prevent_audit() != 0)
1118                 return (-1);
1119
1120         /*
1121          * Read audit_control and get log directories.
1122          */
1123         err = auditd_read_dirs(NULL, NULL);
1124         if (err != ADE_NOERR && err != ADE_SOFTLIM)
1125                 return (-1);
1126
1127         /*
1128          * Setup trail file distribution.
1129          */
1130         (void) auditd_set_dist();
1131
1132         /*
1133          *  Create a new audit trail log.
1134          */
1135         if (getTSstr(tt, TS, sizeof(TS)) != 0)
1136                 return (-1);
1137         err = auditd_swap_trail(TS, &newfile, getgid(), NULL);
1138         if (err != ADE_NOERR && err != ADE_ACTL) {
1139                 ret = -1;
1140                 goto out;
1141         }
1142
1143         /*
1144          * Add the current symlink and recover from crash, if needed.
1145          */
1146         if (auditd_new_curlink(newfile) != 0) {
1147                 ret = -1;
1148                 goto out;
1149         }
1150
1151         /*
1152          * At this point auditing has started so generate audit start-up record.
1153          */
1154         if (auditd_gen_record(AUE_audit_startup, NULL) != 0) {
1155                 ret = -1;
1156                 goto out;
1157         }
1158
1159         /*
1160          *  Configure the audit controls.
1161          */
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();
1168
1169 out:
1170         if (newfile != NULL)
1171                 free(newfile);
1172
1173         return (ret);
1174 }
1175
1176 /*
1177  * Shut down auditing quickly.  Assumes that is only called on system shutdown.
1178  * Returns:
1179  *       0      on success,
1180  *      -1      on failure.
1181  */
1182 int
1183 audit_quick_stop(void)
1184 {
1185         int len;
1186         int cond;
1187         char *ptr;
1188         time_t tt;
1189         char oldname[MAXPATHLEN];
1190         char newname[MAXPATHLEN];
1191         char TS[TIMESTAMP_LEN + 1];
1192
1193         /*
1194          * Auditing already disabled?
1195          */
1196         if (audit_get_cond(&cond) != 0)
1197                 return (-1);
1198         if (cond == AUC_NOAUDIT)
1199                 return (0);
1200
1201         /*
1202          *  Generate audit shutdown record.
1203          */
1204         (void) auditd_gen_record(AUE_audit_shutdown, NULL);
1205
1206         /*
1207          * Shutdown auditing in the kernel.
1208          */
1209         cond = AUC_DISABLED;
1210         if (audit_set_cond(&cond) != 0)
1211                 return (-1);
1212 #ifdef  __BSM_INTERNAL_NOTIFY_KEY
1213         notify_post(__BSM_INTERNAL_NOTIFY_KEY);
1214 #endif
1215
1216         /*
1217          * Rename last audit trail and remove 'current' link.
1218          */
1219         len = readlink(AUDIT_CURRENT_LINK, oldname, sizeof(oldname) - 1);
1220         if (len < 0)
1221                 return (-1);
1222         oldname[len++] = '\0';
1223
1224         if (getTSstr(tt, TS, sizeof(TS)) != 0)
1225                 return (-1);
1226
1227         strlcpy(newname, oldname, sizeof(newname));
1228
1229         if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) {
1230                 memcpy(ptr, TS, POSTFIX_LEN);
1231                 if (auditd_rename(oldname, newname) != 0)
1232                         return (-1);
1233         } else
1234                 return (-1);
1235
1236         (void) unlink(AUDIT_CURRENT_LINK);
1237
1238         return (0);
1239 }