From f7669e641742373606ef85a4855b7028f5b564a5 Mon Sep 17 00:00:00 2001 From: rwatson Date: Mon, 5 Jun 2006 10:52:12 +0000 Subject: Vendor branch import of TrustedBSD OpenBSM 1.0 alpha 6: - Use AU_TO_WRITE and AU_NO_TO_WRITE for the 'keep' argument to au_close(); previously we used hard-coded 0 and 1 values. - Add man page for au_open(), au_write(), au_close(), and au_close_buffer(). - Support a more complete range of data types for the arbitrary data token: add AUR_CHAR (alias to AUR_BYTE), remove AUR_LONG, add AUR_INT32 (alias to AUR_INT), add AUR_INT64. - Add au_close_token(), which allows writing a single token_t to a memory buffer. Not likely to be used much by applications, but useful for writing test tools. - Modify au_to_file() so that it accepts a timeval in user space, not just kernel -- this is not a Solaris BSM API so can be modified without causing compatibility issues. - Define a new API, au_to_header32_tm(), which adds a struct timeval argument to the ordinary au_to_header32(), which is now implemented by wrapping au_to_header32_tm() and calling gettimeofday(). #ifndef KERNEL the APIs that invoke gettimeofday(), rather than having a variable definition. Don't try to retrieve time zone information using gettimeofday(), as it's not needed, and introduces possible failure modes. - Don't perform byte order transformations on the addr/machine fields of the terminal ID that appears in the process32/subject32 tokens. These are assumed to be IP addresses, and as such, to be in network byte order. - Universally, APIs now assume that IP addresses and ports are provided in network byte order. APIs now generally provide these types in network byte order when decoding. - Beginnings of an OpenBSM test framework can now be found in openbsm/test. This code is not built or installed by default. - auditd now assigns more appropriate syslog levels to its debugging and error information. - Support for audit filters introduced: audit filters are dynamically loaded shared objects that run in the context of a new daemon, auditfilterd. The daemon reads from an audit pipe and feeds both BSM and parsed versions of records to shared objects using a module API. This will provide a framework for the writing of intrusion detection services. - New utility API, audit_submit(), added to capture common elements of audit record submission for many applications. Obtained from: TrustedBSD Project --- contrib/openbsm/bin/Makefile.am | 3 +- contrib/openbsm/bin/Makefile.in | 6 +- contrib/openbsm/bin/auditd/auditd.c | 182 +++++--- contrib/openbsm/bin/auditfilterd/Makefile.am | 10 + contrib/openbsm/bin/auditfilterd/Makefile.in | 508 +++++++++++++++++++++ contrib/openbsm/bin/auditfilterd/auditfilterd.8 | 77 ++++ contrib/openbsm/bin/auditfilterd/auditfilterd.c | 341 ++++++++++++++ contrib/openbsm/bin/auditfilterd/auditfilterd.h | 79 ++++ .../openbsm/bin/auditfilterd/auditfilterd_conf.c | 485 ++++++++++++++++++++ contrib/openbsm/bin/auditreduce/auditreduce.c | 7 +- 10 files changed, 1616 insertions(+), 82 deletions(-) create mode 100644 contrib/openbsm/bin/auditfilterd/Makefile.am create mode 100644 contrib/openbsm/bin/auditfilterd/Makefile.in create mode 100644 contrib/openbsm/bin/auditfilterd/auditfilterd.8 create mode 100644 contrib/openbsm/bin/auditfilterd/auditfilterd.c create mode 100644 contrib/openbsm/bin/auditfilterd/auditfilterd.h create mode 100644 contrib/openbsm/bin/auditfilterd/auditfilterd_conf.c (limited to 'contrib/openbsm/bin') 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 @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -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 +#include +#include + +#include +#ifdef HAVE_FULL_QUEUE_H +#include +#else +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 + +#include +#ifdef HAVE_FULL_QUEUE_H +#include +#else +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include #include #include #include -#include -#include #include #include #include -- cgit v1.1