]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/openbsm/bin/auditd/auditd.c
Merge OpenBSM 1.1 alpha 2 from the OpenBSM vendor branch to head, both
[FreeBSD/FreeBSD.git] / contrib / openbsm / bin / auditd / auditd.c
1 /*-
2  * Copyright (c) 2004-2008 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  * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#39 $
30  */
31
32 #include <sys/param.h>
33
34 #include <config/config.h>
35
36 #include <sys/dirent.h>
37 #include <sys/mman.h>
38 #include <sys/socket.h>
39 #ifdef HAVE_FULL_QUEUE_H
40 #include <sys/queue.h>
41 #else /* !HAVE_FULL_QUEUE_H */
42 #include <compat/queue.h>
43 #endif /* !HAVE_FULL_QUEUE_H */
44 #include <sys/stat.h>
45 #include <sys/wait.h>
46
47 #include <bsm/audit.h>
48 #include <bsm/audit_uevents.h>
49 #include <bsm/libbsm.h>
50
51 #include <netinet/in.h>
52
53 #include <err.h>
54 #include <errno.h>
55 #include <fcntl.h>
56 #include <grp.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <time.h>
60 #include <unistd.h>
61 #include <signal.h>
62 #include <string.h>
63 #include <syslog.h>
64 #include <netdb.h>
65
66 #include "auditd.h"
67 #ifdef USE_MACH_IPC
68 #include <notify.h>
69 #include <mach/port.h>
70 #include <mach/mach_error.h>
71 #include <mach/mach_traps.h>
72 #include <mach/mach.h>
73 #include <mach/host_special_ports.h>
74
75 #include "auditd_control_server.h"
76 #include "audit_triggers_server.h"
77 #endif /* USE_MACH_IPC */
78
79 #ifndef HAVE_STRLCPY
80 #include <compat/strlcpy.h>
81 #endif
82
83 #define NA_EVENT_STR_SIZE       25
84 #define POL_STR_SIZE            128
85 static int       ret, minval;
86 static char     *lastfile = NULL;
87 static int       allhardcount = 0;
88 static int       sigchlds, sigchlds_handled;
89 static int       sighups, sighups_handled;
90 #ifndef USE_MACH_IPC
91 static int       sigterms, sigterms_handled;
92 static int       triggerfd = 0;
93
94 #else /* USE_MACH_IPC */
95
96 static mach_port_t      control_port = MACH_PORT_NULL;
97 static mach_port_t      signal_port = MACH_PORT_NULL;
98 static mach_port_t      port_set = MACH_PORT_NULL;
99
100 #ifndef __BSM_INTERNAL_NOTIFY_KEY
101 #define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
102 #endif /* __BSM_INTERNAL_NOTIFY_KEY */
103 #endif /* USE_MACH_IPC */
104
105 static TAILQ_HEAD(, dir_ent)    dir_q;
106
107 static int      config_audit_controls(void);
108
109 /*
110  * Error starting auditd
111  */
112 static void
113 fail_exit(void)
114 {
115
116         audit_warn_nostart();
117         exit(1);
118 }
119
120 /*
121  * Free our local list of directory names.
122  */
123 static void
124 free_dir_q(void)
125 {
126         struct dir_ent *dirent;
127
128         while ((dirent = TAILQ_FIRST(&dir_q))) {
129                 TAILQ_REMOVE(&dir_q, dirent, dirs);
130                 free(dirent->dirname);
131                 free(dirent);
132         }
133 }
134
135 /*
136  * Generate the timestamp string.
137  */
138 static int
139 getTSstr(char *buf, int len)
140 {
141         struct timeval ts;
142         struct timezone tzp;
143         time_t tt;
144
145         if (gettimeofday(&ts, &tzp) != 0)
146                 return (-1);
147         tt = (time_t)ts.tv_sec;
148         if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
149                 return (-1);
150         return (0);
151 }
152
153 /*
154  * Concat the directory name to the given file name.
155  * XXX We should affix the hostname also
156  */
157 static char *
158 affixdir(char *name, struct dir_ent *dirent)
159 {
160         char *fn = NULL;
161
162         syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
163         /* 
164          * Sanity check on file name.
165          */
166         if (strlen(name) != (FILENAME_LEN - 1)) {
167                 syslog(LOG_ERR, "Invalid file name: %s", name);
168                 return (NULL);
169         }
170         asprintf(&fn, "%s/%s", dirent->dirname, name);
171         return (fn);
172 }
173
174 /*
175  * Close the previous audit trail file.
176  */
177 static int
178 close_lastfile(char *TS)
179 {
180         char *ptr;
181         char *oldname;
182         size_t len;
183
184         if (lastfile != NULL) {
185                 len = strlen(lastfile) + 1;
186                 oldname = (char *)malloc(len);
187                 if (oldname == NULL)
188                         return (-1);
189                 strlcpy(oldname, lastfile, len);
190
191                 /* Rename the last file -- append timestamp. */
192                 if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
193                         strlcpy(ptr, TS, TIMESTAMP_LEN);
194                         if (rename(oldname, lastfile) != 0)
195                                 syslog(LOG_ERR,
196                                     "Could not rename %s to %s: %m", oldname,
197                                     lastfile);
198                         else {
199                                 syslog(LOG_INFO, "renamed %s to %s",
200                                     oldname, lastfile);
201                                 audit_warn_closefile(lastfile);
202                         }
203                 } else 
204                         syslog(LOG_ERR, "Could not rename %s to %s", oldname,
205                             lastfile);
206                 free(lastfile);
207                 free(oldname);
208                 lastfile = NULL;
209         }
210         return (0);
211 }
212
213 /*
214  * Create the new audit file with appropriate permissions and ownership.  Try
215  * to clean up if something goes wrong.
216  */
217 static int
218 #ifdef AUDIT_REVIEW_GROUP
219 open_trail(const char *fname, uid_t uid, gid_t gid)
220 #else
221 open_trail(const char *fname)
222 #endif
223 {
224         int error, fd;
225
226         fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
227         if (fd < 0)
228                 return (-1);
229 #ifdef AUDIT_REVIEW_GROUP
230         if (fchown(fd, uid, gid) < 0) {
231                 error = errno;
232                 close(fd);
233                 (void)unlink(fname);
234                 errno = error;
235                 return (-1);
236         }
237 #endif
238         return (fd);
239 }
240
241 /*
242  * Create the new file name, swap with existing audit file.
243  */
244 static int
245 swap_audit_file(void)
246 {
247         char timestr[FILENAME_LEN];
248         char *fn;
249         char TS[TIMESTAMP_LEN];
250         struct dir_ent *dirent;
251 #ifdef AUDIT_REVIEW_GROUP
252         struct group *grp;
253         gid_t gid;
254         uid_t uid;
255 #endif
256         int error, fd;
257
258         if (getTSstr(TS, TIMESTAMP_LEN) != 0)
259                 return (-1);
260
261         snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED);
262
263 #ifdef AUDIT_REVIEW_GROUP
264         /*
265          * XXXRW: Currently, this code falls back to the daemon gid, which is
266          * likely the wheel group.  Is there a better way to deal with this?
267          */
268         grp = getgrnam(AUDIT_REVIEW_GROUP);
269         if (grp == NULL) {
270                 syslog(LOG_INFO,
271                     "Audit review group '%s' not available, using daemon gid",
272                     AUDIT_REVIEW_GROUP);
273                 gid = -1;
274         } else
275                 gid = grp->gr_gid;
276         uid = getuid();
277 #endif
278
279         /* Try until we succeed. */
280         while ((dirent = TAILQ_FIRST(&dir_q))) {
281                 if ((fn = affixdir(timestr, dirent)) == NULL) {
282                         syslog(LOG_INFO, "Failed to swap log at time %s",
283                                 timestr);
284                         return (-1);
285                 }
286
287                 /*
288                  * Create and open the file; then close and pass to the
289                  * kernel if all went well.
290                  */
291                 syslog(LOG_INFO, "New audit file is %s", fn);
292 #ifdef AUDIT_REVIEW_GROUP
293                 fd = open_trail(fn, uid, gid);
294 #else
295                 fd = open_trail(fn);
296 #endif
297                 if (fd < 0)
298                         warn("open(%s)", fn);
299                 if (fd >= 0) {
300                         error = auditctl(fn);
301                         if (error) {
302                                 syslog(LOG_ERR,
303                                     "auditctl failed setting log file! : %s",
304                                     strerror(errno));
305                                 close(fd);
306                         } else {
307                                 /* Success. */
308 #ifdef USE_MACH_IPC
309                                 /* 
310                                  * auditctl() potentially changes the audit
311                                  * state so post that the audit config (may
312                                  * have) changed. 
313                                  */
314                                 notify_post(__BSM_INTERNAL_NOTIFY_KEY);
315 #endif
316                                 close_lastfile(TS);
317                                 lastfile = fn;
318                                 close(fd);
319                                 return (0);
320                         }
321                 }
322
323                 /*
324                  * Tell the administrator about lack of permissions for dir.
325                  */
326                 audit_warn_getacdir(dirent->dirname);
327
328                 /* Try again with a different directory. */
329                 TAILQ_REMOVE(&dir_q, dirent, dirs);
330                 free(dirent->dirname);
331                 free(dirent);
332         }
333         syslog(LOG_ERR, "Log directories exhausted");
334         return (-1);
335 }
336
337 /*
338  * Read the audit_control file contents.
339  */
340 static int
341 read_control_file(void)
342 {
343         char cur_dir[MAXNAMLEN];
344         struct dir_ent *dirent;
345         au_qctrl_t qctrl;
346
347         /*
348          * Clear old values.  Force a re-read of the file the next time.
349          */
350         free_dir_q();
351         endac();
352
353         /*
354          * Read the list of directories into a local linked list.
355          *
356          * XXX We should use the reentrant interfaces once they are
357          * available.
358          */
359         while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
360                 dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
361                 if (dirent == NULL)
362                         return (-1);
363                 dirent->softlim = 0;
364                 dirent->dirname = (char *) malloc(MAXNAMLEN);
365                 if (dirent->dirname == NULL) {
366                         free(dirent);
367                         return (-1);
368                 }
369                 strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
370                 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
371         }
372
373         allhardcount = 0;
374         if (swap_audit_file() == -1) {
375                 syslog(LOG_ERR, "Could not swap audit file");
376                 /*
377                  * XXX Faulty directory listing? - user should be given
378                  * XXX an opportunity to change the audit_control file
379                  * XXX switch to a reduced mode of auditing?
380                  */
381                 return (-1);
382         }
383
384         /*
385          * XXX There are synchronization problems here
386          * XXX what should we do if a trigger for the earlier limit
387          * XXX is generated here?
388          */
389         if (0 == (ret = getacmin(&minval))) {
390                 syslog(LOG_DEBUG, "min free = %d", minval);
391                 if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
392                         syslog(LOG_ERR,
393                             "could not get audit queue settings");
394                                 return (-1);
395                 }
396                 qctrl.aq_minfree = minval;
397                 if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
398                         syslog(LOG_ERR,
399                             "could not set audit queue settings");
400                         return (-1);
401                 }
402         }
403
404         return (0);
405 }
406
407 /*
408  * Close all log files, control files, and tell the audit system.
409  */
410 static int
411 close_all(void)
412 {
413         struct auditinfo ai;
414         int err_ret = 0;
415         char TS[TIMESTAMP_LEN];
416         int aufd;
417         token_t *tok;
418         long cond;
419
420         /* Generate an audit record. */
421         if ((aufd = au_open()) == -1)
422                 syslog(LOG_ERR, "Could not create audit shutdown event.");
423         else {
424                 if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
425                         au_write(aufd, tok);
426                 /*
427                  * XXX we need to implement extended subject tokens so we can
428                  * effectively represent terminal lines with this token type.
429                  */
430                 bzero(&ai, sizeof(ai));
431                 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
432                     getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
433                     != NULL)
434                         au_write(aufd, tok);
435                 if ((tok = au_to_return32(0, 0)) != NULL)
436                         au_write(aufd, tok);
437                 if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
438                         syslog(LOG_ERR,
439                             "Could not close audit shutdown event.");
440         }
441
442         /* Flush contents. */
443         cond = AUC_DISABLED;
444         err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
445         if (err_ret != 0) {
446                 syslog(LOG_ERR, "Disabling audit failed! : %s",
447                     strerror(errno));
448                 err_ret = 1;
449         }
450 #ifdef USE_MACH_IPC
451         /* 
452          * Post a notification that the audit config changed. 
453          */
454         notify_post(__BSM_INTERNAL_NOTIFY_KEY);
455 #endif
456         if (getTSstr(TS, TIMESTAMP_LEN) == 0)
457                 close_lastfile(TS);
458         if (lastfile != NULL)
459                 free(lastfile);
460
461         free_dir_q();
462         if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
463                 syslog(LOG_ERR, "Could not unregister");
464                 audit_warn_postsigterm();
465                 return (1);
466         }
467         endac();
468
469 #ifndef USE_MACH_IPC
470         if (close(triggerfd) != 0)
471                 syslog(LOG_ERR, "Error closing control file");
472 #endif
473         syslog(LOG_INFO, "Finished");
474         return (0);
475 }
476
477 /*
478  * When we get a signal, we are often not at a clean point.  So, little can
479  * be done in the signal handler itself.  Instead,  we send a message to the
480  * main servicing loop to do proper handling from a non-signal-handler
481  * context.
482  */
483 #ifdef USE_MACH_IPC
484 static void
485 relay_signal(int signal)
486 {
487         mach_msg_empty_send_t msg;
488
489         msg.header.msgh_id = signal;
490         msg.header.msgh_remote_port = signal_port;
491         msg.header.msgh_local_port = MACH_PORT_NULL;
492         msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
493         mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
494             0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
495 }
496
497 #else /* ! USE_MACH_IPC */
498
499 static void
500 relay_signal(int signal)
501 {
502
503         if (signal == SIGHUP)
504                 sighups++;
505         if (signal == SIGTERM)
506                 sigterms++;
507         if (signal == SIGCHLD)
508                 sigchlds++;
509 }
510 #endif /* ! USE_MACH_IPC */
511
512 /*
513  * Registering the daemon.
514  */
515 static int
516 register_daemon(void)
517 {
518         FILE * pidfile;
519         int fd;
520         pid_t pid;
521
522         /* Set up the signal hander. */
523         if (signal(SIGTERM, relay_signal) == SIG_ERR) {
524                 syslog(LOG_ERR,
525                     "Could not set signal handler for SIGTERM");
526                 fail_exit();
527         }
528         if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
529                 syslog(LOG_ERR,
530                     "Could not set signal handler for SIGCHLD");
531                 fail_exit();
532         }
533         if (signal(SIGHUP, relay_signal) == SIG_ERR) {
534                 syslog(LOG_ERR,
535                     "Could not set signal handler for SIGHUP");
536                 fail_exit();
537         }
538
539         if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
540                 syslog(LOG_ERR, "Could not open PID file");
541                 audit_warn_tmpfile();
542                 return (-1);
543         }
544
545         /* Attempt to lock the pid file; if a lock is present, exit. */
546         fd = fileno(pidfile);
547         if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
548                 syslog(LOG_ERR,
549                     "PID file is locked (is another auditd running?).");
550                 audit_warn_ebusy();
551                 return (-1);
552         }
553
554         pid = getpid();
555         ftruncate(fd, 0);
556         if (fprintf(pidfile, "%u\n", pid) < 0) {
557                 /* Should not start the daemon. */
558                 fail_exit();
559         }
560
561         fflush(pidfile);
562         return (0);
563 }
564
565 #ifdef USE_MACH_IPC
566 /*
567  * Implementation of the auditd_control() MIG simpleroutine.
568  *
569  * React to input from the audit(1) tool.
570  */
571
572 /* ARGSUSED */
573 kern_return_t
574 auditd_control(mach_port_t __unused auditd_port, int trigger)
575 {
576         int err_ret = 0;
577
578         switch (trigger) {
579
580         case AUDIT_TRIGGER_ROTATE_USER:
581                 /*
582                  * Create a new file and swap with the one
583                  * being used in kernel.
584                  */
585                 if (swap_audit_file() == -1)
586                         syslog(LOG_ERR, "Error swapping audit file");
587                 break;
588
589         case AUDIT_TRIGGER_READ_FILE:
590                 if (read_control_file() == -1)
591                         syslog(LOG_ERR, "Error in audit control file");
592                  break;
593
594         case AUDIT_TRIGGER_CLOSE_AND_DIE:
595                 err_ret = close_all();
596                 exit (err_ret);
597                 break;
598
599         default:
600                 break;
601         }
602
603         return (KERN_SUCCESS);
604 }
605 #endif /* USE_MACH_IPC */
606
607 /*
608  * Handle the audit trigger event.
609  *
610  * We suppress (ignore) duplicated triggers in close succession in order to
611  * try to avoid thrashing-like behavior.  However, not all triggers can be
612  * ignored, as triggers generally represent edge triggers, not level
613  * triggers, and won't be retransmitted if the condition persists.  Of
614  * specific concern is the rotate trigger -- if one is dropped, then it will
615  * not be retransmitted, and the log file will grow in an unbounded fashion.
616  */
617 #define DUPLICATE_INTERVAL      30
618 #ifdef USE_MACH_IPC
619 #define AT_SUCCESS      KERN_SUCCESS
620
621 /* ARGSUSED */
622 kern_return_t
623 audit_triggers(mach_port_t __unused audit_port, int trigger)
624 #else
625 #define AT_SUCCESS      0
626
627 static int
628 handle_audit_trigger(int trigger)
629 #endif
630 {
631         static int last_trigger, last_warning;
632         static time_t last_time;
633         struct dir_ent *dirent;
634         struct timeval ts;
635         struct timezone tzp;
636         time_t tt;
637
638         /*
639          * Suppress duplicate messages from the kernel within the specified
640          * interval.
641          */
642         if (gettimeofday(&ts, &tzp) == 0) {
643                 tt = (time_t)ts.tv_sec;
644                 switch (trigger) {
645                 case AUDIT_TRIGGER_LOW_SPACE:
646                 case AUDIT_TRIGGER_NO_SPACE:
647                         /*
648                          * Triggers we can suppress.  Of course, we also need
649                          * to rate limit the warnings, so apply the same
650                          * interval limit on syslog messages.
651                          */
652                         if ((trigger == last_trigger) &&
653                             (tt < (last_time + DUPLICATE_INTERVAL))) {
654                                 if (tt >= (last_warning + DUPLICATE_INTERVAL))
655                                         syslog(LOG_INFO,
656                                             "Suppressing duplicate trigger %d",
657                                             trigger);
658                                 return (AT_SUCCESS);
659                         }
660                         last_warning = tt;
661                         break;
662
663                 case AUDIT_TRIGGER_ROTATE_KERNEL:
664                 case AUDIT_TRIGGER_ROTATE_USER:
665                 case AUDIT_TRIGGER_READ_FILE:
666                         /*
667                          * Triggers that we cannot suppress.
668                          */
669                         break;
670                 }
671
672                 /*
673                  * Only update last_trigger after aborting due to a duplicate
674                  * trigger, not before, or we will never allow that trigger
675                  * again.
676                  */
677                 last_trigger = trigger;
678                 last_time = tt;
679         }
680
681         /*
682          * Message processing is done here.
683          */
684         dirent = TAILQ_FIRST(&dir_q);
685         switch(trigger) {
686         case AUDIT_TRIGGER_LOW_SPACE:
687                 syslog(LOG_INFO, "Got low space trigger");
688                 if (dirent && (dirent->softlim != 1)) {
689                         TAILQ_REMOVE(&dir_q, dirent, dirs);
690                                 /* Add this node to the end of the list. */
691                                 TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
692                                 audit_warn_soft(dirent->dirname);
693                                 dirent->softlim = 1;
694
695                         if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
696                             swap_audit_file() == -1)
697                                 syslog(LOG_ERR, "Error swapping audit file");
698
699                         /*
700                          * Check if the next dir has already reached its soft
701                          * limit.
702                          */
703                         dirent = TAILQ_FIRST(&dir_q);
704                         if (dirent->softlim == 1)  {
705                                 /* All dirs have reached their soft limit. */
706                                 audit_warn_allsoft();
707                         }
708                 } else {
709                         /*
710                          * Continue auditing to the current file.  Also
711                          * generate an allsoft warning.
712                          *
713                          * XXX do we want to do this ?
714                          */
715                         audit_warn_allsoft();
716                 }
717                 break;
718
719         case AUDIT_TRIGGER_NO_SPACE:
720                 syslog(LOG_INFO, "Got no space trigger");
721
722                 /* Delete current dir, go on to next. */
723                 TAILQ_REMOVE(&dir_q, dirent, dirs);
724                 audit_warn_hard(dirent->dirname);
725                 free(dirent->dirname);
726                 free(dirent);
727
728                 if (swap_audit_file() == -1)
729                         syslog(LOG_ERR, "Error swapping audit file");
730
731                 /* We are out of log directories. */
732                 audit_warn_allhard(++allhardcount);
733                 break;
734
735         case AUDIT_TRIGGER_ROTATE_KERNEL:
736         case AUDIT_TRIGGER_ROTATE_USER:
737                 /*
738                  * Create a new file and swap with the one being used in
739                  * kernel
740                  */
741                 syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
742                     AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
743                 if (swap_audit_file() == -1)
744                         syslog(LOG_ERR, "Error swapping audit file");
745                 break;
746
747         case AUDIT_TRIGGER_READ_FILE:
748                 syslog(LOG_INFO, "Got read file trigger");
749                 if (read_control_file() == -1)
750                         syslog(LOG_ERR, "Error in audit control file");
751                 if (config_audit_controls() == -1)
752                         syslog(LOG_ERR, "Error setting audit controls");
753                 break;
754
755         default:
756                 syslog(LOG_ERR, "Got unknown trigger %d", trigger);
757                 break;
758         }
759
760         return (AT_SUCCESS);
761 }
762
763 #undef  AT_SUCCESS
764
765 static void
766 handle_sighup(void)
767 {
768
769         sighups_handled = sighups;
770         config_audit_controls();
771 }
772
773 static int
774 config_audit_host(void)
775 {
776         char hoststr[MAXHOSTNAMELEN];
777         struct sockaddr_in6 *sin6;
778         struct sockaddr_in *sin;
779         struct addrinfo *res;
780         struct auditinfo_addr aia;
781         int error;
782
783         if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
784                 syslog(LOG_WARNING,
785                     "warning: failed to read 'host' param in control file");
786                 /*
787                  * To maintain reverse compatability with older audit_control
788                  * files, simply drop a warning if the host parameter has not
789                  * been set.  However, we will explicitly disable the
790                  * generation of extended audit header by passing in a zeroed
791                  * termid structure.
792                  */
793                 bzero(&aia, sizeof(aia));
794                 aia.ai_termid.at_type = AU_IPv4;
795                 error = auditon(A_SETKAUDIT, &aia, sizeof(aia));
796                 if (error < 0 && errno == ENOSYS)
797                         return (0);
798                 else if (error < 0) {
799                         syslog(LOG_ERR,
800                             "Failed to set audit host info");
801                         return (-1);
802                 }
803                 return (0);
804         }
805         error = getaddrinfo(hoststr, NULL, NULL, &res);
806         if (error) {
807                 syslog(LOG_ERR, "Failed to lookup hostname: %s",  hoststr);
808                 return (-1);
809         }
810         switch (res->ai_family) {
811         case PF_INET6:
812                 sin6 = (struct sockaddr_in6 *) res->ai_addr;
813                 bcopy(&sin6->sin6_addr.s6_addr,
814                     &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
815                 aia.ai_termid.at_type = AU_IPv6;
816                 break;
817         case PF_INET:
818                 sin = (struct sockaddr_in *) res->ai_addr;
819                 bcopy(&sin->sin_addr.s_addr,
820                     &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
821                 aia.ai_termid.at_type = AU_IPv4;
822                 break;
823         default:
824                 syslog(LOG_ERR,
825                     "Un-supported address family in host parameter");
826                 return (-1);
827         }
828         if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) {
829                 syslog(LOG_ERR,
830                     "auditon: failed to set audit host information");
831                 return (-1);
832         }
833         return (0);
834 }
835
836 /*
837  * Reap our children.
838  */
839 static void
840 reap_children(void)
841 {
842         pid_t child;
843         int wstatus;
844
845         while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
846                 if (!wstatus)
847                         continue;
848                 syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
849                     ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
850                     "exited as a result of signal"),
851                     ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
852                     WTERMSIG(wstatus)));
853         }
854 }
855
856 static void
857 handle_sigchld(void)
858 {
859
860         sigchlds_handled = sigchlds;
861         reap_children();
862 }
863
864 /*
865  * Read the control file for triggers/signals and handle appropriately.
866  */
867 #ifdef USE_MACH_IPC
868 #define MAX_MSG_SIZE    4096
869
870 static boolean_t
871 auditd_combined_server(mach_msg_header_t *InHeadP,
872     mach_msg_header_t *OutHeadP)
873 {
874         mach_port_t local_port = InHeadP->msgh_local_port;
875
876         if (local_port == signal_port) {
877                 int signo = InHeadP->msgh_id;
878                 int ret;
879
880                 switch(signo) {
881                 case SIGTERM:
882                         ret = close_all();
883                         exit(ret);
884
885                 case SIGCHLD:
886                         handle_sigchld();
887                         return (TRUE);
888
889                 case SIGHUP:
890                         handle_sighup();
891                         return (TRUE);
892
893                 default:
894                         syslog(LOG_INFO, "Received signal %d", signo);
895                         return (TRUE);
896                 }
897         } else if (local_port == control_port) {
898                 boolean_t result;
899
900                 result = audit_triggers_server(InHeadP, OutHeadP);
901                 if (!result)
902                         result = auditd_control_server(InHeadP, OutHeadP);
903                         return (result);
904         }
905         syslog(LOG_INFO, "Recevied msg on bad port 0x%x.", local_port);
906         return (FALSE);
907 }
908
909 static int
910 wait_for_events(void)
911 {
912         kern_return_t   result;
913
914         result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
915             port_set, MACH_MSG_OPTION_NONE);
916         syslog(LOG_ERR, "abnormal exit\n");
917         return (close_all());
918 }
919
920 #else /* ! USE_MACH_IPC */
921
922 static int
923 wait_for_events(void)
924 {
925         int num;
926         unsigned int trigger;
927
928         for (;;) {
929                 num = read(triggerfd, &trigger, sizeof(trigger));
930                 if ((num == -1) && (errno != EINTR)) {
931                         syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
932                         return (-1);
933                 }
934                 if (sigterms != sigterms_handled) {
935                         syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
936                         break;
937                 }
938                 if (sigchlds != sigchlds_handled)
939                         handle_sigchld();
940                 if (sighups != sighups_handled) {
941                         syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
942                         handle_sighup();
943                 }
944                 if ((num == -1) && (errno == EINTR))
945                         continue;
946                 if (num == 0) {
947                         syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
948                         return (-1);
949                 }
950                 if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
951                         break;
952                 else
953                         (void)handle_audit_trigger(trigger);
954         }
955         return (close_all());
956 }
957 #endif /* ! USE_MACH_IPC */
958
959 /*
960  * Configure the audit controls in the kernel: the event to class mapping,
961  * kernel preselection mask, etc.
962  */
963 static int
964 config_audit_controls(void)
965 {
966         au_event_ent_t ev, *evp;
967         au_evclass_map_t evc_map;
968         au_mask_t aumask;
969         int ctr = 0;
970         char naeventstr[NA_EVENT_STR_SIZE];
971         char polstr[POL_STR_SIZE];
972         long policy;
973         au_fstat_t au_fstat;
974         size_t filesz;
975
976         /*
977          * Process the audit event file, obtaining a class mapping for each
978          * event, and send that mapping into the kernel.
979          *
980          * XXX There's a risk here that the BSM library will return NULL
981          * for an event when it can't properly map it to a class. In that
982          * case, we will not process any events beyond the one that failed,
983          * but should. We need a way to get a count of the events.
984         */
985         ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
986         ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
987         if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
988                 if (ev.ae_name != NULL)
989                         free(ev.ae_name);
990                 syslog(LOG_ERR,
991                     "Memory allocation error when configuring audit controls.");
992                 return (-1);
993         }
994
995         /*
996          * XXXRW: Currently we have no way to remove mappings from the kernel
997          * when they are removed from the file-based mappings.
998          */
999         evp = &ev;
1000         setauevent();
1001         while ((evp = getauevent_r(evp)) != NULL) {
1002                 evc_map.ec_number = evp->ae_number;
1003                 evc_map.ec_class = evp->ae_class;
1004                 if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
1005                     != 0)
1006                         syslog(LOG_ERR,
1007                                 "Failed to register class mapping for event %s",
1008                                  evp->ae_name);
1009                 else
1010                         ctr++;
1011         }
1012         endauevent();
1013         free(ev.ae_name);
1014         free(ev.ae_desc);
1015         if (ctr == 0)
1016                 syslog(LOG_ERR, "No events to class mappings registered.");
1017         else
1018                 syslog(LOG_DEBUG, "Registered %d event to class mappings.",
1019                     ctr);
1020
1021         /*
1022          * Get the non-attributable event string and set the kernel mask from
1023          * that.
1024          */
1025         if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
1026             (getauditflagsbin(naeventstr, &aumask) == 0)) {
1027                 if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
1028                         syslog(LOG_ERR,
1029                             "Failed to register non-attributable event mask.");
1030                 else
1031                         syslog(LOG_DEBUG,
1032                             "Registered non-attributable event mask.");
1033         } else
1034                 syslog(LOG_ERR,
1035                     "Failed to obtain non-attributable event mask.");
1036
1037         /*
1038          * If a policy is configured in audit_control(5), implement the
1039          * policy.  However, if one isn't defined, set AUDIT_CNT to avoid
1040          * leaving the system in a fragile state.
1041          */
1042         if ((getacpol(polstr, POL_STR_SIZE) == 0) &&
1043             (au_strtopol(polstr, &policy) == 0)) {
1044                 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
1045                         syslog(LOG_ERR, "Failed to set audit policy: %m");
1046         } else {
1047                 syslog(LOG_ERR, "Failed to obtain policy flags: %m");
1048                 policy = AUDIT_CNT;
1049                 if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
1050                         syslog(LOG_ERR,
1051                             "Failed to set default audit policy: %m");
1052         }
1053
1054         /*
1055          * Set trail rotation size.
1056          */
1057         if (getacfilesz(&filesz) == 0) {
1058                 bzero(&au_fstat, sizeof(au_fstat));
1059                 au_fstat.af_filesz = filesz;
1060                 if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0)
1061                         syslog(LOG_ERR, "Failed to set filesz: %m");
1062         } else
1063                 syslog(LOG_ERR, "Failed to obtain filesz: %m");
1064
1065         return (config_audit_host());
1066 }
1067
1068 #ifdef USE_MACH_IPC
1069 static void
1070 mach_setup(void)
1071 {
1072         mach_msg_type_name_t poly;
1073
1074         /*
1075          * Allocate a port set
1076          */
1077         if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
1078             &port_set) != KERN_SUCCESS)  {
1079                 syslog(LOG_ERR, "Allocation of port set failed");
1080                 fail_exit();
1081         }
1082
1083         /*
1084          * Allocate a signal reflection port
1085          */
1086         if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
1087             &signal_port) != KERN_SUCCESS ||
1088             mach_port_move_member(mach_task_self(), signal_port, port_set) !=
1089             KERN_SUCCESS)  {
1090                 syslog(LOG_ERR, "Allocation of signal port failed");
1091                 fail_exit();
1092         }
1093
1094         /*
1095          * Allocate a trigger port
1096          */
1097         if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
1098             &control_port) != KERN_SUCCESS ||
1099             mach_port_move_member(mach_task_self(), control_port, port_set)
1100             != KERN_SUCCESS)
1101                 syslog(LOG_ERR, "Allocation of trigger port failed");
1102
1103         /*
1104          * Create a send right on our trigger port.
1105          */
1106         mach_port_extract_right(mach_task_self(), control_port,
1107             MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
1108
1109         /*
1110          * Register the trigger port with the kernel.
1111          */
1112         if (host_set_audit_control_port(mach_host_self(), control_port) != 
1113             KERN_SUCCESS) {
1114                 syslog(LOG_ERR, "Cannot set Mach control port");
1115                 fail_exit();
1116         } else
1117                 syslog(LOG_DEBUG, "Mach control port registered");
1118 }
1119 #endif /* USE_MACH_IPC */
1120
1121 static void
1122 setup(void)
1123 {
1124         struct auditinfo ai;
1125         auditinfo_t auinfo;
1126         int aufd;
1127         token_t *tok;
1128
1129 #ifdef USE_MACH_IPC
1130         mach_setup();
1131 #else
1132         if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
1133                 syslog(LOG_ERR, "Error opening trigger file");
1134                 fail_exit();
1135         }
1136 #endif
1137
1138         /*
1139          * To prevent event feedback cycles and avoid auditd becoming
1140          * stalled if auditing is suspended, auditd and its children run
1141          * without their events being audited.  We allow the uid, tid, and
1142          * mask fields to be implicitly set to zero, but do set the pid.  We
1143          * run this after opening the trigger device to avoid configuring
1144          * audit state without audit present in the system.
1145          *
1146          * XXXRW: Is there more to it than this?
1147          */
1148         bzero(&auinfo, sizeof(auinfo));
1149         auinfo.ai_asid = getpid();
1150         if (setaudit(&auinfo) == -1) {
1151                 syslog(LOG_ERR, "Error setting audit stat");
1152                 fail_exit();
1153         }
1154
1155         TAILQ_INIT(&dir_q);
1156         if (read_control_file() == -1) {
1157                 syslog(LOG_ERR, "Error reading control file");
1158                 fail_exit();
1159         }
1160
1161         /* Generate an audit record. */
1162         if ((aufd = au_open()) == -1)
1163                 syslog(LOG_ERR, "Could not create audit startup event.");
1164         else {
1165                 /*
1166                  * XXXCSJP Perhaps we want more robust audit records for
1167                  * audit start up and shutdown. This might include capturing
1168                  * failures to initialize the audit subsystem?
1169                  */
1170                 bzero(&ai, sizeof(ai));
1171                 if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
1172                     getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
1173                     != NULL)
1174                         au_write(aufd, tok);
1175                 if ((tok = au_to_text("auditd::Audit startup")) != NULL)
1176                         au_write(aufd, tok);
1177                 if ((tok = au_to_return32(0, 0)) != NULL)
1178                         au_write(aufd, tok);
1179                 if (au_close(aufd, 1, AUE_audit_startup) == -1)
1180                         syslog(LOG_ERR,
1181                             "Could not close audit startup event.");
1182         }
1183
1184         if (config_audit_controls() == 0)
1185                 syslog(LOG_INFO, "Audit controls init successful");
1186         else
1187                 syslog(LOG_ERR, "Audit controls init failed");
1188 }
1189
1190 int
1191 main(int argc, char **argv)
1192 {
1193         int ch;
1194         int debug = 0;
1195         int rc, logopts;
1196
1197         while ((ch = getopt(argc, argv, "d")) != -1) {
1198                 switch(ch) {
1199                 case 'd':
1200                         /* Debug option. */
1201                         debug = 1;
1202                         break;
1203
1204                 case '?':
1205                 default:
1206                         (void)fprintf(stderr,
1207                             "usage: auditd [-d] \n");
1208                         exit(1);
1209                 }
1210         }
1211
1212         logopts = LOG_CONS | LOG_PID;
1213         if (debug != 0)
1214                 logopts |= LOG_PERROR;
1215
1216 #ifdef LOG_SECURITY
1217         openlog("auditd", logopts, LOG_SECURITY);
1218 #else
1219         openlog("auditd", logopts, LOG_AUTH);
1220 #endif
1221         syslog(LOG_INFO, "starting...");
1222
1223         if (debug == 0 && daemon(0, 0) == -1) {
1224                 syslog(LOG_ERR, "Failed to daemonize");
1225                 exit(1);
1226         }
1227
1228         if (register_daemon() == -1) {
1229                 syslog(LOG_ERR, "Could not register as daemon");
1230                 exit(1);
1231         }
1232
1233         setup();
1234
1235         rc = wait_for_events();
1236         syslog(LOG_INFO, "auditd exiting.");
1237
1238         exit(rc);
1239 }