]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/openbsm/bin/auditd/auditd.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / openbsm / bin / auditd / auditd.c
1 /*-
2  * Copyright (c) 2004-2009 Apple Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
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 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
30 #include <sys/types.h>
31
32 #include <config/config.h>
33
34 #include <sys/dirent.h>
35 #ifdef HAVE_FULL_QUEUE_H
36 #include <sys/queue.h>
37 #else   /* !HAVE_FULL_QUEUE_H */
38 #include <compat/queue.h>
39 #endif  /* !HAVE_FULL_QUEUE_H */
40 #include <sys/mman.h>
41 #include <sys/param.h>
42 #include <sys/stat.h>
43 #include <sys/wait.h>
44
45 #include <bsm/audit.h>
46 #include <bsm/audit_uevents.h>
47 #include <bsm/auditd_lib.h>
48 #include <bsm/libbsm.h>
49
50 #include <err.h>
51 #include <errno.h>
52 #include <fcntl.h>
53 #include <grp.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <time.h>
57 #include <unistd.h>
58 #include <signal.h>
59 #include <string.h>
60
61 #include "auditd.h"
62
63 #ifndef HAVE_STRLCPY
64 #include <compat/strlcpy.h>
65 #endif
66
67 /*
68  * XXX The following are temporary until these can be added to the kernel
69  * audit.h header.
70  */
71 #ifndef AUDIT_TRIGGER_INITIALIZE
72 #define AUDIT_TRIGGER_INITIALIZE        7
73 #endif
74 #ifndef AUDIT_TRIGGER_EXPIRE_TRAILS
75 #define AUDIT_TRIGGER_EXPIRE_TRAILS     8
76 #endif
77
78
79 /*
80  * LaunchD flag (Mac OS X and, maybe, FreeBSD only.)  See launchd(8) and
81  * http://wiki.freebsd.org/launchd for more information.
82  *
83  *      In order for auditd to work "on demand" with launchd(8) it can't:
84  *              call daemon(3)
85  *              call fork and having the parent process exit
86  *              change uids or gids.
87  *              set up the current working directory or chroot.
88  *              set the session id
89  *              change stdio to /dev/null.
90  *              call setrusage(2)
91  *              call setpriority(2)
92  *              Ignore SIGTERM.
93  *      auditd (in 'launchd mode') is launched on demand so it must catch
94  *      SIGTERM to exit cleanly.
95  */
96 static int      launchd_flag = 0;
97
98 /*
99  * The GID of the audit review group (if used).  The audit trail files and
100  * system logs (Mac OS X only) can only be reviewed by members of this group
101  * or the audit administrator (aka. "root").
102  */
103 static gid_t    audit_review_gid = -1;
104
105 /*
106  * The path and file name of the last audit trail file.
107  */
108 static char     *lastfile = NULL;
109
110 /*
111  * Error starting auditd. Run warn script and exit.
112  */
113 static void
114 fail_exit(void)
115 {
116
117         audit_warn_nostart();
118         exit(1);
119 }
120
121 /*
122  * Follow the 'current' symlink to get the active trail file name.
123  */
124 static char *
125 get_curfile(void)
126 {
127         char *cf;
128         int len;
129
130         cf = malloc(MAXPATHLEN);
131         if (cf == NULL) {
132                 auditd_log_err("malloc failed: %m");
133                 return (NULL);
134         }
135
136         len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1);
137         if (len < 0) {
138                 free(cf);
139                 return (NULL);
140         }
141
142         /* readlink() doesn't terminate string. */
143         cf[len] = '\0';
144
145         return (cf);
146 }
147
148 /*
149  * Close the previous audit trail file.
150  */
151 static int
152 close_lastfile(char *TS)
153 {
154         char *ptr;
155         char *oldname;
156
157         /* If lastfile is NULL try to get it from the 'current' link.  */
158         if (lastfile == NULL)
159                 lastfile = get_curfile();
160
161         if (lastfile != NULL) {
162                 oldname = strdup(lastfile);
163                 if (oldname == NULL)
164                         return (-1);
165
166                 /* Rename the last file -- append timestamp. */
167                 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
168                         memcpy(ptr, TS, POSTFIX_LEN);
169                         if (auditd_rename(oldname, lastfile) != 0)
170                                 auditd_log_err(
171                                     "Could not rename %s to %s: %m", oldname,
172                                     lastfile);
173                         else {
174                                 /*
175                                  * Remove the 'current' symlink since the link
176                                  * is now invalid.
177                                  */
178                                 (void) unlink(AUDIT_CURRENT_LINK);
179                                 auditd_log_notice("renamed %s to %s",
180                                     oldname, lastfile);
181                                 audit_warn_closefile(lastfile);
182                         }
183                 } else
184                         auditd_log_err("Could not rename %s to %s", oldname,
185                             lastfile);
186                 free(lastfile);
187                 free(oldname);
188                 lastfile = NULL;
189         }
190         return (0);
191 }
192
193 /*
194  * Create the new file name, swap with existing audit file.
195  */
196 static int
197 swap_audit_file(void)
198 {
199         int err;
200         char *newfile, *name;
201         char TS[TIMESTAMP_LEN + 1];
202         time_t tt;
203
204         if (getTSstr(tt, TS, sizeof(TS)) != 0)
205                 return (-1);
206         /*
207          * If prefix and suffix are the same, it means that records are
208          * being produced too fast. We don't want to rename now, because
209          * next trail file can get the same name and once that one is
210          * terminated also within one second it will overwrite the current
211          * one. Just keep writing to the same trail and wait for the next
212          * trigger from the kernel.
213          * FREEBSD KERNEL WAS UPDATED TO KEEP SENDING TRIGGERS, WHICH MIGHT
214          * NOT BE THE CASE FOR OTHER OSES.
215          * If the kernel will not keep sending triggers, trail file will not
216          * be terminated.
217          */
218         if (lastfile == NULL) {
219                 name = NULL;
220         } else {
221                 name = strrchr(lastfile, '/');
222                 if (name != NULL)
223                         name++;
224         }
225         if (name != NULL && strncmp(name, TS, TIMESTAMP_LEN) == 0) {
226                 auditd_log_debug("Not ready to terminate trail file yet.");
227                 return (0);
228         }
229         err = auditd_swap_trail(TS, &newfile, audit_review_gid,
230             audit_warn_getacdir);
231         if (err != ADE_NOERR) {
232                 auditd_log_err("%s: %m", auditd_strerror(err));
233                 if (err != ADE_ACTL)
234                         return (-1);
235         }
236
237         /*
238          * Only close the last file if were in an auditing state before
239          * calling swap_audit_file().  We may need to recover from a crash.
240          */
241         if (auditd_get_state() == AUD_STATE_ENABLED)
242                 close_lastfile(TS);
243
244
245         /*
246          * auditd_swap_trail() potentially enables auditing (if not already
247          * enabled) so updated the cached state as well.
248          */
249         auditd_set_state(AUD_STATE_ENABLED);
250
251         /*
252          *  Create 'current' symlink.  Recover from crash, if needed.
253          */
254         if (auditd_new_curlink(newfile) != 0)
255                 auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m",
256                     newfile, auditd_strerror(err));
257
258         lastfile = newfile;
259         auditd_log_notice("New audit file is %s", newfile);
260
261         return (0);
262 }
263
264 /*
265  * Create a new audit log trail file and swap with the current one, if any.
266  */
267 static int
268 do_trail_file(void)
269 {
270         int err;
271
272         /*
273          * First, refresh the list of audit log directories.
274          */
275         err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
276         if (err) {
277                 auditd_log_err("auditd_read_dirs(): %s",
278                     auditd_strerror(err));
279                 if (err == ADE_HARDLIM)
280                         audit_warn_allhard();
281                 if (err != ADE_SOFTLIM)
282                         return (-1);
283                 else
284                         audit_warn_allsoft();
285                         /* continue on with soft limit error */
286         }
287
288         /*
289          * Create a new file and swap with the one being used in kernel.
290          */
291         if (swap_audit_file() == -1) {
292                 /*
293                  * XXX Faulty directory listing? - user should be given
294                  * XXX an opportunity to change the audit_control file
295                  * XXX switch to a reduced mode of auditing?
296                  */
297                 return (-1);
298         }
299
300         /*
301          * Finally, see if there are any trail files to expire.
302          */
303         err = auditd_expire_trails(audit_warn_expired);
304         if (err)
305                 auditd_log_err("auditd_expire_trails(): %s",
306                     auditd_strerror(err));
307
308         return (0);
309 }
310
311 /*
312  * Start up auditing.
313  */
314 static void
315 audit_setup(void)
316 {
317         int err;
318
319         /* Configure trail files distribution. */
320         err = auditd_set_dist();
321         if (err) {
322                 auditd_log_err("auditd_set_dist() %s: %m",
323                     auditd_strerror(err));
324         } else
325                 auditd_log_debug("Configured trail files distribution.");
326
327         if (do_trail_file() == -1) {
328                 auditd_log_err("Error creating audit trail file");
329                 fail_exit();
330         }
331
332         /* Generate an audit record. */
333         err = auditd_gen_record(AUE_audit_startup, NULL);
334         if (err)
335                 auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m",
336                     auditd_strerror(err));
337
338         if (auditd_config_controls() == 0)
339                 auditd_log_info("Audit controls init successful");
340         else
341                 auditd_log_err("Audit controls init failed");
342 }
343
344
345 /*
346  * Close auditd pid file and trigger mechanism.
347  */
348 static int
349 close_misc(void)
350 {
351
352         auditd_close_dirs();
353         if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) {
354                 auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE);
355                 return (1);
356         }
357         endac();
358
359         if (auditd_close_trigger() != 0) {
360                 auditd_log_err("Error closing trigger messaging mechanism");
361                 return (1);
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         int err_ret = 0;
373         char TS[TIMESTAMP_LEN + 1];
374         int err;
375         int cond;
376         time_t tt;
377
378         err = auditd_gen_record(AUE_audit_shutdown, NULL);
379         if (err)
380                 auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m",
381                     auditd_strerror(err));
382
383         /* Flush contents. */
384         cond = AUC_DISABLED;
385         err_ret = audit_set_cond(&cond);
386         if (err_ret != 0) {
387                 auditd_log_err("Disabling audit failed! : %s", strerror(errno));
388                 err_ret = 1;
389         }
390
391         /*
392          * Updated the cached state that auditing has been disabled.
393          */
394         auditd_set_state(AUD_STATE_DISABLED);
395
396         if (getTSstr(tt, TS, sizeof(TS)) == 0)
397                 close_lastfile(TS);
398         if (lastfile != NULL)
399                 free(lastfile);
400
401         err_ret += close_misc();
402
403         if (err_ret) {
404                 auditd_log_err("Could not unregister");
405                 audit_warn_postsigterm();
406         }
407
408         auditd_log_info("Finished");
409         return (err_ret);
410 }
411
412 /*
413  * Register the daemon with the signal handler and the auditd pid file.
414  */
415 static int
416 register_daemon(void)
417 {
418         struct sigaction action;
419         FILE * pidfile;
420         int fd;
421         pid_t pid;
422
423         /* Set up the signal hander. */
424         action.sa_handler = auditd_relay_signal;
425         /*
426          * sa_flags must not include SA_RESTART, so that read(2) will be
427          * interruptible in auditd_wait_for_events
428          */
429         action.sa_flags = 0;
430         sigemptyset(&action.sa_mask);
431         if (sigaction(SIGTERM, &action, NULL) != 0) {
432                 auditd_log_err(
433                     "Could not set signal handler for SIGTERM");
434                 fail_exit();
435         }
436         if (sigaction(SIGCHLD, &action, NULL) != 0) {
437                 auditd_log_err(
438                     "Could not set signal handler for SIGCHLD");
439                 fail_exit();
440         }
441         if (sigaction(SIGHUP, &action, NULL) != 0) {
442                 auditd_log_err(
443                     "Could not set signal handler for SIGHUP");
444                 fail_exit();
445         }
446         if (sigaction(SIGALRM, &action, NULL) != 0) {
447                 auditd_log_err(
448                     "Could not set signal handler for SIGALRM");
449                 fail_exit();
450         }
451
452         if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
453                 auditd_log_err("Could not open PID file");
454                 audit_warn_tmpfile();
455                 return (-1);
456         }
457
458         /* Attempt to lock the pid file; if a lock is present, exit. */
459         fd = fileno(pidfile);
460         if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
461                 auditd_log_err(
462                     "PID file is locked (is another auditd running?).");
463                 audit_warn_ebusy();
464                 return (-1);
465         }
466
467         pid = getpid();
468         ftruncate(fd, 0);
469         if (fprintf(pidfile, "%u\n", pid) < 0) {
470                 /* Should not start the daemon. */
471                 fail_exit();
472         }
473
474         fflush(pidfile);
475         return (0);
476 }
477
478 /*
479  * Handle the audit trigger event.
480  *
481  * We suppress (ignore) duplicated triggers in close succession in order to
482  * try to avoid thrashing-like behavior.  However, not all triggers can be
483  * ignored, as triggers generally represent edge triggers, not level
484  * triggers, and won't be retransmitted if the condition persists.  Of
485  * specific concern is the rotate trigger -- if one is dropped, then it will
486  * not be retransmitted, and the log file will grow in an unbounded fashion.
487  */
488 #define DUPLICATE_INTERVAL      30
489 void
490 auditd_handle_trigger(int trigger)
491 {
492         static int last_trigger, last_warning;
493         static time_t last_time;
494         struct timeval ts;
495         struct timezone tzp;
496         time_t tt;
497         int au_state;
498         int err = 0;
499
500         /*
501          * Suppress duplicate messages from the kernel within the specified
502          * interval.
503          */
504         if (gettimeofday(&ts, &tzp) == 0) {
505                 tt = (time_t)ts.tv_sec;
506                 switch (trigger) {
507                 case AUDIT_TRIGGER_LOW_SPACE:
508                 case AUDIT_TRIGGER_NO_SPACE:
509                         /*
510                          * Triggers we can suppress.  Of course, we also need
511                          * to rate limit the warnings, so apply the same
512                          * interval limit on syslog messages.
513                          */
514                         if ((trigger == last_trigger) &&
515                             (tt < (last_time + DUPLICATE_INTERVAL))) {
516                                 if (tt >= (last_warning + DUPLICATE_INTERVAL))
517                                         auditd_log_info(
518                                             "Suppressing duplicate trigger %d",
519                                             trigger);
520                                 return;
521                         }
522                         last_warning = tt;
523                         break;
524
525                 case AUDIT_TRIGGER_ROTATE_KERNEL:
526                 case AUDIT_TRIGGER_ROTATE_USER:
527                 case AUDIT_TRIGGER_READ_FILE:
528                 case AUDIT_TRIGGER_CLOSE_AND_DIE:
529                 case AUDIT_TRIGGER_INITIALIZE:
530                         /*
531                          * Triggers that we cannot suppress.
532                          */
533                         break;
534                 }
535
536                 /*
537                  * Only update last_trigger after aborting due to a duplicate
538                  * trigger, not before, or we will never allow that trigger
539                  * again.
540                  */
541                 last_trigger = trigger;
542                 last_time = tt;
543         }
544
545         au_state = auditd_get_state();
546
547         /*
548          * Message processing is done here.
549          */
550         switch(trigger) {
551         case AUDIT_TRIGGER_LOW_SPACE:
552                 auditd_log_notice("Got low space trigger");
553                 if (do_trail_file() == -1)
554                         auditd_log_err("Error swapping audit file");
555                 break;
556
557         case AUDIT_TRIGGER_NO_SPACE:
558                 auditd_log_notice("Got no space trigger");
559                 if (do_trail_file() == -1)
560                         auditd_log_err("Error swapping audit file");
561                 break;
562
563         case AUDIT_TRIGGER_ROTATE_KERNEL:
564         case AUDIT_TRIGGER_ROTATE_USER:
565                 auditd_log_info("Got open new trigger from %s", trigger ==
566                     AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
567                 if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
568                         auditd_log_err("Error swapping audit file");
569                 break;
570
571         case AUDIT_TRIGGER_READ_FILE:
572                 auditd_log_info("Got read file trigger");
573                 if (au_state == AUD_STATE_ENABLED) {
574                         if (auditd_config_controls() == -1)
575                                 auditd_log_err("Error setting audit controls");
576                         else if (do_trail_file() == -1)
577                                 auditd_log_err("Error swapping audit file");
578                 }
579                 break;
580
581         case AUDIT_TRIGGER_CLOSE_AND_DIE:
582                 auditd_log_info("Got close and die trigger");
583                 if (au_state == AUD_STATE_ENABLED)
584                         err = close_all();
585                 /*
586                  * Running under launchd don't exit.  Wait for launchd to
587                  * send SIGTERM.
588                  */
589                 if (!launchd_flag) {
590                         auditd_log_info("auditd exiting.");
591                         exit (err);
592                 }
593                 break;
594
595         case AUDIT_TRIGGER_INITIALIZE:
596                 auditd_log_info("Got audit initialize trigger");
597                 if (au_state == AUD_STATE_DISABLED)
598                         audit_setup();
599                 break;
600
601         case AUDIT_TRIGGER_EXPIRE_TRAILS:
602                 auditd_log_info("Got audit expire trails trigger");
603                 err = auditd_expire_trails(audit_warn_expired);
604                 if (err)
605                         auditd_log_err("auditd_expire_trails(): %s",
606                             auditd_strerror(err));
607                 break;
608
609         default:
610                 auditd_log_err("Got unknown trigger %d", trigger);
611                 break;
612         }
613 }
614
615 /*
616  * Reap our children.
617  */
618 void
619 auditd_reap_children(void)
620 {
621         pid_t child;
622         int wstatus;
623
624         while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
625                 if (!wstatus)
626                         continue;
627                 auditd_log_info("warn process [pid=%d] %s %d.", child,
628                     ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
629                     "exited as a result of signal"),
630                     ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
631                     WTERMSIG(wstatus)));
632         }
633 }
634
635 /*
636  * Reap any children and terminate.  If under launchd don't shutdown auditing
637  * but just the other stuff.
638  */
639 void
640 auditd_terminate(void)
641 {
642         int ret;
643
644         auditd_reap_children();
645
646         if (launchd_flag)
647                 ret = close_misc();
648         else
649                 ret = close_all();
650
651         exit(ret);
652 }
653
654 /*
655  * Configure the audit controls in the kernel: the event to class mapping,
656  * kernel preselection mask, etc.
657  */
658 int
659 auditd_config_controls(void)
660 {
661         int cnt, err;
662         int ret = 0;
663
664         /*
665          * Configure event to class mappings in kernel.
666          */
667         cnt = auditd_set_evcmap();
668         if (cnt < 0) {
669                 auditd_log_err("auditd_set_evcmap() failed: %m");
670                 ret = -1;
671         } else if (cnt == 0) {
672                 auditd_log_err("No events to class mappings registered.");
673                 ret = -1;
674         } else
675                 auditd_log_debug("Registered %d event to class mappings.", cnt);
676
677         /*
678          * Configure non-attributable event mask in kernel.
679          */
680         err = auditd_set_namask();
681         if (err) {
682                 auditd_log_err("auditd_set_namask() %s: %m",
683                     auditd_strerror(err));
684                 ret = -1;
685         } else
686                 auditd_log_debug("Registered non-attributable event mask.");
687
688         /*
689          * Configure audit policy in kernel.
690          */
691         err = auditd_set_policy();
692         if (err) {
693                 auditd_log_err("auditd_set_policy() %s: %m",
694                     auditd_strerror(err));
695                 ret = -1;
696         } else
697                 auditd_log_debug("Set audit policy in kernel.");
698
699         /*
700          * Configure audit trail log size in kernel.
701          */
702         err = auditd_set_fsize();
703         if (err) {
704                 auditd_log_err("audit_set_fsize() %s: %m",
705                     auditd_strerror(err));
706                 ret = -1;
707         } else
708                 auditd_log_debug("Set audit trail size in kernel.");
709
710         /*
711          * Configure audit trail volume minimum free percentage of blocks in
712          * kernel.
713          */
714         err = auditd_set_minfree();
715         if (err) {
716                 auditd_log_err("auditd_set_minfree() %s: %m",
717                     auditd_strerror(err));
718                 ret = -1;
719         } else
720                 auditd_log_debug(
721                     "Set audit trail min free percent in kernel.");
722
723         /*
724          * Configure host address in the audit kernel information.
725          */
726         err = auditd_set_host();
727         if (err) {
728                 if (err == ADE_PARSE) {
729                         auditd_log_notice(
730                             "audit_control(5) may be missing 'host:' field");
731                 } else {
732                         auditd_log_err("auditd_set_host() %s: %m",
733                             auditd_strerror(err));
734                         ret = -1;
735                 }
736         } else
737                 auditd_log_debug(
738                     "Set audit host address information in kernel.");
739
740         return (ret);
741 }
742
743 /*
744  * Setup and initialize auditd.
745  */
746 static void
747 setup(void)
748 {
749         int err;
750
751         if (auditd_open_trigger(launchd_flag) < 0) {
752                 auditd_log_err("Error opening trigger messaging mechanism");
753                 fail_exit();
754         }
755
756         /*
757          * To prevent event feedback cycles and avoid auditd becoming
758          * stalled if auditing is suspended, auditd and its children run
759          * without their events being audited.  We allow the uid, tid, and
760          * mask fields to be implicitly set to zero, but do set the pid.  We
761          * run this after opening the trigger device to avoid configuring
762          * audit state without audit present in the system.
763          */
764         err = auditd_prevent_audit();
765         if (err) {
766                 auditd_log_err("auditd_prevent_audit() %s: %m",
767                     auditd_strerror(err));
768                 fail_exit();
769         }
770
771         /*
772          * Make sure auditd auditing state is correct.
773          */
774         auditd_set_state(AUD_STATE_INIT);
775
776         /*
777          * If under launchd, don't start auditing.  Wait for a trigger to
778          * do so.
779          */
780         if (!launchd_flag)
781                 audit_setup();
782 }
783
784 int
785 main(int argc, char **argv)
786 {
787         int ch;
788         int debug = 0;
789 #ifdef AUDIT_REVIEW_GROUP
790         struct group *grp;
791 #endif
792
793         while ((ch = getopt(argc, argv, "dl")) != -1) {
794                 switch(ch) {
795                 case 'd':
796                         /* Debug option. */
797                         debug = 1;
798                         break;
799
800                 case 'l':
801                         /* Be launchd friendly. */
802                         launchd_flag = 1;
803                         break;
804
805                 case '?':
806                 default:
807                         (void)fprintf(stderr,
808                             "usage: auditd [-d] [-l]\n");
809                         exit(1);
810                 }
811         }
812
813         audit_review_gid = getgid();
814
815 #ifdef AUDIT_REVIEW_GROUP
816         /*
817          * XXXRW: Currently, this code falls back to the daemon gid, which is
818          * likely the wheel group.  Is there a better way to deal with this?
819          */
820         grp = getgrnam(AUDIT_REVIEW_GROUP);
821         if (grp != NULL)
822                 audit_review_gid = grp->gr_gid;
823 #endif
824
825         auditd_openlog(debug, audit_review_gid);
826
827         if (launchd_flag)
828                 auditd_log_info("started by launchd...");
829         else
830                 auditd_log_info("starting...");
831
832 #ifdef AUDIT_REVIEW_GROUP
833         if (grp == NULL)
834                 auditd_log_info(
835                     "Audit review group '%s' not available, using daemon gid (%d)",
836                     AUDIT_REVIEW_GROUP, audit_review_gid);
837 #endif
838         if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
839                 auditd_log_err("Failed to daemonize");
840                 exit(1);
841         }
842
843         if (register_daemon() == -1) {
844                 auditd_log_err("Could not register as daemon");
845                 exit(1);
846         }
847
848         setup();
849
850         /*
851          * auditd_wait_for_events() shouldn't return unless something is wrong.
852          */
853         auditd_wait_for_events();
854
855         auditd_log_err("abnormal exit.");
856         close_all();
857         exit(-1);
858 }