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