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