]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/openbsm/bin/auditd/auditd.c
This commit was generated by cvs2svn to compensate for changes in r159285,
[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#16 $
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
63 static int       ret, minval;
64 static char     *lastfile = NULL;
65 static int       allhardcount = 0;
66 static int       triggerfd = 0;
67 static int       sigchlds, sigchlds_handled;
68 static int       sighups, sighups_handled;
69 static int       sigterms, sigterms_handled;
70 static long      global_flags;
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()
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, "Could not rename %s to %s",
164                                     oldname, lastfile);
165                         else
166                                 syslog(LOG_INFO, "renamed %s to %s",
167                                     oldname, lastfile);
168                 }
169                 free(lastfile);
170                 free(oldname);
171                 lastfile = NULL;
172         }
173         return (0);
174 }
175
176 /*
177  * Create the new audit file with appropriate permissions and ownership.  Try
178  * to clean up if something goes wrong.
179  */
180 static int
181 #ifdef AUDIT_REVIEW_GROUP
182 open_trail(const char *fname, uid_t uid, gid_t gid)
183 #else
184 open_trail(const char *fname)
185 #endif
186 {
187         int error, fd;
188
189         fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
190         if (fd < 0)
191                 return (-1);
192 #ifdef AUDIT_REVIEW_GROUP
193         if (fchown(fd, uid, gid) < 0) {
194                 error = errno;
195                 close(fd);
196                 (void)unlink(fname);
197                 errno = error;
198                 return (-1);
199         }
200 #endif
201         return (fd);
202 }
203
204 /*
205  * Create the new file name, swap with existing audit file.
206  */
207 static int
208 swap_audit_file(void)
209 {
210         char timestr[2 * POSTFIX_LEN];
211         char *fn;
212         char TS[POSTFIX_LEN];
213         struct dir_ent *dirent;
214 #ifdef AUDIT_REVIEW_GROUP
215         struct group *grp;
216         gid_t gid;
217         uid_t uid;
218 #endif
219         int error, fd;
220
221         if (getTSstr(TS, POSTFIX_LEN) != 0)
222                 return (-1);
223
224         strcpy(timestr, TS);
225         strcat(timestr, NOT_TERMINATED);
226
227 #ifdef AUDIT_REVIEW_GROUP
228         /*
229          * XXXRW: Currently, this code falls back to the daemon gid, which is
230          * likely the wheel group.  Is there a better way to deal with this?
231          */
232         grp = getgrnam(AUDIT_REVIEW_GROUP);
233         if (grp == NULL) {
234                 syslog(LOG_INFO,
235                     "Audit review group '%s' not available, using daemon gid",
236                     AUDIT_REVIEW_GROUP);
237                 gid = -1;
238         } else
239                 gid = grp->gr_gid;
240         uid = getuid();
241 #endif
242
243         /* Try until we succeed. */
244         while ((dirent = TAILQ_FIRST(&dir_q))) {
245                 if ((fn = affixdir(timestr, dirent)) == NULL) {
246                         syslog(LOG_INFO, "Failed to swap log at time %s",
247                                 timestr);
248                         return (-1);
249                 }
250
251                 /*
252                  * Create and open the file; then close and pass to the
253                  * kernel if all went well.
254                  */
255                 syslog(LOG_INFO, "New audit file is %s", fn);
256 #ifdef AUDIT_REVIEW_GROUP
257                 fd = open_trail(fn, uid, gid);
258 #else
259                 fd = open_trail(fn);
260 #endif
261                 if (fd < 0)
262                         warn("open(%s)", fn);
263                 if (fd >= 0) {
264                         error = auditctl(fn);
265                         if (error) {
266                                 syslog(LOG_ERR,
267                                     "auditctl failed setting log file! : %s",
268                                     strerror(errno));
269                                 close(fd);
270                         } else {
271                                 /* Success. */
272                                 close_lastfile(TS);
273                                 lastfile = fn;
274                                 close(fd);
275                                 return (0);
276                         }
277                 }
278
279                 /*
280                  * Tell the administrator about lack of permissions for dir.
281                  */
282                 audit_warn_getacdir(dirent->dirname);
283
284                 /* Try again with a different directory. */
285                 TAILQ_REMOVE(&dir_q, dirent, dirs);
286                 free(dirent->dirname);
287                 free(dirent);
288         }
289         syslog(LOG_ERR, "Log directories exhausted\n");
290         return (-1);
291 }
292
293 /*
294  * Read the audit_control file contents.
295  */
296 static int
297 read_control_file(void)
298 {
299         char cur_dir[MAXNAMLEN];
300         struct dir_ent *dirent;
301         au_qctrl_t qctrl;
302
303         /*
304          * Clear old values.  Force a re-read of the file the next time.
305          */
306         free_dir_q();
307         endac();
308
309         /*
310          * Read the list of directories into a local linked list.
311          *
312          * XXX We should use the reentrant interfaces once they are
313          * available.
314          */
315         while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
316                 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
317                 if (dirent == NULL)
318                         return (-1);
319                 dirent->softlim = 0;
320                 dirent->dirname = (char *) malloc(MAXNAMLEN);
321                 if (dirent->dirname == NULL) {
322                         free(dirent);
323                         return (-1);
324                 }
325                 strcpy(dirent->dirname, cur_dir);
326                 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
327         }
328
329         allhardcount = 0;
330         if (swap_audit_file() == -1) {
331                 syslog(LOG_ERR, "Could not swap audit file");
332                 /*
333                  * XXX Faulty directory listing? - user should be given
334                  * XXX an opportunity to change the audit_control file
335                  * XXX switch to a reduced mode of auditing?
336                  */
337                 return (-1);
338         }
339
340         /*
341          * XXX There are synchronization problems here
342          * XXX what should we do if a trigger for the earlier limit
343          * XXX is generated here?
344          */
345         if (0 == (ret = getacmin(&minval))) {
346                 syslog(LOG_DEBUG, "min free = %d\n", minval);
347                 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
348                         syslog(LOG_ERR,
349                             "could not get audit queue settings");
350                                 return (-1);
351                 }
352                 qctrl.aq_minfree = minval;
353                 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
354                         syslog(LOG_ERR,
355                             "could not set audit queue settings");
356                         return (-1);
357                 }
358         }
359
360         return (0);
361 }
362
363 /*
364  * Close all log files, control files, and tell the audit system.
365  */
366 static int
367 close_all(void)
368 {
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                 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
382                         syslog(LOG_ERR,
383                             "Could not close audit shutdown event.");
384         }
385
386         /* Flush contents. */
387         cond = AUC_DISABLED;
388         err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
389         if (err_ret != 0) {
390                 syslog(LOG_ERR, "Disabling audit failed! : %s",
391                     strerror(errno));
392                 err_ret = 1;
393         }
394         if (getTSstr(TS, POSTFIX_LEN) == 0)
395                 close_lastfile(TS);
396         if (lastfile != NULL)
397                 free(lastfile);
398
399         free_dir_q();
400         if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
401                 syslog(LOG_ERR, "Could not unregister");
402                 audit_warn_postsigterm();
403                 return (1);
404         }
405         endac();
406
407         if (close(triggerfd) != 0)
408                 syslog(LOG_ERR, "Error closing control file");
409         syslog(LOG_INFO, "Finished");
410         return (0);
411 }
412
413 /*
414  * When we get a signal, we are often not at a clean point.  So, little can
415  * be done in the signal handler itself.  Instead,  we send a message to the
416  * main servicing loop to do proper handling from a non-signal-handler
417  * context.
418  */
419 static void
420 relay_signal(int signal)
421 {
422
423         if (signal == SIGHUP)
424                 sighups++;
425         if (signal == SIGTERM)
426                 sigterms++;
427         if (signal == SIGCHLD)
428                 sigchlds++;
429 }
430
431 /*
432  * Registering the daemon.
433  */
434 static int
435 register_daemon(void)
436 {
437         FILE * pidfile;
438         int fd;
439         pid_t pid;
440
441         /* Set up the signal hander. */
442         if (signal(SIGTERM, relay_signal) == SIG_ERR) {
443                 syslog(LOG_ERR,
444                     "Could not set signal handler for SIGTERM");
445                 fail_exit();
446         }
447         if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
448                 syslog(LOG_ERR,
449                     "Could not set signal handler for SIGCHLD");
450                 fail_exit();
451         }
452         if (signal(SIGHUP, relay_signal) == SIG_ERR) {
453                 syslog(LOG_ERR,
454                     "Could not set signal handler for SIGHUP");
455                 fail_exit();
456         }
457
458         if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
459                 syslog(LOG_ERR, "Could not open PID file");
460                 audit_warn_tmpfile();
461                 return (-1);
462         }
463
464         /* Attempt to lock the pid file; if a lock is present, exit. */
465         fd = fileno(pidfile);
466         if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
467                 syslog(LOG_ERR,
468                     "PID file is locked (is another auditd running?).");
469                 audit_warn_ebusy();
470                 return (-1);
471         }
472
473         pid = getpid();
474         ftruncate(fd, 0);
475         if (fprintf(pidfile, "%u\n", pid) < 0) {
476                 /* Should not start the daemon. */
477                 fail_exit();
478         }
479
480         fflush(pidfile);
481         return (0);
482 }
483
484 /*
485  * Suppress duplicate messages within a 30 second interval.   This should be
486  * enough to time to rotate log files without thrashing from soft warnings
487  * generated before the log is actually rotated.
488  */
489 #define DUPLICATE_INTERVAL      30
490 static void
491 handle_audit_trigger(int trigger)
492 {
493         static int last_trigger;
494         static time_t last_time;
495         struct dir_ent *dirent;
496
497         /*
498          * Suppres duplicate messages from the kernel within the specified
499          * interval.
500          */
501         struct timeval ts;
502         struct timezone tzp;
503         time_t tt;
504
505         if (gettimeofday(&ts, &tzp) == 0) {
506                 tt = (time_t)ts.tv_sec;
507                 if ((trigger == last_trigger) &&
508                     (tt < (last_time + DUPLICATE_INTERVAL)))
509                         return;
510                 last_trigger = trigger;
511                 last_time = tt;
512         }
513
514         /*
515          * Message processing is done here.
516          */
517         dirent = TAILQ_FIRST(&dir_q);
518         switch(trigger) {
519
520         case AUDIT_TRIGGER_LOW_SPACE:
521                 syslog(LOG_INFO, "Got low space trigger");
522                 if (dirent && (dirent->softlim != 1)) {
523                         TAILQ_REMOVE(&dir_q, dirent, dirs);
524                                 /* Add this node to the end of the list. */
525                                 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
526                                 audit_warn_soft(dirent->dirname);
527                                 dirent->softlim = 1;
528
529                         if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
530                             swap_audit_file() == -1)
531                                 syslog(LOG_ERR, "Error swapping audit file");
532
533                         /*
534                          * Check if the next dir has already reached its soft
535                          * limit.
536                          */
537                         dirent = TAILQ_FIRST(&dir_q);
538                         if (dirent->softlim == 1)  {
539                                 /* All dirs have reached their soft limit. */
540                                 audit_warn_allsoft();
541                         }
542                 } else {
543                         /*
544                          * Continue auditing to the current file.  Also
545                          * generate  an allsoft warning.
546                          * XXX do we want to do this ?
547                          */
548                         audit_warn_allsoft();
549                 }
550                 break;
551
552         case AUDIT_TRIGGER_NO_SPACE:
553                 syslog(LOG_INFO, "Got no space trigger");
554
555                 /* Delete current dir, go on to next. */
556                 TAILQ_REMOVE(&dir_q, dirent, dirs);
557                 audit_warn_hard(dirent->dirname);
558                 free(dirent->dirname);
559                 free(dirent);
560
561                 if (swap_audit_file() == -1)
562                         syslog(LOG_ERR, "Error swapping audit file");
563
564                 /* We are out of log directories. */
565                 audit_warn_allhard(++allhardcount);
566                 break;
567
568         case AUDIT_TRIGGER_OPEN_NEW:
569                 /*
570                  * Create a new file and swap with the one being used in
571                  * kernel
572                  */
573                 syslog(LOG_INFO, "Got open new trigger");
574                 if (swap_audit_file() == -1)
575                         syslog(LOG_ERR, "Error swapping audit file");
576                 break;
577
578         case AUDIT_TRIGGER_READ_FILE:
579                 syslog(LOG_INFO, "Got read file trigger");
580                 if (read_control_file() == -1)
581                         syslog(LOG_ERR, "Error in audit control file");
582                 if (config_audit_controls() == -1)
583                         syslog(LOG_ERR, "Error setting audit controls");
584                 break;
585
586         default:
587                 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
588                 break;
589         }
590 }
591
592 static void
593 handle_sighup(void)
594 {
595
596         sighups_handled = sighups;
597         config_audit_controls();
598 }
599
600 /*
601  * Reap our children.
602  */
603 static void
604 reap_children(void)
605 {
606         pid_t child;
607         int wstatus;
608
609         while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
610                 if (!wstatus)
611                         continue;
612                 syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
613                     ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
614                     "exited as a result of signal"),
615                     ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
616                     WTERMSIG(wstatus)));
617         }
618 }
619
620 static void
621 handle_sigchld(void)
622 {
623
624         sigchlds_handled = sigchlds;
625         reap_children();
626 }
627
628 /*
629  * Read the control file for triggers/signals and handle appropriately.
630  */
631 static int
632 wait_for_events(void)
633 {
634         int num;
635         unsigned int trigger;
636
637         for (;;) {
638                 num = read(triggerfd, &trigger, sizeof(trigger));
639                 if ((num == -1) && (errno != EINTR)) {
640                         syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
641                         return (-1);
642                 }
643                 if (sigterms != sigterms_handled) {
644                         syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
645                         break;
646                 }
647                 if (sigchlds != sigchlds_handled) {
648                         syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__);
649                         handle_sigchld();
650                 }
651                 if (sighups != sighups_handled) {
652                         syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
653                         handle_sighup();
654                 }
655                 if ((num == -1) && (errno == EINTR))
656                         continue;
657                 if (num == 0) {
658                         syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
659                         return (-1);
660                 }
661                 syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger);
662                 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
663                         break;
664                 else
665                         handle_audit_trigger(trigger);
666         }
667         return (close_all());
668 }
669
670 /*
671  * Configure the audit controls in the kernel: the event to class mapping,
672  * kernel preselection mask, etc.
673  */
674 static int
675 config_audit_controls(void)
676 {
677         au_event_ent_t ev, *evp;
678         au_evclass_map_t evc_map;
679         au_mask_t aumask;
680         int ctr = 0;
681         char naeventstr[NA_EVENT_STR_SIZE];
682
683         /*
684          * Process the audit event file, obtaining a class mapping for each
685          * event, and send that mapping into the kernel.
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                 syslog(LOG_ERR,
695                     "Memory allocation error when configuring audit controls.");
696                 return (-1);
697         }
698         evp = &ev;
699         setauevent();
700         while ((evp = getauevent_r(evp)) != NULL) {
701                 evc_map.ec_number = evp->ae_number;
702                 evc_map.ec_class = evp->ae_class;
703                 if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
704                     != 0)
705                         syslog(LOG_ERR,
706                                 "Failed to register class mapping for event %s",
707                                  evp->ae_name);
708                 else
709                         ctr++;
710         }
711         endauevent();
712         free(ev.ae_name);
713         free(ev.ae_desc);
714         if (ctr == 0)
715                 syslog(LOG_ERR, "No events to class mappings registered.");
716         else
717                 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
718                     ctr);
719
720         /*
721          * Get the non-attributable event string and set the kernel mask from
722          * that.
723          */
724         if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
725             (getauditflagsbin(naeventstr, &aumask) == 0)) {
726                 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
727                         syslog(LOG_ERR,
728                             "Failed to register non-attributable event mask.");
729                 else
730                         syslog(LOG_DEBUG,
731                             "Registered non-attributable event mask.");
732         } else
733                 syslog(LOG_ERR,
734                     "Failed to obtain non-attributable event mask.");
735
736         /*
737          * Set the audit policy flags based on passed in parameter values.
738          */
739         if (auditon(A_SETPOLICY, &global_flags, sizeof(global_flags)))
740                 syslog(LOG_ERR, "Failed to set audit policy.");
741
742         return (0);
743 }
744
745 static void
746 setup(void)
747 {
748         auditinfo_t auinfo;
749         int aufd;
750         token_t *tok;
751
752         if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
753                 syslog(LOG_ERR, "Error opening trigger file");
754                 fail_exit();
755         }
756
757         /*
758          * To provide event feedback cycles and avoid auditd becoming
759          * stalled if auditing is suspended, auditd and its children run
760          * without their events being audited.  We allow the uid, tid, and
761          * mask fields to be implicitly set to zero, but do set the pid.  We
762          * run this after opening the trigger device to avoid configuring
763          * audit state without audit present in the system.
764          *
765          * XXXRW: Is there more to it than this?
766          */
767         bzero(&auinfo, sizeof(auinfo));
768         auinfo.ai_asid = getpid();
769         if (setaudit(&auinfo) == -1) {
770                 syslog(LOG_ERR, "Error setting audit stat");
771                 fail_exit();
772         }
773
774         TAILQ_INIT(&dir_q);
775         if (read_control_file() == -1) {
776                 syslog(LOG_ERR, "Error reading control file");
777                 fail_exit();
778         }
779
780         /* Generate an audit record. */
781         if ((aufd = au_open()) == -1)
782                 syslog(LOG_ERR, "Could not create audit startup event.");
783         else {
784                 if ((tok = au_to_text("auditd::Audit startup")) != NULL)
785                         au_write(aufd, tok);
786                 if (au_close(aufd, 1, AUE_audit_startup) == -1)
787                         syslog(LOG_ERR,
788                             "Could not close audit startup event.");
789         }
790
791         if (config_audit_controls() == 0)
792                 syslog(LOG_INFO, "Audit controls init successful");
793         else
794                 syslog(LOG_ERR, "Audit controls init failed");
795 }
796
797 int
798 main(int argc, char **argv)
799 {
800         int ch;
801         int debug = 0;
802         int rc;
803
804         global_flags |= AUDIT_CNT;
805         while ((ch = getopt(argc, argv, "dhs")) != -1) {
806                 switch(ch) {
807                 case 'd':
808                         /* Debug option. */
809                         debug = 1;
810                         break;
811
812                 case 's':
813                         /* Fail-stop option. */
814                         global_flags &= ~(AUDIT_CNT);
815                         break;
816
817                 case 'h':
818                         /* Halt-stop option. */
819                         global_flags |= AUDIT_AHLT;
820                         break;
821
822                 case '?':
823                 default:
824                         (void)fprintf(stderr,
825                             "usage: auditd [-h | -s] [-d] \n");
826                         exit(1);
827                 }
828         }
829
830 #ifdef LOG_SECURITY
831         openlog("auditd", LOG_CONS | LOG_PID, LOG_SECURITY);
832 #else
833         openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH);
834 #endif
835         syslog(LOG_INFO, "starting...");
836
837         if (debug == 0 && daemon(0, 0) == -1) {
838                 syslog(LOG_ERR, "Failed to daemonize");
839                 exit(1);
840         }
841
842         if (register_daemon() == -1) {
843                 syslog(LOG_ERR, "Could not register as daemon");
844                 exit(1);
845         }
846
847         setup();
848
849         rc = wait_for_events();
850         syslog(LOG_INFO, "auditd exiting.");
851
852         exit(rc);
853 }