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