summaryrefslogtreecommitdiffstats
path: root/contrib/openbsm/bin
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-06-05 10:52:12 +0000
committerrwatson <rwatson@FreeBSD.org>2006-06-05 10:52:12 +0000
commit4c355f6b7d92ffbb9cd7fcc7eca2b6364c3bace7 (patch)
tree32e83e301da59f20a423c5b1cac506030cade870 /contrib/openbsm/bin
parent571f2f563f5e4a509d7a05efe83598055c520854 (diff)
parentf7669e641742373606ef85a4855b7028f5b564a5 (diff)
downloadFreeBSD-src-4c355f6b7d92ffbb9cd7fcc7eca2b6364c3bace7.zip
FreeBSD-src-4c355f6b7d92ffbb9cd7fcc7eca2b6364c3bace7.tar.gz
This commit was generated by cvs2svn to compensate for changes in r159248,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/openbsm/bin')
-rw-r--r--contrib/openbsm/bin/Makefile.am3
-rw-r--r--contrib/openbsm/bin/Makefile.in6
-rw-r--r--contrib/openbsm/bin/auditd/auditd.c182
-rw-r--r--contrib/openbsm/bin/auditfilterd/Makefile.am10
-rw-r--r--contrib/openbsm/bin/auditfilterd/Makefile.in508
-rw-r--r--contrib/openbsm/bin/auditfilterd/auditfilterd.877
-rw-r--r--contrib/openbsm/bin/auditfilterd/auditfilterd.c341
-rw-r--r--contrib/openbsm/bin/auditfilterd/auditfilterd.h79
-rw-r--r--contrib/openbsm/bin/auditfilterd/auditfilterd_conf.c485
-rw-r--r--contrib/openbsm/bin/auditreduce/auditreduce.c7
10 files changed, 1616 insertions, 82 deletions
diff --git a/contrib/openbsm/bin/Makefile.am b/contrib/openbsm/bin/Makefile.am
index 7c2fee2..735c241 100644
--- a/contrib/openbsm/bin/Makefile.am
+++ b/contrib/openbsm/bin/Makefile.am
@@ -1,8 +1,9 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.am#2 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.am#3 $
#
SUBDIRS = \
+ auditfilterd \
auditreduce \
praudit
diff --git a/contrib/openbsm/bin/Makefile.in b/contrib/openbsm/bin/Makefile.in
index e1d7fdd..5646450 100644
--- a/contrib/openbsm/bin/Makefile.in
+++ b/contrib/openbsm/bin/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.in#3 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.in#4 $
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
@@ -62,7 +62,7 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = auditreduce praudit audit auditd
+DIST_SUBDIRS = auditfilterd auditreduce praudit audit auditd
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
@@ -165,7 +165,7 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-SUBDIRS = auditreduce praudit $(am__append_1)
+SUBDIRS = auditfilterd auditreduce praudit $(am__append_1)
all: all-recursive
.SUFFIXES:
diff --git a/contrib/openbsm/bin/auditd/auditd.c b/contrib/openbsm/bin/auditd/auditd.c
index 471f4f6..edfe6c0 100644
--- a/contrib/openbsm/bin/auditd/auditd.c
+++ b/contrib/openbsm/bin/auditd/auditd.c
@@ -30,7 +30,7 @@
*
* @APPLE_BSD_LICENSE_HEADER_END@
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#13 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#16 $
*/
#include <sys/types.h>
@@ -44,6 +44,7 @@
#include <bsm/audit_uevents.h>
#include <bsm/libbsm.h>
+#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
@@ -63,6 +64,7 @@ static int ret, minval;
static char *lastfile = NULL;
static int allhardcount = 0;
static int triggerfd = 0;
+static int sigchlds, sigchlds_handled;
static int sighups, sighups_handled;
static int sigterms, sigterms_handled;
static long global_flags;
@@ -127,7 +129,7 @@ affixdir(char *name, struct dir_ent *dirent)
const char *sep = "/";
curdir = dirent->dirname;
- syslog(LOG_INFO, "dir = %s\n", dirent->dirname);
+ syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
fn = malloc(strlen(curdir) + strlen(sep) + (2 * POSTFIX_LEN) + 1);
if (fn == NULL)
@@ -158,10 +160,10 @@ close_lastfile(char *TS)
*ptr = '.';
strcpy(ptr+1, TS);
if (rename(oldname, lastfile) != 0)
- syslog(LOG_ERR, "Could not rename %s to %s \n",
+ syslog(LOG_ERR, "Could not rename %s to %s",
oldname, lastfile);
else
- syslog(LOG_INFO, "renamed %s to %s \n",
+ syslog(LOG_INFO, "renamed %s to %s",
oldname, lastfile);
}
free(lastfile);
@@ -241,7 +243,7 @@ swap_audit_file(void)
/* Try until we succeed. */
while ((dirent = TAILQ_FIRST(&dir_q))) {
if ((fn = affixdir(timestr, dirent)) == NULL) {
- syslog(LOG_INFO, "Failed to swap log at time %s\n",
+ syslog(LOG_INFO, "Failed to swap log at time %s",
timestr);
return (-1);
}
@@ -250,7 +252,7 @@ swap_audit_file(void)
* Create and open the file; then close and pass to the
* kernel if all went well.
*/
- syslog(LOG_INFO, "New audit file is %s\n", fn);
+ syslog(LOG_INFO, "New audit file is %s", fn);
#ifdef AUDIT_REVIEW_GROUP
fd = open_trail(fn, uid, gid);
#else
@@ -262,7 +264,7 @@ swap_audit_file(void)
error = auditctl(fn);
if (error) {
syslog(LOG_ERR,
- "auditctl failed setting log file! : %s\n",
+ "auditctl failed setting log file! : %s",
strerror(errno));
close(fd);
} else {
@@ -284,7 +286,7 @@ swap_audit_file(void)
free(dirent->dirname);
free(dirent);
}
- syslog(LOG_INFO, "Log directories exhausted\n");
+ syslog(LOG_ERR, "Log directories exhausted\n");
return (-1);
}
@@ -326,7 +328,7 @@ read_control_file(void)
allhardcount = 0;
if (swap_audit_file() == -1) {
- syslog(LOG_ERR, "Could not swap audit file\n");
+ syslog(LOG_ERR, "Could not swap audit file");
/*
* XXX Faulty directory listing? - user should be given
* XXX an opportunity to change the audit_control file
@@ -341,16 +343,16 @@ read_control_file(void)
* XXX is generated here?
*/
if (0 == (ret = getacmin(&minval))) {
- syslog(LOG_INFO, "min free = %d\n", minval);
+ syslog(LOG_DEBUG, "min free = %d\n", minval);
if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
syslog(LOG_ERR,
- "could not get audit queue settings\n");
+ "could not get audit queue settings");
return (-1);
}
qctrl.aq_minfree = minval;
if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
syslog(LOG_ERR,
- "could not set audit queue settings\n");
+ "could not set audit queue settings");
return (-1);
}
}
@@ -372,20 +374,20 @@ close_all(void)
/* Generate an audit record. */
if ((aufd = au_open()) == -1)
- syslog(LOG_ERR, "Could not create audit shutdown event.\n");
+ syslog(LOG_ERR, "Could not create audit shutdown event.");
else {
if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
au_write(aufd, tok);
if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
syslog(LOG_ERR,
- "Could not close audit shutdown event.\n");
+ "Could not close audit shutdown event.");
}
/* Flush contents. */
cond = AUC_DISABLED;
err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
if (err_ret != 0) {
- syslog(LOG_ERR, "Disabling audit failed! : %s\n",
+ syslog(LOG_ERR, "Disabling audit failed! : %s",
strerror(errno));
err_ret = 1;
}
@@ -396,15 +398,15 @@ close_all(void)
free_dir_q();
if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
- syslog(LOG_ERR, "Could not unregister\n");
+ syslog(LOG_ERR, "Could not unregister");
audit_warn_postsigterm();
return (1);
}
endac();
if (close(triggerfd) != 0)
- syslog(LOG_ERR, "Error closing control file\n");
- syslog(LOG_INFO, "Finished.\n");
+ syslog(LOG_ERR, "Error closing control file");
+ syslog(LOG_INFO, "Finished");
return (0);
}
@@ -422,6 +424,8 @@ relay_signal(int signal)
sighups++;
if (signal == SIGTERM)
sigterms++;
+ if (signal == SIGCHLD)
+ sigchlds++;
}
/*
@@ -437,23 +441,22 @@ register_daemon(void)
/* Set up the signal hander. */
if (signal(SIGTERM, relay_signal) == SIG_ERR) {
syslog(LOG_ERR,
- "Could not set signal handler for SIGTERM\n");
+ "Could not set signal handler for SIGTERM");
fail_exit();
}
if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
syslog(LOG_ERR,
- "Could not set signal handler for SIGCHLD\n");
+ "Could not set signal handler for SIGCHLD");
fail_exit();
}
if (signal(SIGHUP, relay_signal) == SIG_ERR) {
syslog(LOG_ERR,
- "Could not set signal handler for SIGHUP\n");
+ "Could not set signal handler for SIGHUP");
fail_exit();
}
if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
- syslog(LOG_ERR,
- "Could not open PID file\n");
+ syslog(LOG_ERR, "Could not open PID file");
audit_warn_tmpfile();
return (-1);
}
@@ -462,7 +465,7 @@ register_daemon(void)
fd = fileno(pidfile);
if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
syslog(LOG_ERR,
- "PID file is locked (is another auditd running?).\n");
+ "PID file is locked (is another auditd running?).");
audit_warn_ebusy();
return (-1);
}
@@ -490,7 +493,6 @@ handle_audit_trigger(int trigger)
static int last_trigger;
static time_t last_time;
struct dir_ent *dirent;
- int rc;
/*
* Suppres duplicate messages from the kernel within the specified
@@ -516,7 +518,7 @@ handle_audit_trigger(int trigger)
switch(trigger) {
case AUDIT_TRIGGER_LOW_SPACE:
- syslog(LOG_INFO, "Got low space trigger\n");
+ syslog(LOG_INFO, "Got low space trigger");
if (dirent && (dirent->softlim != 1)) {
TAILQ_REMOVE(&dir_q, dirent, dirs);
/* Add this node to the end of the list. */
@@ -526,7 +528,7 @@ handle_audit_trigger(int trigger)
if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file\n");
+ syslog(LOG_ERR, "Error swapping audit file");
/*
* Check if the next dir has already reached its soft
@@ -548,7 +550,7 @@ handle_audit_trigger(int trigger)
break;
case AUDIT_TRIGGER_NO_SPACE:
- syslog(LOG_INFO, "Got no space trigger\n");
+ syslog(LOG_INFO, "Got no space trigger");
/* Delete current dir, go on to next. */
TAILQ_REMOVE(&dir_q, dirent, dirs);
@@ -557,7 +559,7 @@ handle_audit_trigger(int trigger)
free(dirent);
if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file\n");
+ syslog(LOG_ERR, "Error swapping audit file");
/* We are out of log directories. */
audit_warn_allhard(++allhardcount);
@@ -568,21 +570,21 @@ handle_audit_trigger(int trigger)
* Create a new file and swap with the one being used in
* kernel
*/
- syslog(LOG_INFO, "Got open new trigger\n");
+ syslog(LOG_INFO, "Got open new trigger");
if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file\n");
+ syslog(LOG_ERR, "Error swapping audit file");
break;
case AUDIT_TRIGGER_READ_FILE:
- syslog(LOG_INFO, "Got read file trigger\n");
+ syslog(LOG_INFO, "Got read file trigger");
if (read_control_file() == -1)
- syslog(LOG_ERR, "Error in audit control file\n");
+ syslog(LOG_ERR, "Error in audit control file");
if (config_audit_controls() == -1)
- syslog(LOG_ERR, "Error setting audit controls\n");
+ syslog(LOG_ERR, "Error setting audit controls");
break;
default:
- syslog(LOG_ERR, "Got unknown trigger %d\n", trigger);
+ syslog(LOG_ERR, "Got unknown trigger %d", trigger);
break;
}
}
@@ -596,10 +598,38 @@ handle_sighup(void)
}
/*
- * Read the control file for triggers and handle appropriately.
+ * Reap our children.
+ */
+static void
+reap_children(void)
+{
+ pid_t child;
+ int wstatus;
+
+ while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
+ if (!wstatus)
+ continue;
+ syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
+ ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
+ "exited as a result of signal"),
+ ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
+ WTERMSIG(wstatus)));
+ }
+}
+
+static void
+handle_sigchld(void)
+{
+
+ sigchlds_handled = sigchlds;
+ reap_children();
+}
+
+/*
+ * Read the control file for triggers/signals and handle appropriately.
*/
static int
-wait_for_triggers(void)
+wait_for_events(void)
{
int num;
unsigned int trigger;
@@ -607,24 +637,28 @@ wait_for_triggers(void)
for (;;) {
num = read(triggerfd, &trigger, sizeof(trigger));
if ((num == -1) && (errno != EINTR)) {
- syslog(LOG_ERR, "%s: error %d\n", __FUNCTION__, errno);
+ syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
return (-1);
}
if (sigterms != sigterms_handled) {
- syslog(LOG_INFO, "%s: SIGTERM", __FUNCTION__);
+ syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
break;
}
+ if (sigchlds != sigchlds_handled) {
+ syslog(LOG_DEBUG, "%s: SIGCHLD", __FUNCTION__);
+ handle_sigchld();
+ }
if (sighups != sighups_handled) {
- syslog(LOG_INFO, "%s: SIGHUP", __FUNCTION__);
+ syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
handle_sighup();
}
if ((num == -1) && (errno == EINTR))
continue;
if (num == 0) {
- syslog(LOG_INFO, "%s: read EOF\n", __FUNCTION__);
+ syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
return (-1);
}
- syslog(LOG_INFO, "%s: read %d\n", __FUNCTION__, trigger);
+ syslog(LOG_DEBUG, "%s: read %d", __FUNCTION__, trigger);
if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
break;
else
@@ -634,26 +668,6 @@ wait_for_triggers(void)
}
/*
- * Reap our children.
- */
-static void
-reap_children(void)
-{
- pid_t child;
- int wstatus;
-
- while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
- if (!wstatus)
- continue;
- syslog(LOG_INFO, "warn process [pid=%d] %s %d.\n", child,
- ((WIFEXITED(wstatus)) ? "exited with non-zero status" :
- "exited as a result of signal"),
- ((WIFEXITED(wstatus)) ? WEXITSTATUS(wstatus) :
- WTERMSIG(wstatus)));
- }
-}
-
-/*
* Configure the audit controls in the kernel: the event to class mapping,
* kernel preselection mask, etc.
*/
@@ -700,7 +714,7 @@ config_audit_controls(void)
if (ctr == 0)
syslog(LOG_ERR, "No events to class mappings registered.");
else
- syslog(LOG_INFO, "Registered %d event to class mappings.",
+ syslog(LOG_DEBUG, "Registered %d event to class mappings.",
ctr);
/*
@@ -713,7 +727,7 @@ config_audit_controls(void)
syslog(LOG_ERR,
"Failed to register non-attributable event mask.");
else
- syslog(LOG_INFO,
+ syslog(LOG_DEBUG,
"Registered non-attributable event mask.");
} else
syslog(LOG_ERR,
@@ -731,35 +745,53 @@ config_audit_controls(void)
static void
setup(void)
{
+ auditinfo_t auinfo;
int aufd;
token_t *tok;
if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
- syslog(LOG_ERR, "Error opening trigger file\n");
+ syslog(LOG_ERR, "Error opening trigger file");
+ fail_exit();
+ }
+
+ /*
+ * To provide event feedback cycles and avoid auditd becoming
+ * stalled if auditing is suspended, auditd and its children run
+ * without their events being audited. We allow the uid, tid, and
+ * mask fields to be implicitly set to zero, but do set the pid. We
+ * run this after opening the trigger device to avoid configuring
+ * audit state without audit present in the system.
+ *
+ * XXXRW: Is there more to it than this?
+ */
+ bzero(&auinfo, sizeof(auinfo));
+ auinfo.ai_asid = getpid();
+ if (setaudit(&auinfo) == -1) {
+ syslog(LOG_ERR, "Error setting audit stat");
fail_exit();
}
TAILQ_INIT(&dir_q);
if (read_control_file() == -1) {
- syslog(LOG_ERR, "Error reading control file\n");
+ syslog(LOG_ERR, "Error reading control file");
fail_exit();
}
/* Generate an audit record. */
if ((aufd = au_open()) == -1)
- syslog(LOG_ERR, "Could not create audit startup event.\n");
+ syslog(LOG_ERR, "Could not create audit startup event.");
else {
if ((tok = au_to_text("auditd::Audit startup")) != NULL)
au_write(aufd, tok);
if (au_close(aufd, 1, AUE_audit_startup) == -1)
syslog(LOG_ERR,
- "Could not close audit startup event.\n");
+ "Could not close audit startup event.");
}
if (config_audit_controls() == 0)
- syslog(LOG_INFO, "Audit controls init successful\n");
+ syslog(LOG_INFO, "Audit controls init successful");
else
- syslog(LOG_INFO, "Audit controls init failed\n");
+ syslog(LOG_ERR, "Audit controls init failed");
}
int
@@ -800,22 +832,22 @@ main(int argc, char **argv)
#else
openlog("auditd", LOG_CONS | LOG_PID, LOG_AUTH);
#endif
- syslog(LOG_INFO, "starting...\n");
+ syslog(LOG_INFO, "starting...");
if (debug == 0 && daemon(0, 0) == -1) {
- syslog(LOG_ERR, "Failed to daemonize\n");
+ syslog(LOG_ERR, "Failed to daemonize");
exit(1);
}
if (register_daemon() == -1) {
- syslog(LOG_ERR, "Could not register as daemon\n");
+ syslog(LOG_ERR, "Could not register as daemon");
exit(1);
}
setup();
- rc = wait_for_triggers();
- syslog(LOG_INFO, "auditd exiting.\n");
+ rc = wait_for_events();
+ syslog(LOG_INFO, "auditd exiting.");
exit(rc);
}
diff --git a/contrib/openbsm/bin/auditfilterd/Makefile.am b/contrib/openbsm/bin/auditfilterd/Makefile.am
new file mode 100644
index 0000000..b8d96a4
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/Makefile.am
@@ -0,0 +1,10 @@
+#
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.am#1 $
+#
+
+INCLUDES = -I$(top_srcdir)
+
+sbin_PROGRAMS = auditfilterd
+auditfilterd_SOURCES = auditfilterd_conf.c auditfilterd.c
+auditfilterd_LDADD = $(top_builddir)/libbsm/libbsm.la
+man8_MANS = auditfilterd.8
diff --git a/contrib/openbsm/bin/auditfilterd/Makefile.in b/contrib/openbsm/bin/auditfilterd/Makefile.in
new file mode 100644
index 0000000..85df641
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/Makefile.in
@@ -0,0 +1,508 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.in#1 $
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = auditfilterd$(EXEEXT)
+subdir = bin/auditfilterd
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(sbin_PROGRAMS)
+am_auditfilterd_OBJECTS = auditfilterd_conf.$(OBJEXT) \
+ auditfilterd.$(OBJEXT)
+auditfilterd_OBJECTS = $(am_auditfilterd_OBJECTS)
+auditfilterd_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/config
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(auditfilterd_SOURCES)
+DIST_SOURCES = $(auditfilterd_SOURCES)
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man8_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+HAVE_AUDIT_SYSCALLS_FALSE = @HAVE_AUDIT_SYSCALLS_FALSE@
+HAVE_AUDIT_SYSCALLS_TRUE = @HAVE_AUDIT_SYSCALLS_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+INCLUDES = -I$(top_srcdir)
+auditfilterd_SOURCES = auditfilterd_conf.c auditfilterd.c
+auditfilterd_LDADD = $(top_builddir)/libbsm/libbsm.la
+man8_MANS = auditfilterd.8
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/auditfilterd/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign bin/auditfilterd/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+ done
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+auditfilterd$(EXEEXT): $(auditfilterd_OBJECTS) $(auditfilterd_DEPENDENCIES)
+ @rm -f auditfilterd$(EXEEXT)
+ $(LINK) $(auditfilterd_LDFLAGS) $(auditfilterd_OBJECTS) $(auditfilterd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditfilterd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditfilterd_conf.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-man8: $(man8_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(mkdir_p) "$(DESTDIR)$(man8dir)"
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-exec-am: install-sbinPROGRAMS
+
+install-info: install-info-am
+
+install-man: install-man8
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-man uninstall-sbinPROGRAMS
+
+uninstall-man: uninstall-man8
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sbinPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-man8 install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-info-am uninstall-man \
+ uninstall-man8 uninstall-sbinPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/contrib/openbsm/bin/auditfilterd/auditfilterd.8 b/contrib/openbsm/bin/auditfilterd/auditfilterd.8
new file mode 100644
index 0000000..0d9d2cb
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/auditfilterd.8
@@ -0,0 +1,77 @@
+.\"-
+.\" Copyright (c) 2006 Robert N. M. Watson
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/auditfilterd.8#2 $
+.\"
+.Dd March 27, 2006
+.Dt AUDITFILTERD 8
+.Os
+.Sh NAME
+.Nm auditfilterd
+.Nd audit filter daemon
+.Sh SYNOPSIS
+.Nm auditfilterd
+.Op Fl d
+.Op Fl c Ar conffile
+.Op Fl t Ar trailfile
+.Sh DESCRIPTION
+The
+.Nm
+daemon is an extensible audit event monitoring daemon, allowing pluggable
+modules to track audit events from a live audit source.
+It is configured using the
+.Xr audit_filter 5
+configuration file.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Starts the daemon in debug mode - it will not daemonize.
+.It Fl c Ar conffile
+Specify an alternative configuration file.
+.It Fl t Ar trailfile
+Specify an alternative source of audit event records.
+.El
+.Sh FILES
+.Bl -tag -width "/etc/security/audit_filterd" -compact
+.It Pa /etc/security/audit_filterd
+Default configuration file for
+.Nm .
+.It Pa /dev/auditpipe
+Default audit record source for
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr audit 8 ,
+.Xr auditd 8
+.Sh AUTHORS
+The
+.Nm
+daemon and audit filter APIs were created by Robert Watson.
+.Sh HISTORY
+The OpenBSM implementation was created by McAfee Research, the security
+division of McAfee Inc., under contract to Apple Computer Inc. in 2004.
+It was subsequently adopted by the TrustedBSD Project as the foundation for
+the OpenBSM distribution.
diff --git a/contrib/openbsm/bin/auditfilterd/auditfilterd.c b/contrib/openbsm/bin/auditfilterd/auditfilterd.c
new file mode 100644
index 0000000..5128af0
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/auditfilterd.c
@@ -0,0 +1,341 @@
+/*-
+ * Copyright (c) 2006 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * This software was developed by Robert Watson for the TrustedBSD Project.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/auditfilterd.c#6 $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <config/config.h>
+#ifdef HAVE_FULL_QUEUE_H
+#include <sys/queue.h>
+#else
+#include <compat/queue.h>
+#endif
+
+#include <bsm/libbsm.h>
+#include <bsm/audit_filter.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "auditfilterd.h"
+
+/*
+ * Global list of registered filters.
+ */
+struct auditfilter_module_list filter_list;
+
+/*
+ * Configuration and signal->main flags.
+ */
+int debug; /* Debugging mode requested, don't detach. */
+int reread_config; /* SIGHUP has been received. */
+int quit; /* SIGQUIT/TERM/INT has been received. */
+
+static void
+usage(void)
+{
+
+ fprintf(stderr, "auditfilterd [-c conffile] [-d] [-p pipefile]"
+ " [-t trailfile]\n");
+ fprintf(stderr, " -c Specify configuration file (default: %s)\n",
+ AUDITFILTERD_CONFFILE);
+ fprintf(stderr, " -d Debugging mode, don't daemonize\n");
+ fprintf(stderr, " -p Specify pipe file (default: %s)\n",
+ AUDITFILTERD_PIPEFILE);
+ fprintf(stderr, " -t Specify audit trail file (default: none)\n");
+ exit(-1);
+}
+
+static void
+auditfilterd_init(void)
+{
+
+ TAILQ_INIT(&filter_list);
+}
+
+static void
+signal_handler(int signum)
+{
+
+ switch (signum) {
+ case SIGHUP:
+ reread_config++;
+ break;
+
+ case SIGINT:
+ case SIGTERM:
+ case SIGQUIT:
+ quit++;
+ break;
+ }
+}
+
+/*
+ * Present raw BSM to a set of registered and interested filters.
+ */
+static void
+present_bsmrecord(struct timespec *ts, u_char *data, u_int len)
+{
+ struct auditfilter_module *am;
+
+ TAILQ_FOREACH(am, &filter_list, am_list) {
+ if (am->am_bsmrecord != NULL)
+ (am->am_bsmrecord)(am->am_instance, ts, data, len);
+ }
+}
+
+/*
+ * Parse the BSM into a set of tokens, which will be pased to registered
+ * and interested filters.
+ */
+#define MAX_TOKENS 128 /* Maximum tokens we handle per record. */
+static void
+present_tokens(struct timespec *ts, u_char *data, u_int len)
+{
+ struct auditfilter_module *am;
+ tokenstr_t tokens[MAX_TOKENS];
+ u_int bytesread;
+ int tokencount;
+
+ tokencount = 0;
+ while (bytesread < len) {
+ if (au_fetch_tok(&tokens[tokencount], data + bytesread,
+ len - bytesread) == -1)
+ break;
+ bytesread += tokens[tokencount].len;
+ tokencount++;
+ }
+
+ TAILQ_FOREACH(am, &filter_list, am_list) {
+ if (am->am_record != NULL)
+ (am->am_record)(am->am_instance, ts, tokencount,
+ tokens);
+ }
+}
+
+/*
+ * The main loop spins pulling records out of the record source and passing
+ * them to modules for processing.
+ */
+static void
+mainloop_file(const char *conffile, const char *trailfile, FILE *trail_fp)
+{
+ struct timespec ts;
+ FILE *conf_fp;
+ u_char *buf;
+ int reclen;
+
+ while (1) {
+ /*
+ * On SIGHUP, we reread the configuration file and reopen
+ * the trail file.
+ */
+ if (reread_config) {
+ reread_config = 0;
+ warnx("rereading configuration");
+ conf_fp = fopen(conffile, "r");
+ if (conf_fp == NULL)
+ err(-1, "%s", conffile);
+ auditfilterd_conf(conffile, conf_fp);
+ fclose(conf_fp);
+
+ fclose(trail_fp);
+ trail_fp = fopen(trailfile, "r");
+ if (trail_fp == NULL)
+ err(-1, "%s", trailfile);
+ }
+ if (quit) {
+ warnx("quitting");
+ break;
+ }
+
+ /*
+ * For now, be relatively unrobust about incomplete records,
+ * but in the future will want to do better. Need to look
+ * more at the right blocking and signal behavior here.
+ */
+ reclen = au_read_rec(trail_fp, &buf);
+ if (reclen == -1)
+ continue;
+ if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
+ err(-1, "clock_gettime");
+ present_bsmrecord(&ts, buf, reclen);
+ present_tokens(&ts, buf, reclen);
+ free(buf);
+ }
+}
+
+/*
+ * The main loop spins pulling records out of the record source and passing
+ * them to modules for processing. This version of the function accepts
+ * discrete record input from a file descriptor, as opposed to buffered input
+ * from a file stream.
+ */
+static void
+mainloop_pipe(const char *conffile, const char *pipefile, int pipe_fd)
+{
+ u_char record[MAX_AUDIT_RECORD_SIZE];
+ struct timespec ts;
+ FILE *conf_fp;
+ int reclen;
+
+ while (1) {
+ /*
+ * On SIGHUP, we reread the configuration file. Unlike with
+ * a trail file, we don't reopen the pipe, as we don't want
+ * to miss records which will be flushed if we do.
+ */
+ if (reread_config) {
+ reread_config = 0;
+ warnx("rereading configuration");
+ conf_fp = fopen(conffile, "r");
+ if (conf_fp == NULL)
+ err(-1, "%s", conffile);
+ auditfilterd_conf(conffile, conf_fp);
+ fclose(conf_fp);
+ }
+ if (quit) {
+ warnx("quitting");
+ break;
+ }
+
+ /*
+ * For now, be relatively unrobust about incomplete records,
+ * but in the future will want to do better. Need to look
+ * more at the right blocking and signal behavior here.
+ */
+ reclen = read(pipe_fd, record, MAX_AUDIT_RECORD_SIZE);
+ if (reclen < 0)
+ continue;
+ if (clock_gettime(CLOCK_REALTIME, &ts) < 0)
+ err(-1, "clock_gettime");
+ present_bsmrecord(&ts, record, reclen);
+ present_tokens(&ts, record, reclen);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *pipefile, *trailfile, *conffile;
+ FILE *trail_fp, *conf_fp;
+ struct stat sb;
+ int pipe_fd;
+ int ch;
+
+ conffile = AUDITFILTERD_CONFFILE;
+ trailfile = NULL;
+ pipefile = NULL;
+ while ((ch = getopt(argc, argv, "c:dp:t:")) != -1) {
+ switch (ch) {
+ case 'c':
+ conffile = optarg;
+ break;
+
+ case 'd':
+ debug++;
+ break;
+
+ case 't':
+ if (trailfile != NULL || pipefile != NULL)
+ usage();
+ trailfile = optarg;
+ break;
+
+ case 'p':
+ if (pipefile != NULL || trailfile != NULL)
+ usage();
+ pipefile = optarg;
+ break;
+
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ /*
+ * We allow only one of a pipe or a trail to be used. If none is
+ * specified, we provide a default pipe path.
+ */
+ if (pipefile == NULL && trailfile == NULL)
+ pipefile = AUDITFILTERD_PIPEFILE;
+
+ if (pipefile != NULL) {
+ pipe_fd = open(pipefile, O_RDONLY);
+ if (pipe_fd < 0)
+ err(-1, "open:%s", pipefile);
+ if (fstat(pipe_fd, &sb) < 0)
+ err(-1, "stat: %s", pipefile);
+ if (!S_ISCHR(sb.st_mode))
+ errx(-1, "fstat: %s not device", pipefile);
+ } else {
+ trail_fp = fopen(trailfile, "r");
+ if (trail_fp == NULL)
+ err(-1, "%s", trailfile);
+ }
+
+ conf_fp = fopen(conffile, "r");
+ if (conf_fp == NULL)
+ err(-1, "%s", conffile);
+
+ auditfilterd_init();
+ if (auditfilterd_conf(conffile, conf_fp) < 0)
+ exit(-1);
+ fclose(conf_fp);
+
+ if (!debug) {
+ if (daemon(0, 0) < 0)
+ err(-1, "daemon");
+ }
+
+ signal(SIGHUP, signal_handler);
+ signal(SIGINT, signal_handler);
+ signal(SIGQUIT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ if (pipefile != NULL)
+ mainloop_pipe(conffile, pipefile, pipe_fd);
+ else
+ mainloop_file(conffile, trailfile, trail_fp);
+
+ auditfilterd_conf_shutdown();
+ return (0);
+}
diff --git a/contrib/openbsm/bin/auditfilterd/auditfilterd.h b/contrib/openbsm/bin/auditfilterd/auditfilterd.h
new file mode 100644
index 0000000..189c21f
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/auditfilterd.h
@@ -0,0 +1,79 @@
+/*-
+ * Copyright (c) 2006 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * This software was developed by Robert Watson for the TrustedBSD Project.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/auditfilterd.h#3 $
+ */
+
+#define AUDITFILTERD_CONFFILE "/etc/security/audit_filter"
+#define AUDITFILTERD_PIPEFILE "/dev/auditpipe"
+
+/*
+ * Limit on the number of arguments that can appear in an audit_filterd
+ * configuration line.
+ */
+#define AUDITFILTERD_CONF_MAXARGS 256
+
+/*
+ * Data structure description each instantiated module.
+ */
+struct auditfilter_module {
+ /*
+ * Fields from configuration file and dynamic linker.
+ */
+ char *am_modulename;
+ char *am_arg_buffer;
+ int am_argc;
+ char **am_argv;
+ void *am_dlhandle;
+
+ /*
+ * Fields provided by or extracted from the module.
+ */
+ void *am_instance;
+ audit_filter_attach_t am_attach;
+ audit_filter_reinit_t am_reinit;
+ audit_filter_record_t am_record;
+ audit_filter_bsmrecord_t am_bsmrecord;
+ audit_filter_detach_t am_detach;
+
+ /*
+ * Fields for maintaining the list of modules.
+ */
+ TAILQ_ENTRY(auditfilter_module) am_list;
+};
+TAILQ_HEAD(auditfilter_module_list, auditfilter_module);
+
+/*
+ * List of currently registered modules.
+ */
+extern struct auditfilter_module_list filter_list;
+
+/*
+ * Function definitions.
+ */
+int auditfilterd_conf(const char *filename, FILE *fp);
+void auditfilterd_conf_shutdown(void);
diff --git a/contrib/openbsm/bin/auditfilterd/auditfilterd_conf.c b/contrib/openbsm/bin/auditfilterd/auditfilterd_conf.c
new file mode 100644
index 0000000..4e1759d
--- /dev/null
+++ b/contrib/openbsm/bin/auditfilterd/auditfilterd_conf.c
@@ -0,0 +1,485 @@
+/*-
+ * Copyright (c) 2006 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * This software was developed by Robert Watson for the TrustedBSD Project.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/auditfilterd_conf.c#3 $
+ */
+
+/*
+ * Configuration file parser for auditfilterd. The configuration file is a
+ * very simple format, similar to other BSM configuration files, consisting
+ * of configuration entries of one line each. The configuration function is
+ * aware of previous runs, and will update the current configuration as
+ * needed.
+ *
+ * Modules are in one of two states: attached, or detached. If attach fails,
+ * detach is not called because it was not attached. If a module is attached
+ * and a call to its reinit method fails, we will detach it.
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+#ifdef HAVE_FULL_QUEUE_H
+#include <sys/queue.h>
+#else
+#include <compat/queue.h>
+#endif
+
+#include <bsm/libbsm.h>
+#include <bsm/audit_filter.h>
+
+#include <dlfcn.h>
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "auditfilterd.h"
+
+/*
+ * Free an individual auditfilter_module structure. Will not shut down the
+ * module, just frees the memory. Does so conditional on pointers being
+ * non-NULL so that it can be used on partially allocated structures.
+ */
+static void
+auditfilter_module_free(struct auditfilter_module *am)
+{
+
+ if (am->am_modulename != NULL)
+ free(am->am_modulename);
+ if (am->am_arg_buffer != NULL)
+ free(am->am_arg_buffer);
+ if (am->am_argv != NULL)
+ free(am->am_argv);
+}
+
+/*
+ * Free all memory associated with an auditfilter_module list. Does not
+ * dlclose() or shut down the modules, just free the memory. Use
+ * auditfilter_module_list_detach() for that, if required.
+ */
+static void
+auditfilter_module_list_free(struct auditfilter_module_list *list)
+{
+ struct auditfilter_module *am;
+
+ while (!(TAILQ_EMPTY(list))) {
+ am = TAILQ_FIRST(list);
+ TAILQ_REMOVE(list, am, am_list);
+ auditfilter_module_free(am);
+ }
+}
+
+/*
+ * Detach an attached module from an auditfilter_module structure. Does not
+ * free the data structure itself.
+ */
+static void
+auditfilter_module_detach(struct auditfilter_module *am)
+{
+
+ if (am->am_detach != NULL)
+ am->am_detach(am->am_instance);
+ am->am_instance = NULL;
+ (void)dlclose(am->am_dlhandle);
+ am->am_dlhandle = NULL;
+}
+
+/*
+ * Walk an auditfilter_module list, detaching each module. Intended to be
+ * combined with auditfilter_module_list_free().
+ */
+static void
+auditfilter_module_list_detach(struct auditfilter_module_list *list)
+{
+ struct auditfilter_module *am;
+
+ TAILQ_FOREACH(am, list, am_list)
+ auditfilter_module_detach(am);
+}
+
+/*
+ * Given a filled out auditfilter_module, use dlopen() and dlsym() to attach
+ * the module. If we fail, leave fields in the state we found them.
+ *
+ * XXXRW: Need a better way to report errors.
+ */
+static int
+auditfilter_module_attach(struct auditfilter_module *am)
+{
+
+ am->am_dlhandle = dlopen(am->am_modulename, RTLD_NOW);
+ if (am->am_dlhandle == NULL) {
+ warnx("auditfilter_module_attach: %s: %s", am->am_modulename,
+ dlerror());
+ return (-1);
+ }
+
+ /*
+ * Not implementing these is not considered a failure condition,
+ * although we might want to consider warning if obvious stuff is
+ * not implemented, such as am_record.
+ */
+ am->am_attach = dlsym(am->am_dlhandle, AUDIT_FILTER_ATTACH_STRING);
+ am->am_reinit = dlsym(am->am_dlhandle, AUDIT_FILTER_REINIT_STRING);
+ am->am_record = dlsym(am->am_dlhandle, AUDIT_FILTER_RECORD_STRING);
+ am->am_bsmrecord = dlsym(am->am_dlhandle,
+ AUDIT_FILTER_BSMRECORD_STRING);
+ am->am_detach = dlsym(am->am_dlhandle, AUDIT_FILTER_DETACH_STRING);
+
+ if (am->am_attach != NULL) {
+ if (am->am_attach(&am->am_instance, am->am_argc, am->am_argv)
+ != AUDIT_FILTER_SUCCESS) {
+ warnx("auditfilter_module_attach: %s: failed",
+ am->am_modulename);
+ dlclose(am->am_dlhandle);
+ am->am_dlhandle = NULL;
+ am->am_attach = NULL;
+ am->am_reinit = NULL;
+ am->am_record = NULL;
+ am->am_bsmrecord = NULL;
+ am->am_detach = NULL;
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+/*
+ * When the arguments for a module are changed, we notify the module through
+ * a call to its reinit method, if any. Return 0 on success, or -1 on
+ * failure.
+ */
+static int
+auditfilter_module_reinit(struct auditfilter_module *am)
+{
+
+ if (am->am_reinit == NULL)
+ return (0);
+
+ if (am->am_reinit(&am->am_instance, am->am_argc, am->am_argv) !=
+ AUDIT_FILTER_SUCCESS) {
+ warnx("auditfilter_module_reinit: %s: failed",
+ am->am_modulename);
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
+ * Given a configuration line, generate an auditfilter_module structure that
+ * describes it; caller will not pass comments in, so they are not looked
+ * for. Do not attempt to instantiate it. Will destroy the contents of
+ * 'buffer'.
+ *
+ * Configuration lines consist of two parts: the module name and arguments
+ * separated by a ':', and then a ','-delimited list of arguments.
+ *
+ * XXXRW: Need to decide where to send the warning output -- stderr for now.
+ */
+struct auditfilter_module *
+auditfilter_module_parse(const char *filename, int linenumber, char *buffer)
+{
+ char *arguments, *module, **ap;
+ struct auditfilter_module *am;
+
+ am = malloc(sizeof(*am));
+ if (am == NULL) {
+ warn("auditfilter_module_parse: %s:%d", filename, linenumber);
+ return (NULL);
+ }
+ bzero(am, sizeof(*am));
+
+ /*
+ * First, break out the module and arguments strings. We look for
+ * one extra argument to make sure there are no more :'s in the line.
+ * That way, we prevent modules from using argument strings that, in
+ * the future, may cause problems for adding additional columns.
+ */
+ arguments = buffer;
+ module = strsep(&arguments, ":");
+ if (module == NULL || arguments == NULL) {
+ warnx("auditfilter_module_parse: %s:%d: parse error",
+ filename, linenumber);
+ return (NULL);
+ }
+
+ am->am_modulename = strdup(module);
+ if (am->am_modulename == NULL) {
+ warn("auditfilter_module_parse: %s:%d", filename, linenumber);
+ auditfilter_module_free(am);
+ return (NULL);
+ }
+
+ am->am_arg_buffer = strdup(buffer);
+ if (am->am_arg_buffer == NULL) {
+ warn("auditfilter_module_parse: %s:%d", filename, linenumber);
+ auditfilter_module_free(am);
+ return (NULL);
+ }
+
+ /*
+ * Now, break out the arguments string into a series of arguments.
+ * This is a bit more complicated, and requires cleanup if things go
+ * wrong.
+ */
+ am->am_argv = malloc(sizeof(char *) * AUDITFILTERD_CONF_MAXARGS);
+ if (am->am_argv == NULL) {
+ warn("auditfilter_module_parse: %s:%d", filename, linenumber);
+ auditfilter_module_free(am);
+ return (NULL);
+ }
+ bzero(am->am_argv, sizeof(char *) * AUDITFILTERD_CONF_MAXARGS);
+ am->am_argc = 0;
+ for (ap = am->am_argv; (*ap = strsep(&arguments, " \t")) != NULL;) {
+ if (**ap != '\0') {
+ am->am_argc++;
+ if (++ap >= &am->am_argv[AUDITFILTERD_CONF_MAXARGS])
+ break;
+ }
+ }
+ if (ap >= &am->am_argv[AUDITFILTERD_CONF_MAXARGS]) {
+ warnx("auditfilter_module_parse: %s:%d: too many arguments",
+ filename, linenumber);
+ auditfilter_module_free(am);
+ return (NULL);
+ }
+
+ return (am);
+}
+
+/*
+ * Read a configuration file, and populate 'list' with the configuration
+ * lines. Does not attempt to instantiate the configuration, just read it
+ * into a useful set of data structures.
+ */
+static int
+auditfilterd_conf_read(const char *filename, FILE *fp,
+ struct auditfilter_module_list *list)
+{
+ int error, linenumber, syntaxerror;
+ struct auditfilter_module *am;
+ char buffer[LINE_MAX];
+
+ syntaxerror = 0;
+ linenumber = 0;
+ while (!feof(fp) && !ferror(fp)) {
+ if (fgets(buffer, LINE_MAX, fp) == NULL)
+ break;
+ linenumber++;
+ if (buffer[0] == '#' || strlen(buffer) < 1)
+ continue;
+ buffer[strlen(buffer)-1] = '\0';
+ am = auditfilter_module_parse(filename, linenumber, buffer);
+ if (am == NULL) {
+ syntaxerror = 1;
+ break;
+ }
+ TAILQ_INSERT_HEAD(list, am, am_list);
+ }
+
+ /*
+ * File I/O error.
+ */
+ if (ferror(fp)) {
+ error = errno;
+ auditfilter_module_list_free(list);
+ errno = error;
+ return (-1);
+ }
+
+ /*
+ * Syntax error.
+ */
+ if (syntaxerror) {
+ auditfilter_module_list_free(list);
+ errno = EINVAL;
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Apply changes necessary to bring a new configuration into force. The new
+ * configuration data is passed in, and the current configuration is updated
+ * to match it. The contents of 'list' are freed or otherwise disposed of
+ * before return.
+ *
+ * The algorithms here are not very efficient, but this is an infrequent
+ * operation on very short lists.
+ */
+static void
+auditfilterd_conf_apply(struct auditfilter_module_list *list)
+{
+ struct auditfilter_module *am1, *am2, *am_tmp;
+ int argc_tmp, found;
+ char **argv_tmp;
+
+ /*
+ * First, remove remove and detach any entries that appear in the
+ * current configuration, but not the new configuration.
+ */
+ TAILQ_FOREACH_SAFE(am1, &filter_list, am_list, am_tmp) {
+ found = 0;
+ TAILQ_FOREACH(am2, list, am_list) {
+ if (strcmp(am1->am_modulename, am2->am_modulename)
+ == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ /*
+ * am1 appears in filter_list, but not the new list, detach
+ * and free the module.
+ */
+ warnx("detaching module %s", am1->am_modulename);
+ TAILQ_REMOVE(&filter_list, am1, am_list);
+ auditfilter_module_detach(am1);
+ auditfilter_module_free(am1);
+ }
+
+ /*
+ * Next, update the configuration of any modules that appear in both
+ * lists. We do this by swapping the two argc and argv values and
+ * freeing the new one, rather than detaching the old one and
+ * attaching the new one. That way module state is preserved.
+ */
+ TAILQ_FOREACH(am1, &filter_list, am_list) {
+ found = 0;
+ TAILQ_FOREACH(am2, list, am_list) {
+ if (strcmp(am1->am_modulename, am2->am_modulename)
+ == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ continue;
+
+ /*
+ * Swap the arguments.
+ */
+ argc_tmp = am1->am_argc;
+ argv_tmp = am1->am_argv;
+ am1->am_argc = am2->am_argc;
+ am1->am_argv = am2->am_argv;
+ am2->am_argc = argc_tmp;
+ am2->am_argv = argv_tmp;
+
+ /*
+ * The reinit is a bit tricky: if reinit fails, we actually
+ * remove the old entry and detach that, as we don't allow
+ * running modules to be out of sync with the configuration
+ * file.
+ */
+ warnx("reiniting module %s", am1->am_modulename);
+ if (auditfilter_module_reinit(am1) != 0) {
+ warnx("reinit failed for module %s, detaching",
+ am1->am_modulename);
+ TAILQ_REMOVE(&filter_list, am1, am_list);
+ auditfilter_module_detach(am1);
+ auditfilter_module_free(am1);
+ }
+
+ /*
+ * Free the entry from the new list, which will discard the
+ * old arguments. No need to detach, as it was never
+ * attached in the first place.
+ */
+ TAILQ_REMOVE(list, am2, am_list);
+ auditfilter_module_free(am2);
+ }
+
+ /*
+ * Finally, attach any new entries that don't appear in the old
+ * configuration, and if they attach successfully, move them to the
+ * real configuration list.
+ */
+ TAILQ_FOREACH(am1, list, am_list) {
+ found = 0;
+ TAILQ_FOREACH(am2, &filter_list, am_list) {
+ if (strcmp(am1->am_modulename, am2->am_modulename)
+ == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (found)
+ continue;
+ /*
+ * Attach the entry. If it succeeds, add to filter_list,
+ * otherwise, free. No need to detach if attach failed.
+ */
+ warnx("attaching module %s", am1->am_modulename);
+ TAILQ_REMOVE(list, am1, am_list);
+ if (auditfilter_module_attach(am1) != 0) {
+ warnx("attaching module %s failed",
+ am1->am_modulename);
+ auditfilter_module_free(am1);
+ } else
+ TAILQ_INSERT_HEAD(&filter_list, am1, am_list);
+ }
+
+ if (TAILQ_FIRST(list) != NULL)
+ warnx("auditfilterd_conf_apply: new list not empty\n");
+}
+
+/*
+ * Read the new configuration file into a local list. If the configuration
+ * file is parsed OK, then apply the changes.
+ */
+int
+auditfilterd_conf(const char *filename, FILE *fp)
+{
+ struct auditfilter_module_list list;
+
+ TAILQ_INIT(&list);
+ if (auditfilterd_conf_read(filename, fp, &list) < 0)
+ return (-1);
+
+ auditfilterd_conf_apply(&list);
+
+ return (0);
+}
+
+/*
+ * Detach and free all active filter modules for daemon shutdown.
+ */
+void
+auditfilterd_conf_shutdown(void)
+{
+
+ auditfilter_module_list_detach(&filter_list);
+ auditfilter_module_list_free(&filter_list);
+}
diff --git a/contrib/openbsm/bin/auditreduce/auditreduce.c b/contrib/openbsm/bin/auditreduce/auditreduce.c
index 63619b7..25a14ff 100644
--- a/contrib/openbsm/bin/auditreduce/auditreduce.c
+++ b/contrib/openbsm/bin/auditreduce/auditreduce.c
@@ -26,7 +26,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#13 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#14 $
*/
/*
@@ -42,11 +42,12 @@
#include <bsm/libbsm.h>
+#include <err.h>
+#include <grp.h>
+#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
-#include <grp.h>
-#include <pwd.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
OpenPOWER on IntegriCloud