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
fail_exit(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 *
get_curfile(void)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
close_lastfile(char * TS)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
swap_audit_file(void)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
do_trail_file(void)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
audit_setup(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
close_misc(void)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
close_all(void)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
register_daemon(void)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
auditd_handle_trigger(int trigger)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
auditd_reap_children(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
auditd_terminate(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
auditd_config_controls(void)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 queue size in kernel.
712 */
713 err = auditd_set_qsize();
714 if (err) {
715 auditd_log_err("auditd_set_qsize() %s: %m",
716 auditd_strerror(err));
717 ret = -1;
718 } else
719 auditd_log_debug("Set audit trail queue in kernel.");
720
721 /*
722 * Configure audit trail volume minimum free percentage of blocks in
723 * kernel.
724 */
725 err = auditd_set_minfree();
726 if (err) {
727 auditd_log_err("auditd_set_minfree() %s: %m",
728 auditd_strerror(err));
729 ret = -1;
730 } else
731 auditd_log_debug(
732 "Set audit trail min free percent in kernel.");
733
734 /*
735 * Configure host address in the audit kernel information.
736 */
737 err = auditd_set_host();
738 if (err) {
739 if (err == ADE_PARSE) {
740 auditd_log_notice(
741 "audit_control(5) may be missing 'host:' field");
742 } else {
743 auditd_log_err("auditd_set_host() %s: %m",
744 auditd_strerror(err));
745 ret = -1;
746 }
747 } else
748 auditd_log_debug(
749 "Set audit host address information in kernel.");
750
751 return (ret);
752 }
753
754 /*
755 * Setup and initialize auditd.
756 */
757 static void
setup(void)758 setup(void)
759 {
760 int err;
761
762 if (auditd_open_trigger(launchd_flag) < 0) {
763 auditd_log_err("Error opening trigger messaging mechanism");
764 fail_exit();
765 }
766
767 /*
768 * To prevent event feedback cycles and avoid auditd becoming
769 * stalled if auditing is suspended, auditd and its children run
770 * without their events being audited. We allow the uid, tid, and
771 * mask fields to be implicitly set to zero, but do set the pid. We
772 * run this after opening the trigger device to avoid configuring
773 * audit state without audit present in the system.
774 */
775 err = auditd_prevent_audit();
776 if (err) {
777 auditd_log_err("auditd_prevent_audit() %s: %m",
778 auditd_strerror(err));
779 fail_exit();
780 }
781
782 /*
783 * Make sure auditd auditing state is correct.
784 */
785 auditd_set_state(AUD_STATE_INIT);
786
787 /*
788 * If under launchd, don't start auditing. Wait for a trigger to
789 * do so.
790 */
791 if (!launchd_flag)
792 audit_setup();
793 }
794
795 int
main(int argc,char ** argv)796 main(int argc, char **argv)
797 {
798 int ch;
799 int debug = 0;
800 #ifdef AUDIT_REVIEW_GROUP
801 struct group *grp;
802 #endif
803
804 while ((ch = getopt(argc, argv, "dl")) != -1) {
805 switch(ch) {
806 case 'd':
807 /* Debug option. */
808 debug = 1;
809 break;
810
811 case 'l':
812 /* Be launchd friendly. */
813 launchd_flag = 1;
814 break;
815
816 case '?':
817 default:
818 (void)fprintf(stderr,
819 "usage: auditd [-d] [-l]\n");
820 exit(1);
821 }
822 }
823
824 audit_review_gid = getgid();
825
826 #ifdef AUDIT_REVIEW_GROUP
827 /*
828 * XXXRW: Currently, this code falls back to the daemon gid, which is
829 * likely the wheel group. Is there a better way to deal with this?
830 */
831 grp = getgrnam(AUDIT_REVIEW_GROUP);
832 if (grp != NULL)
833 audit_review_gid = grp->gr_gid;
834 #endif
835
836 auditd_openlog(debug, audit_review_gid);
837
838 if (launchd_flag)
839 auditd_log_info("started by launchd...");
840 else
841 auditd_log_info("starting...");
842
843 #ifdef AUDIT_REVIEW_GROUP
844 if (grp == NULL)
845 auditd_log_info(
846 "Audit review group '%s' not available, using daemon gid (%d)",
847 AUDIT_REVIEW_GROUP, audit_review_gid);
848 #endif
849 if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
850 auditd_log_err("Failed to daemonize");
851 exit(1);
852 }
853
854 if (register_daemon() == -1) {
855 auditd_log_err("Could not register as daemon");
856 exit(1);
857 }
858
859 setup();
860
861 /*
862 * auditd_wait_for_events() shouldn't return unless something is wrong.
863 */
864 auditd_wait_for_events();
865
866 auditd_log_err("abnormal exit.");
867 close_all();
868 exit(-1);
869 }
870