summaryrefslogtreecommitdiffstats
path: root/contrib/openbsm/bin
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-12-31 11:12:24 +0000
committerrwatson <rwatson@FreeBSD.org>2008-12-31 11:12:24 +0000
commite52e71cb6e0521b64120ded9c019b22fe96533e8 (patch)
tree1be031d8331a1b0a29a40e1493c5707f3b6ce3e7 /contrib/openbsm/bin
parent21750937a7237874f3b78cae9b4f522d2bf161d4 (diff)
parent0c86a1e4f3fbe31c24bb9609b2df551fd777428b (diff)
downloadFreeBSD-src-e52e71cb6e0521b64120ded9c019b22fe96533e8.zip
FreeBSD-src-e52e71cb6e0521b64120ded9c019b22fe96533e8.tar.gz
Merge OpenBSM alpha 4 from OpenBSM vendor branch to head, both
contrib/openbsm (svn merge) and src/sys/{bsm,security/audit} (manual merge). Add libauditd build parts and add to auditd's linkage; force libbsm to build before libauditd. OpenBSM history for imported revisions below for reference. MFC after: 1 month Sponsored by: Apple Inc. Obtained from: TrustedBSD Project OpenBSM 1.1 alpha 4 - With the addition of BSM error number mapping, we also need to map the local error number passed to audit_submit(3) to a BSM error number, rather than have the caller perform that conversion. - Reallocate user audit events to avoid collisions with Solaris; adopt a more formal allocation scheme, and add some events allocated in Solaris that will be of immediate use on other platforms. - Add an event for Calife. - Add au_strerror(3), which allows generating strings for BSM errors directly, rather than requiring applications to map to the local error space, which might not be able to entirely represent the BSM error number space. - Major auditd rewrite for launchd(8) support. Add libauditd library that is shared between launchd and auditd. - Add AUDIT_TRIGGER_INITIALIZE trigger (sent via 'audit -i') for (re)starting auditing under launchd(8) on Mac OS X. - Add 'current' symlink to active audit trail. - Add crash recovery of previous audit trail file when detected on audit startup that it has not been properly terminated. - Add the event AUE_audit_recovery to indicated when an audit trail file has been recovered from not being properly terminated. This event is stored in the new audit trail file and includes the path of recovered audit trail file. - Mac OS X and FreeBSD dependent code in auditd.c is separated into auditd_darwin.c and auditd_fbsd.c files. - Add an event for the posix_spawn(2) and fsgetpath(2) Mac OS X system calls. - For Mac OS X, we use ASL(3) instead of syslog(3) for logging. - Add support for NOTICE level logging. OpenBSM 1.1 alpha 3 - Add two new functions, au_bsm_to_errno() and au_errno_to_bsm(), to map between BSM error numbers (largely the Solaris definitions) and local errno(2) values for 32-bit and 64-bit return tokens. This is required as operating systems don't agree on some of the values of more recent error numbers. - Fix a bug how au_to_exec_args(3) and au_to_exec_env(3) calculates the total size for the token. This buge. - Deprecated Darwin constants, such as TRAILER_PAD_MAGIC, removed.
Diffstat (limited to 'contrib/openbsm/bin')
-rw-r--r--contrib/openbsm/bin/Makefile.in2
-rw-r--r--contrib/openbsm/bin/audit/Makefile.am10
-rw-r--r--contrib/openbsm/bin/audit/Makefile.in16
-rw-r--r--contrib/openbsm/bin/audit/audit.823
-rw-r--r--contrib/openbsm/bin/audit/audit.c33
-rw-r--r--contrib/openbsm/bin/auditd/Makefile.am18
-rw-r--r--contrib/openbsm/bin/auditd/Makefile.in41
-rw-r--r--contrib/openbsm/bin/auditd/audit_warn.c15
-rw-r--r--contrib/openbsm/bin/auditd/auditd.855
-rw-r--r--contrib/openbsm/bin/auditd/auditd.c1190
-rw-r--r--contrib/openbsm/bin/auditd/auditd.h39
-rw-r--r--contrib/openbsm/bin/auditd/auditd_darwin.c484
-rw-r--r--contrib/openbsm/bin/auditd/auditd_fbsd.c272
-rw-r--r--contrib/openbsm/bin/auditfilterd/Makefile.in2
-rw-r--r--contrib/openbsm/bin/auditreduce/Makefile.in2
-rw-r--r--contrib/openbsm/bin/auditreduce/auditreduce.c4
-rw-r--r--contrib/openbsm/bin/praudit/Makefile.in2
17 files changed, 1298 insertions, 910 deletions
diff --git a/contrib/openbsm/bin/Makefile.in b/contrib/openbsm/bin/Makefile.in
index ddace58..06ef9a7 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#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/Makefile.in#10 $
#
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
diff --git a/contrib/openbsm/bin/audit/Makefile.am b/contrib/openbsm/bin/audit/Makefile.am
index ed62929..1b5d554 100644
--- a/contrib/openbsm/bin/audit/Makefile.am
+++ b/contrib/openbsm/bin/audit/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.am#4 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.am#6 $
#
if USE_NATIVE_INCLUDES
@@ -13,11 +13,11 @@ audit_LDADD = $(top_builddir)/libbsm/libbsm.la
man8_MANS = audit.8
if USE_MACH_IPC
-audit_SOURCES = auditd_control_user.c audit.c
-CLEANFILES = auditd_control_user.c auditd_control_user.h
+audit_SOURCES = auditd_controlUser.c audit.c
+CLEANFILES = auditd_controlUser.c auditd_control.h
-auditd_control_user.c: $(top_srcdir)/bin/auditd/auditd_control.defs
- $(MIG) -user auditd_control_user.c -header auditd_control_user.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
+auditd_controlUser.c auditd_control.h: $(top_srcdir)/bin/auditd/auditd_control.defs
+ $(MIG) -user auditd_controlUser.c -header auditd_control.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
else
audit_SOURCES = audit.c
endif
diff --git a/contrib/openbsm/bin/audit/Makefile.in b/contrib/openbsm/bin/audit/Makefile.in
index edaf018..ae2dd6e 100644
--- a/contrib/openbsm/bin/audit/Makefile.in
+++ b/contrib/openbsm/bin/audit/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/audit/Makefile.in#11 $
#
VPATH = @srcdir@
@@ -49,9 +49,9 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
-am__audit_SOURCES_DIST = audit.c auditd_control_user.c
+am__audit_SOURCES_DIST = audit.c auditd_controlUser.c
@USE_MACH_IPC_FALSE@am_audit_OBJECTS = audit.$(OBJEXT)
-@USE_MACH_IPC_TRUE@am_audit_OBJECTS = auditd_control_user.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@am_audit_OBJECTS = auditd_controlUser.$(OBJEXT) \
@USE_MACH_IPC_TRUE@ audit.$(OBJEXT)
audit_OBJECTS = $(am_audit_OBJECTS)
audit_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la
@@ -188,8 +188,8 @@ top_srcdir = @top_srcdir@
audit_LDADD = $(top_builddir)/libbsm/libbsm.la
man8_MANS = audit.8
@USE_MACH_IPC_FALSE@audit_SOURCES = audit.c
-@USE_MACH_IPC_TRUE@audit_SOURCES = auditd_control_user.c audit.c
-@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_user.c auditd_control_user.h
+@USE_MACH_IPC_TRUE@audit_SOURCES = auditd_controlUser.c audit.c
+@USE_MACH_IPC_TRUE@CLEANFILES = auditd_controlUser.c auditd_control.h
all: all-am
.SUFFIXES:
@@ -262,7 +262,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_control_user.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_controlUser.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -521,8 +521,8 @@ uninstall-man: uninstall-man8
uninstall-sbinPROGRAMS
-@USE_MACH_IPC_TRUE@auditd_control_user.c: $(top_srcdir)/bin/auditd/auditd_control.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user auditd_control_user.c -header auditd_control_user.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@auditd_controlUser.c auditd_control.h: $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user auditd_controlUser.c -header auditd_control.h -server /dev/null -sheader /dev/null $(top_srcdir)/bin/auditd/auditd_control.defs
# 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/audit/audit.8 b/contrib/openbsm/bin/audit/audit.8
index 4aaa494..b0276d4 100644
--- a/contrib/openbsm/bin/audit/audit.8
+++ b/contrib/openbsm/bin/audit/audit.8
@@ -25,9 +25,9 @@
.\" (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/audit/audit.8#11 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.8#13 $
.\"
-.Dd October 2, 2006
+.Dd December 11, 2008
.Dt AUDIT 8
.Os
.Sh NAME
@@ -35,7 +35,7 @@
.Nd audit management utility
.Sh SYNOPSIS
.Nm
-.Fl n | s | t
+.Fl i | n | s | t
.Sh DESCRIPTION
The
.Nm
@@ -43,6 +43,13 @@ utility controls the state of the audit system.
One of the following flags is required as an argument to
.Nm :
.Bl -tag -width indent
+.It Fl i
+Initializes and starts auditing.
+This option is currently for Mac OS X only
+and requires
+.Xr auditd 8
+to be configured to run under
+.Xr launchd 8 .
.It Fl n
Forces the audit system to close the existing audit log file and rotate to
a new log file in a location specified in the audit control file.
@@ -59,6 +66,13 @@ and renamed to indicate the time of the shutdown.
The
.Xr auditd 8
daemon must already be running.
+Optionally, it can be configured to be started
+on-demand by
+.Xr launchd 8
+(Mac OS X only).
+The
+.Nm
+utility requires audit administrator privileges for successful operation.
.Sh FILES
.Bl -tag -width ".Pa /etc/security/audit_control" -compact
.It Pa /etc/security/audit_control
@@ -67,7 +81,8 @@ Audit policy file used to configure the auditing system.
.Sh SEE ALSO
.Xr audit 4 ,
.Xr audit_control 5 ,
-.Xr auditd 8
+.Xr auditd 8 ,
+.Xr launchd 8
.Sh HISTORY
The OpenBSM implementation was created by McAfee Research, the security
division of McAfee Inc., under contract to Apple Computer Inc.\& in 2004.
diff --git a/contrib/openbsm/bin/audit/audit.c b/contrib/openbsm/bin/audit/audit.c
index b1415a6..3a07aa7 100644
--- a/contrib/openbsm/bin/audit/audit.c
+++ b/contrib/openbsm/bin/audit/audit.c
@@ -26,7 +26,7 @@
* (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/audit/audit.c#11 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/audit/audit.c#13 $
*/
/*
* Program to trigger the audit daemon with a message that is either:
@@ -47,6 +47,7 @@
#include <bsm/libbsm.h>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -64,7 +65,15 @@ static int send_trigger(unsigned int);
#include <mach/host_special_ports.h>
#include <servers/bootstrap.h>
-#include "auditd_control_user.h"
+#include "auditd_control.h"
+
+/*
+ * XXX the following is temporary until this can be added to the kernel
+ * audit.h header.
+ */
+#ifndef AUDIT_TRIGGER_INITIALIZE
+#define AUDIT_TRIGGER_INITIALIZE 7
+#endif
static int
send_trigger(unsigned int trigger)
@@ -74,7 +83,12 @@ send_trigger(unsigned int trigger)
error = host_get_audit_control_port(mach_host_self(), &serverPort);
if (error != KERN_SUCCESS) {
- mach_error("Cannot get auditd_control Mach port: ", error);
+ if (geteuid() != 0) {
+ errno = EPERM;
+ perror("audit requires root privileges");
+ } else
+ mach_error("Cannot get auditd_control Mach port:",
+ error);
return (-1);
}
@@ -96,7 +110,10 @@ send_trigger(unsigned int trigger)
error = auditon(A_SENDTRIGGER, &trigger, sizeof(trigger));
if (error != 0) {
- perror("Error sending trigger");
+ if (error == EPERM)
+ perror("audit requires root privileges");
+ else
+ perror("Error sending trigger");
return (-1);
}
@@ -108,7 +125,7 @@ static void
usage(void)
{
- (void)fprintf(stderr, "Usage: audit -n | -s | -t \n");
+ (void)fprintf(stderr, "Usage: audit -i | -n | -s | -t \n");
exit(-1);
}
@@ -124,9 +141,13 @@ main(int argc, char **argv)
if (argc != 2)
usage();
- while ((ch = getopt(argc, argv, "nst")) != -1) {
+ while ((ch = getopt(argc, argv, "inst")) != -1) {
switch(ch) {
+ case 'i':
+ trigger = AUDIT_TRIGGER_INITIALIZE;
+ break;
+
case 'n':
trigger = AUDIT_TRIGGER_ROTATE_USER;
break;
diff --git a/contrib/openbsm/bin/auditd/Makefile.am b/contrib/openbsm/bin/auditd/Makefile.am
index f65b155..2372fa6 100644
--- a/contrib/openbsm/bin/auditd/Makefile.am
+++ b/contrib/openbsm/bin/auditd/Makefile.am
@@ -1,5 +1,5 @@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.am#4 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.am#5 $
#
if USE_NATIVE_INCLUDES
@@ -9,18 +9,18 @@ INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
endif
sbin_PROGRAMS = auditd
-auditd_LDADD = $(top_builddir)/libbsm/libbsm.la
+auditd_LDADD = $(top_builddir)/libbsm/libbsm.la $(top_builddir)/libauditd/libauditd.la
man8_MANS = auditd.8
if USE_MACH_IPC
-auditd_SOURCES = auditd_control_server.c audit_triggers_server.c audit_warn.c auditd.c
-CLEANFILES = auditd_control_server.c auditd_control_server.h audit_triggers_server.c audit_triggers_server.h
+auditd_SOURCES = auditd_controlServer.c audit_triggersServer.c audit_warn.c auditd.c auditd_darwin.c
+CLEANFILES = auditd_control_server.c auditd_controlServer.h audit_triggersServer.c audit_triggersServer.h
-auditd_control_server.c: auditd_control.defs
- $(MIG) -user /dev/null -header /dev/null -server auditd_control_server.c -sheader auditd_control_server.h $(top_srcdir)/bin/auditd/auditd_control.defs
+auditd_controlServer.c auditd_controlServer.h: auditd_control.defs
+ $(MIG) -user /dev/null -header /dev/null -server auditd_controlServer.c -sheader auditd_controlServer.h $(top_srcdir)/bin/auditd/auditd_control.defs
-audit_triggers_server.c: audit_triggers.defs
- $(MIG) -user /dev/null -header /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h $(top_srcdir)/bin/auditd/audit_triggers.defs
+audit_triggersServer.c audit_triggersServer.h: audit_triggers.defs
+ $(MIG) -user /dev/null -header /dev/null -server audit_triggersServer.c -sheader audit_triggersServer.h $(top_srcdir)/bin/auditd/audit_triggers.defs
else
-auditd_SOURCES = audit_warn.c auditd.c
+auditd_SOURCES = audit_warn.c auditd.c auditd_fbsd.c
endif
diff --git a/contrib/openbsm/bin/auditd/Makefile.in b/contrib/openbsm/bin/auditd/Makefile.in
index 731607c..44240d6 100644
--- a/contrib/openbsm/bin/auditd/Makefile.in
+++ b/contrib/openbsm/bin/auditd/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.in#9 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/Makefile.in#10 $
#
VPATH = @srcdir@
@@ -49,16 +49,17 @@ CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(sbin_PROGRAMS)
-am__auditd_SOURCES_DIST = audit_warn.c auditd.c \
- auditd_control_server.c audit_triggers_server.c
+am__auditd_SOURCES_DIST = audit_warn.c auditd.c auditd_fbsd.c \
+ auditd_controlServer.c audit_triggersServer.c auditd_darwin.c
@USE_MACH_IPC_FALSE@am_auditd_OBJECTS = audit_warn.$(OBJEXT) \
-@USE_MACH_IPC_FALSE@ auditd.$(OBJEXT)
-@USE_MACH_IPC_TRUE@am_auditd_OBJECTS = \
-@USE_MACH_IPC_TRUE@ auditd_control_server.$(OBJEXT) \
-@USE_MACH_IPC_TRUE@ audit_triggers_server.$(OBJEXT) \
-@USE_MACH_IPC_TRUE@ audit_warn.$(OBJEXT) auditd.$(OBJEXT)
+@USE_MACH_IPC_FALSE@ auditd.$(OBJEXT) auditd_fbsd.$(OBJEXT)
+@USE_MACH_IPC_TRUE@am_auditd_OBJECTS = auditd_controlServer.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ audit_triggersServer.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ audit_warn.$(OBJEXT) auditd.$(OBJEXT) \
+@USE_MACH_IPC_TRUE@ auditd_darwin.$(OBJEXT)
auditd_OBJECTS = $(am_auditd_OBJECTS)
-auditd_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la
+auditd_DEPENDENCIES = $(top_builddir)/libbsm/libbsm.la \
+ $(top_builddir)/libauditd/libauditd.la
DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
@@ -189,11 +190,11 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
@USE_NATIVE_INCLUDES_FALSE@INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys
@USE_NATIVE_INCLUDES_TRUE@INCLUDES = -I$(top_builddir) -I$(top_srcdir)
-auditd_LDADD = $(top_builddir)/libbsm/libbsm.la
+auditd_LDADD = $(top_builddir)/libbsm/libbsm.la $(top_builddir)/libauditd/libauditd.la
man8_MANS = auditd.8
-@USE_MACH_IPC_FALSE@auditd_SOURCES = audit_warn.c auditd.c
-@USE_MACH_IPC_TRUE@auditd_SOURCES = auditd_control_server.c audit_triggers_server.c audit_warn.c auditd.c
-@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_server.c auditd_control_server.h audit_triggers_server.c audit_triggers_server.h
+@USE_MACH_IPC_FALSE@auditd_SOURCES = audit_warn.c auditd.c auditd_fbsd.c
+@USE_MACH_IPC_TRUE@auditd_SOURCES = auditd_controlServer.c audit_triggersServer.c audit_warn.c auditd.c auditd_darwin.c
+@USE_MACH_IPC_TRUE@CLEANFILES = auditd_control_server.c auditd_controlServer.h audit_triggersServer.c audit_triggersServer.h
all: all-am
.SUFFIXES:
@@ -265,10 +266,12 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_triggers_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_triggersServer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_warn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_control_server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_controlServer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_darwin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_fbsd.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -527,11 +530,11 @@ uninstall-man: uninstall-man8
uninstall-sbinPROGRAMS
-@USE_MACH_IPC_TRUE@auditd_control_server.c: auditd_control.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server auditd_control_server.c -sheader auditd_control_server.h $(top_srcdir)/bin/auditd/auditd_control.defs
+@USE_MACH_IPC_TRUE@auditd_controlServer.c auditd_controlServer.h: auditd_control.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server auditd_controlServer.c -sheader auditd_controlServer.h $(top_srcdir)/bin/auditd/auditd_control.defs
-@USE_MACH_IPC_TRUE@audit_triggers_server.c: audit_triggers.defs
-@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h $(top_srcdir)/bin/auditd/audit_triggers.defs
+@USE_MACH_IPC_TRUE@audit_triggersServer.c audit_triggersServer.h: audit_triggers.defs
+@USE_MACH_IPC_TRUE@ $(MIG) -user /dev/null -header /dev/null -server audit_triggersServer.c -sheader audit_triggersServer.h $(top_srcdir)/bin/auditd/audit_triggers.defs
# 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/auditd/audit_warn.c b/contrib/openbsm/bin/auditd/audit_warn.c
index 7bc7a14..6dfb3bd 100644
--- a/contrib/openbsm/bin/auditd/audit_warn.c
+++ b/contrib/openbsm/bin/auditd/audit_warn.c
@@ -26,7 +26,7 @@
* (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/auditd/audit_warn.c#9 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/audit_warn.c#10 $
*/
#include <sys/types.h>
@@ -71,20 +71,15 @@ auditwarnlog(char *args[])
}
/*
- * Indicates that the hard limit for all filesystems has been exceeded count
- * times.
+ * Indicates that the hard limit for all filesystems has been exceeded.
*/
int
-audit_warn_allhard(int count)
+audit_warn_allhard(void)
{
- char intstr[12];
- char *args[3];
-
- snprintf(intstr, 12, "%d", count);
+ char *args[2];
args[0] = HARDLIM_ALL_WARN;
- args[1] = intstr;
- args[2] = NULL;
+ args[1] = NULL;
return (auditwarnlog(args));
}
diff --git a/contrib/openbsm/bin/auditd/auditd.8 b/contrib/openbsm/bin/auditd/auditd.8
index 199b9cc..49cf9ea 100644
--- a/contrib/openbsm/bin/auditd/auditd.8
+++ b/contrib/openbsm/bin/auditd/auditd.8
@@ -25,9 +25,9 @@
.\" (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/auditd/auditd.8#14 $
+.\" $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.8#16 $
.\"
-.Dd October 2, 2006
+.Dd December 11, 2008
.Dt AUDITD 8
.Os
.Sh NAME
@@ -35,7 +35,7 @@
.Nd audit log management daemon
.Sh SYNOPSIS
.Nm
-.Op Fl d
+.Op Fl d | l
.Sh DESCRIPTION
The
.Nm
@@ -50,7 +50,16 @@ The options are as follows:
.Bl -tag -width indent
.It Fl d
Starts the daemon in debug mode \[em] it will not daemonize.
+.It Fl l
+This option is for when
+.Nm
+is configured to start on-demand using
+.Xr launchd 8 .
.El
+.Pp
+Optionally, the audit review group "audit" may be created.
+Non-privileged
+users that are members of this group may read the audit trail log files.
.Sh NOTE
To assure uninterrupted audit support, the
.Nm
@@ -63,20 +72,33 @@ the
.Pa audit_control
file.
.Pp
-.\" Sending a
-.\" .Dv SIGHUP
-.\" to a running
-.\" .Nm
-.\" daemon will force it to exit.
-Sending a
-.Dv SIGTERM
-to a running
+If
+.Nm
+is started on-demand by
+.Xr launchd 8
+then auditing should only be started and stopped with
+.Xr audit 8 .
+.Pp
+On Mac OS X,
.Nm
-daemon will force it to exit.
+uses the
+.Xr asl 3
+API for writing system log messages.
+Therefore, only the audit administrator
+and members of the audit review group will be able to read the
+system log entries.
.Sh FILES
-.Bl -tag -width ".Pa /var/audit" -compact
+.Bl -tag -width ".Pa /etc/security" -compact
.It Pa /var/audit
Default directory for storing audit log files.
+.Pp
+.It Pa /etc/security
+The directory containing the auditing configuration files
+.Xr audit_class 5 ,
+.Xr audit_control 5 ,
+.Xr audit_event 5 ,
+and
+.Xr audit_warn 5 .
.El
.Sh COMPATIBILITY
The historical
@@ -92,9 +114,14 @@ and
and are no longer available as arguments to
.Nm .
.Sh SEE ALSO
+.Xr asl 3 ,
.Xr audit 4 ,
+.Xr audit_class 5 ,
.Xr audit_control 5 ,
-.Xr audit 8
+.Xr audit_event 5 ,
+.Xr audit_warn 5 ,
+.Xr audit 8 ,
+.Xr launchd 8
.Sh HISTORY
The OpenBSM implementation was created by McAfee Research, the security
division of McAfee Inc., under contract to Apple Computer Inc.\& in 2004.
diff --git a/contrib/openbsm/bin/auditd/auditd.c b/contrib/openbsm/bin/auditd/auditd.c
index e0c03d0..316402a 100644
--- a/contrib/openbsm/bin/auditd/auditd.c
+++ b/contrib/openbsm/bin/auditd/auditd.c
@@ -26,30 +26,29 @@
* (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/auditd/auditd.c#39 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.c#40 $
*/
-#include <sys/param.h>
+#include <sys/types.h>
#include <config/config.h>
#include <sys/dirent.h>
-#include <sys/mman.h>
-#include <sys/socket.h>
#ifdef HAVE_FULL_QUEUE_H
#include <sys/queue.h>
#else /* !HAVE_FULL_QUEUE_H */
#include <compat/queue.h>
#endif /* !HAVE_FULL_QUEUE_H */
+#include <sys/mman.h>
+#include <sys/param.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <bsm/audit.h>
#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
#include <bsm/libbsm.h>
-#include <netinet/in.h>
-
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -60,115 +59,88 @@
#include <unistd.h>
#include <signal.h>
#include <string.h>
-#include <syslog.h>
-#include <netdb.h>
#include "auditd.h"
-#ifdef USE_MACH_IPC
-#include <notify.h>
-#include <mach/port.h>
-#include <mach/mach_error.h>
-#include <mach/mach_traps.h>
-#include <mach/mach.h>
-#include <mach/host_special_ports.h>
-
-#include "auditd_control_server.h"
-#include "audit_triggers_server.h"
-#endif /* USE_MACH_IPC */
#ifndef HAVE_STRLCPY
#include <compat/strlcpy.h>
#endif
-#define NA_EVENT_STR_SIZE 25
-#define POL_STR_SIZE 128
-static int ret, minval;
-static char *lastfile = NULL;
-static int allhardcount = 0;
-static int sigchlds, sigchlds_handled;
-static int sighups, sighups_handled;
-#ifndef USE_MACH_IPC
-static int sigterms, sigterms_handled;
-static int triggerfd = 0;
-
-#else /* USE_MACH_IPC */
-
-static mach_port_t control_port = MACH_PORT_NULL;
-static mach_port_t signal_port = MACH_PORT_NULL;
-static mach_port_t port_set = MACH_PORT_NULL;
-
-#ifndef __BSM_INTERNAL_NOTIFY_KEY
-#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
-#endif /* __BSM_INTERNAL_NOTIFY_KEY */
-#endif /* USE_MACH_IPC */
-
-static TAILQ_HEAD(, dir_ent) dir_q;
-
-static int config_audit_controls(void);
-
/*
- * Error starting auditd
+ * XXX the following is temporary until this can be added to the kernel
+ * audit.h header.
*/
-static void
-fail_exit(void)
-{
+#ifndef AUDIT_TRIGGER_INITIALIZE
+#define AUDIT_TRIGGER_INITIALIZE 7
+#endif
- audit_warn_nostart();
- exit(1);
-}
+/*
+ * LaunchD flag (Mac OS X and, maybe, FreeBSD only.) See launchd(8) and
+ * http://wiki.freebsd.org/launchd for more information.
+ *
+ * In order for auditd to work "on demand" with launchd(8) it can't:
+ * call daemon(3)
+ * call fork and having the parent process exit
+ * change uids or gids.
+ * set up the current working directory or chroot.
+ * set the session id
+ * change stdio to /dev/null.
+ * call setrusage(2)
+ * call setpriority(2)
+ * Ignore SIGTERM.
+ * auditd (in 'launchd mode') is launched on demand so it must catch
+ * SIGTERM to exit cleanly.
+ */
+static int launchd_flag = 0;
/*
- * Free our local list of directory names.
+ * The GID of the audit review group (if used). The audit trail files and
+ * system logs (Mac OS X only) can only be reviewed by members of this group
+ * or the audit administrator (aka. "root").
*/
-static void
-free_dir_q(void)
-{
- struct dir_ent *dirent;
+static gid_t audit_review_gid = -1;
- while ((dirent = TAILQ_FIRST(&dir_q))) {
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
-}
+/*
+ * The path and file name of the last audit trail file.
+ */
+static char *lastfile = NULL;
/*
- * Generate the timestamp string.
+ * Error starting auditd. Run warn script and exit.
*/
-static int
-getTSstr(char *buf, int len)
+static void
+fail_exit(void)
{
- struct timeval ts;
- struct timezone tzp;
- time_t tt;
- if (gettimeofday(&ts, &tzp) != 0)
- return (-1);
- tt = (time_t)ts.tv_sec;
- if (!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt)))
- return (-1);
- return (0);
+ audit_warn_nostart();
+ exit(1);
}
/*
- * Concat the directory name to the given file name.
- * XXX We should affix the hostname also
+ * Follow the 'current' symlink to get the active trail file name.
*/
static char *
-affixdir(char *name, struct dir_ent *dirent)
+get_curfile(void)
{
- char *fn = NULL;
+ char *cf;
+ int len;
- syslog(LOG_DEBUG, "dir = %s", dirent->dirname);
- /*
- * Sanity check on file name.
- */
- if (strlen(name) != (FILENAME_LEN - 1)) {
- syslog(LOG_ERR, "Invalid file name: %s", name);
+ cf = malloc(MAXPATHLEN);
+ if (cf == NULL) {
+ auditd_log_err("malloc failed: %m");
+ return (NULL);
+ }
+
+ len = readlink(AUDIT_CURRENT_LINK, cf, MAXPATHLEN - 1);
+ if (len < 0) {
+ free(cf);
return (NULL);
}
- asprintf(&fn, "%s/%s", dirent->dirname, name);
- return (fn);
+
+ /* readlink() doesn't terminate string. */
+ cf[len] = '\0';
+
+ return (cf);
}
/*
@@ -181,6 +153,10 @@ close_lastfile(char *TS)
char *oldname;
size_t len;
+ /* If lastfile is NULL try to get it from the 'current' link. */
+ if (lastfile == NULL)
+ lastfile = get_curfile();
+
if (lastfile != NULL) {
len = strlen(lastfile) + 1;
oldname = (char *)malloc(len);
@@ -192,16 +168,21 @@ close_lastfile(char *TS)
if ((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
strlcpy(ptr, TS, TIMESTAMP_LEN);
if (rename(oldname, lastfile) != 0)
- syslog(LOG_ERR,
+ auditd_log_err(
"Could not rename %s to %s: %m", oldname,
lastfile);
else {
- syslog(LOG_INFO, "renamed %s to %s",
+ /*
+ * Remove the 'current' symlink since the link
+ * is now invalid.
+ */
+ (void) unlink(AUDIT_CURRENT_LINK);
+ auditd_log_notice( "renamed %s to %s",
oldname, lastfile);
audit_warn_closefile(lastfile);
}
} else
- syslog(LOG_ERR, "Could not rename %s to %s", oldname,
+ auditd_log_err( "Could not rename %s to %s", oldname,
lastfile);
free(lastfile);
free(oldname);
@@ -211,168 +192,81 @@ close_lastfile(char *TS)
}
/*
- * Create the new audit file with appropriate permissions and ownership. Try
- * to clean up if something goes wrong.
- */
-static int
-#ifdef AUDIT_REVIEW_GROUP
-open_trail(const char *fname, uid_t uid, gid_t gid)
-#else
-open_trail(const char *fname)
-#endif
-{
- int error, fd;
-
- fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP);
- if (fd < 0)
- return (-1);
-#ifdef AUDIT_REVIEW_GROUP
- if (fchown(fd, uid, gid) < 0) {
- error = errno;
- close(fd);
- (void)unlink(fname);
- errno = error;
- return (-1);
- }
-#endif
- return (fd);
-}
-
-/*
* Create the new file name, swap with existing audit file.
*/
static int
swap_audit_file(void)
{
- char timestr[FILENAME_LEN];
- char *fn;
+ int err;
+ char *newfile;
char TS[TIMESTAMP_LEN];
- struct dir_ent *dirent;
-#ifdef AUDIT_REVIEW_GROUP
- struct group *grp;
- gid_t gid;
- uid_t uid;
-#endif
- int error, fd;
+ time_t tt;
- if (getTSstr(TS, TIMESTAMP_LEN) != 0)
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0)
return (-1);
+ err = auditd_swap_trail(TS, &newfile, audit_review_gid,
+ audit_warn_getacdir);
+ if (err != ADE_NOERR) {
+ auditd_log_err( "%s: %m", auditd_strerror(err));
+ if (err != ADE_ACTL)
+ return (-1);
+ }
- snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED);
-
-#ifdef AUDIT_REVIEW_GROUP
/*
- * XXXRW: Currently, this code falls back to the daemon gid, which is
- * likely the wheel group. Is there a better way to deal with this?
+ * Only close the last file if were in an auditing state before
+ * calling swap_audit_file(). We may need to recover from a crash.
*/
- grp = getgrnam(AUDIT_REVIEW_GROUP);
- if (grp == NULL) {
- syslog(LOG_INFO,
- "Audit review group '%s' not available, using daemon gid",
- AUDIT_REVIEW_GROUP);
- gid = -1;
- } else
- gid = grp->gr_gid;
- uid = getuid();
-#endif
+ if (auditd_get_state() == AUD_STATE_ENABLED)
+ close_lastfile(TS);
- /* 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",
- timestr);
- return (-1);
- }
- /*
- * Create and open the file; then close and pass to the
- * kernel if all went well.
- */
- syslog(LOG_INFO, "New audit file is %s", fn);
-#ifdef AUDIT_REVIEW_GROUP
- fd = open_trail(fn, uid, gid);
-#else
- fd = open_trail(fn);
-#endif
- if (fd < 0)
- warn("open(%s)", fn);
- if (fd >= 0) {
- error = auditctl(fn);
- if (error) {
- syslog(LOG_ERR,
- "auditctl failed setting log file! : %s",
- strerror(errno));
- close(fd);
- } else {
- /* Success. */
-#ifdef USE_MACH_IPC
- /*
- * auditctl() potentially changes the audit
- * state so post that the audit config (may
- * have) changed.
- */
- notify_post(__BSM_INTERNAL_NOTIFY_KEY);
-#endif
- close_lastfile(TS);
- lastfile = fn;
- close(fd);
- return (0);
- }
- }
+ /*
+ * auditd_swap_trail() potentially enables auditing (if not already
+ * enabled) so updated the cached state as well.
+ */
+ auditd_set_state(AUD_STATE_ENABLED);
+
+ /*
+ * Create 'current' symlink. Recover from crash, if needed.
+ */
+ if (auditd_new_curlink(newfile) != 0)
+ auditd_log_err("auditd_new_curlink(\"%s\") failed: %s: %m",
+ newfile, auditd_strerror(err));
- /*
- * Tell the administrator about lack of permissions for dir.
- */
- audit_warn_getacdir(dirent->dirname);
+ lastfile = newfile;
+ auditd_log_notice("New audit file is %s", newfile);
- /* Try again with a different directory. */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- free(dirent->dirname);
- free(dirent);
- }
- syslog(LOG_ERR, "Log directories exhausted");
- return (-1);
+ return (0);
}
/*
- * Read the audit_control file contents.
+ * Create a new audit log trail file and swap with the current one, if any.
*/
static int
-read_control_file(void)
+do_trail_file(void)
{
- char cur_dir[MAXNAMLEN];
- struct dir_ent *dirent;
- au_qctrl_t qctrl;
+ int err;
/*
- * Clear old values. Force a re-read of the file the next time.
+ * First, refresh the list of audit log directories.
*/
- free_dir_q();
- endac();
-
- /*
- * Read the list of directories into a local linked list.
- *
- * XXX We should use the reentrant interfaces once they are
- * available.
- */
- while (getacdir(cur_dir, MAXNAMLEN) >= 0) {
- dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent));
- if (dirent == NULL)
- return (-1);
- dirent->softlim = 0;
- dirent->dirname = (char *) malloc(MAXNAMLEN);
- if (dirent->dirname == NULL) {
- free(dirent);
+ err = auditd_read_dirs(audit_warn_soft, audit_warn_hard);
+ if (err) {
+ auditd_log_err("auditd_read_dirs() %s: %m",
+ auditd_strerror(err));
+ if (err == ADE_HARDLIM)
+ audit_warn_allhard();
+ if (err != ADE_SOFTLIM)
return (-1);
- }
- strlcpy(dirent->dirname, cur_dir, MAXNAMLEN);
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
+ else
+ audit_warn_allsoft();
+ /* continue on with soft limit error */
}
- allhardcount = 0;
+ /*
+ * Create a new file and swap with the one being used in kernel.
+ */
if (swap_audit_file() == -1) {
- 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
@@ -381,26 +275,54 @@ read_control_file(void)
return (-1);
}
- /*
- * XXX There are synchronization problems here
- * XXX what should we do if a trigger for the earlier limit
- * XXX is generated here?
- */
- if (0 == (ret = getacmin(&minval))) {
- syslog(LOG_DEBUG, "min free = %d", minval);
- if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
- syslog(LOG_ERR,
- "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");
- return (-1);
- }
+ return (0);
+}
+
+/*
+ * Start up auditing.
+ */
+static void
+audit_setup(void)
+{
+ int err;
+
+ if (do_trail_file() == -1) {
+ auditd_log_err("Error creating audit trail file");
+ fail_exit();
}
+ /* Generate an audit record. */
+ err = auditd_gen_record(AUE_audit_startup, NULL);
+ if (err)
+ auditd_log_err("auditd_gen_record(AUE_audit_startup) %s: %m",
+ auditd_strerror(err));
+
+ if (auditd_config_controls() == 0)
+ auditd_log_info("Audit controls init successful");
+ else
+ auditd_log_err("Audit controls init failed");
+
+}
+
+
+/*
+ * Close auditd pid file and trigger mechanism.
+ */
+static int
+close_misc(void)
+{
+
+ auditd_close_dirs();
+ if (unlink(AUDITD_PIDFILE) == -1 && errno != ENOENT) {
+ auditd_log_err("Couldn't remove %s: %m", AUDITD_PIDFILE);
+ return (1);
+ }
+ endac();
+
+ if (auditd_close_trigger() != 0) {
+ auditd_log_err("Error closing trigger messaging mechanism");
+ return (1);
+ }
return (0);
}
@@ -410,107 +332,48 @@ read_control_file(void)
static int
close_all(void)
{
- struct auditinfo ai;
int err_ret = 0;
char TS[TIMESTAMP_LEN];
- int aufd;
- token_t *tok;
+ int err;
long cond;
+ time_t tt;
- /* Generate an audit record. */
- if ((aufd = au_open()) == -1)
- syslog(LOG_ERR, "Could not create audit shutdown event.");
- else {
- if ((tok = au_to_text("auditd::Audit shutdown")) != NULL)
- au_write(aufd, tok);
- /*
- * XXX we need to implement extended subject tokens so we can
- * effectively represent terminal lines with this token type.
- */
- bzero(&ai, sizeof(ai));
- if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
- getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
- != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_return32(0, 0)) != NULL)
- au_write(aufd, tok);
- if (au_close(aufd, 1, AUE_audit_shutdown) == -1)
- syslog(LOG_ERR,
- "Could not close audit shutdown event.");
- }
+ err = auditd_gen_record(AUE_audit_shutdown, NULL);
+ if (err)
+ auditd_log_err("auditd_gen_record(AUE_audit_shutdown) %s: %m",
+ auditd_strerror(err));
/* Flush contents. */
cond = AUC_DISABLED;
err_ret = auditon(A_SETCOND, &cond, sizeof(cond));
if (err_ret != 0) {
- syslog(LOG_ERR, "Disabling audit failed! : %s",
- strerror(errno));
+ auditd_log_err("Disabling audit failed! : %s", strerror(errno));
err_ret = 1;
}
-#ifdef USE_MACH_IPC
- /*
- * Post a notification that the audit config changed.
+
+ /*
+ * Updated the cached state that auditing has been disabled.
*/
- notify_post(__BSM_INTERNAL_NOTIFY_KEY);
-#endif
- if (getTSstr(TS, TIMESTAMP_LEN) == 0)
+ auditd_set_state(AUD_STATE_DISABLED);
+
+ if (getTSstr(tt, TS, TIMESTAMP_LEN) == 0)
close_lastfile(TS);
if (lastfile != NULL)
free(lastfile);
- free_dir_q();
- if ((remove(AUDITD_PIDFILE) == -1) || err_ret) {
- syslog(LOG_ERR, "Could not unregister");
+ err_ret += close_misc();
+
+ if (err_ret) {
+ auditd_log_err("Could not unregister");
audit_warn_postsigterm();
- return (1);
}
- endac();
-#ifndef USE_MACH_IPC
- if (close(triggerfd) != 0)
- syslog(LOG_ERR, "Error closing control file");
-#endif
- syslog(LOG_INFO, "Finished");
- return (0);
+ auditd_log_info("Finished");
+ return (err_ret);
}
/*
- * When we get a signal, we are often not at a clean point. So, little can
- * be done in the signal handler itself. Instead, we send a message to the
- * main servicing loop to do proper handling from a non-signal-handler
- * context.
- */
-#ifdef USE_MACH_IPC
-static void
-relay_signal(int signal)
-{
- mach_msg_empty_send_t msg;
-
- msg.header.msgh_id = signal;
- msg.header.msgh_remote_port = signal_port;
- msg.header.msgh_local_port = MACH_PORT_NULL;
- msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
- mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
- 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-}
-
-#else /* ! USE_MACH_IPC */
-
-static void
-relay_signal(int signal)
-{
-
- if (signal == SIGHUP)
- sighups++;
- if (signal == SIGTERM)
- sigterms++;
- if (signal == SIGCHLD)
- sigchlds++;
-}
-#endif /* ! USE_MACH_IPC */
-
-/*
- * Registering the daemon.
+ * Register the daemon with the signal handler and the auditd pid file.
*/
static int
register_daemon(void)
@@ -520,24 +383,29 @@ register_daemon(void)
pid_t pid;
/* Set up the signal hander. */
- if (signal(SIGTERM, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGTERM, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGTERM");
fail_exit();
}
- if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGCHLD, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGCHLD");
fail_exit();
}
- if (signal(SIGHUP, relay_signal) == SIG_ERR) {
- syslog(LOG_ERR,
+ if (signal(SIGHUP, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
"Could not set signal handler for SIGHUP");
fail_exit();
}
+ if (signal(SIGALRM, auditd_relay_signal) == SIG_ERR) {
+ auditd_log_err(
+ "Could not set signal handler for SIGALRM");
+ fail_exit();
+ }
if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
- syslog(LOG_ERR, "Could not open PID file");
+ auditd_log_err("Could not open PID file");
audit_warn_tmpfile();
return (-1);
}
@@ -545,7 +413,7 @@ register_daemon(void)
/* Attempt to lock the pid file; if a lock is present, exit. */
fd = fileno(pidfile);
if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
- syslog(LOG_ERR,
+ auditd_log_err(
"PID file is locked (is another auditd running?).");
audit_warn_ebusy();
return (-1);
@@ -562,48 +430,6 @@ register_daemon(void)
return (0);
}
-#ifdef USE_MACH_IPC
-/*
- * Implementation of the auditd_control() MIG simpleroutine.
- *
- * React to input from the audit(1) tool.
- */
-
-/* ARGSUSED */
-kern_return_t
-auditd_control(mach_port_t __unused auditd_port, int trigger)
-{
- int err_ret = 0;
-
- switch (trigger) {
-
- case AUDIT_TRIGGER_ROTATE_USER:
- /*
- * Create a new file and swap with the one
- * being used in kernel.
- */
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
- break;
-
- case AUDIT_TRIGGER_READ_FILE:
- if (read_control_file() == -1)
- syslog(LOG_ERR, "Error in audit control file");
- break;
-
- case AUDIT_TRIGGER_CLOSE_AND_DIE:
- err_ret = close_all();
- exit (err_ret);
- break;
-
- default:
- break;
- }
-
- return (KERN_SUCCESS);
-}
-#endif /* USE_MACH_IPC */
-
/*
* Handle the audit trigger event.
*
@@ -615,25 +441,16 @@ auditd_control(mach_port_t __unused auditd_port, int trigger)
* not be retransmitted, and the log file will grow in an unbounded fashion.
*/
#define DUPLICATE_INTERVAL 30
-#ifdef USE_MACH_IPC
-#define AT_SUCCESS KERN_SUCCESS
-
-/* ARGSUSED */
-kern_return_t
-audit_triggers(mach_port_t __unused audit_port, int trigger)
-#else
-#define AT_SUCCESS 0
-
-static int
-handle_audit_trigger(int trigger)
-#endif
+void
+auditd_handle_trigger(int trigger)
{
static int last_trigger, last_warning;
static time_t last_time;
- struct dir_ent *dirent;
struct timeval ts;
struct timezone tzp;
time_t tt;
+ int au_state;
+ int err = 0;
/*
* Suppress duplicate messages from the kernel within the specified
@@ -652,10 +469,10 @@ handle_audit_trigger(int trigger)
if ((trigger == last_trigger) &&
(tt < (last_time + DUPLICATE_INTERVAL))) {
if (tt >= (last_warning + DUPLICATE_INTERVAL))
- syslog(LOG_INFO,
+ auditd_log_info(
"Suppressing duplicate trigger %d",
trigger);
- return (AT_SUCCESS);
+ return;
}
last_warning = tt;
break;
@@ -663,6 +480,8 @@ handle_audit_trigger(int trigger)
case AUDIT_TRIGGER_ROTATE_KERNEL:
case AUDIT_TRIGGER_ROTATE_USER:
case AUDIT_TRIGGER_READ_FILE:
+ case AUDIT_TRIGGER_CLOSE_AND_DIE:
+ case AUDIT_TRIGGER_INITIALIZE:
/*
* Triggers that we cannot suppress.
*/
@@ -678,166 +497,70 @@ handle_audit_trigger(int trigger)
last_time = tt;
}
+ au_state = auditd_get_state();
+
/*
* Message processing is done here.
*/
- dirent = TAILQ_FIRST(&dir_q);
switch(trigger) {
case AUDIT_TRIGGER_LOW_SPACE:
- 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. */
- TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
- audit_warn_soft(dirent->dirname);
- dirent->softlim = 1;
-
- if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL &&
- swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
-
- /*
- * Check if the next dir has already reached its soft
- * limit.
- */
- dirent = TAILQ_FIRST(&dir_q);
- if (dirent->softlim == 1) {
- /* All dirs have reached their soft limit. */
- audit_warn_allsoft();
- }
- } else {
- /*
- * Continue auditing to the current file. Also
- * generate an allsoft warning.
- *
- * XXX do we want to do this ?
- */
- audit_warn_allsoft();
- }
+ auditd_log_notice("Got low space trigger");
+ if (do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_NO_SPACE:
- syslog(LOG_INFO, "Got no space trigger");
-
- /* Delete current dir, go on to next. */
- TAILQ_REMOVE(&dir_q, dirent, dirs);
- audit_warn_hard(dirent->dirname);
- free(dirent->dirname);
- free(dirent);
-
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
-
- /* We are out of log directories. */
- audit_warn_allhard(++allhardcount);
+ auditd_log_notice("Got no space trigger");
+ if (do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_ROTATE_KERNEL:
case AUDIT_TRIGGER_ROTATE_USER:
- /*
- * Create a new file and swap with the one being used in
- * kernel
- */
- syslog(LOG_INFO, "Got open new trigger from %s", trigger ==
+ auditd_log_info("Got open new trigger from %s", trigger ==
AUDIT_TRIGGER_ROTATE_KERNEL ? "kernel" : "user");
- if (swap_audit_file() == -1)
- syslog(LOG_ERR, "Error swapping audit file");
+ if (au_state == AUD_STATE_ENABLED && do_trail_file() == -1)
+ auditd_log_err("Error swapping audit file");
break;
case AUDIT_TRIGGER_READ_FILE:
- syslog(LOG_INFO, "Got read file trigger");
- if (read_control_file() == -1)
- syslog(LOG_ERR, "Error in audit control file");
- if (config_audit_controls() == -1)
- syslog(LOG_ERR, "Error setting audit controls");
- break;
-
- default:
- syslog(LOG_ERR, "Got unknown trigger %d", trigger);
+ auditd_log_info("Got read file trigger");
+ if (au_state == AUD_STATE_ENABLED &&
+ auditd_config_controls() == -1)
+ auditd_log_err("Error setting audit controls");
break;
- }
-
- return (AT_SUCCESS);
-}
-#undef AT_SUCCESS
-
-static void
-handle_sighup(void)
-{
-
- sighups_handled = sighups;
- config_audit_controls();
-}
-
-static int
-config_audit_host(void)
-{
- char hoststr[MAXHOSTNAMELEN];
- struct sockaddr_in6 *sin6;
- struct sockaddr_in *sin;
- struct addrinfo *res;
- struct auditinfo_addr aia;
- int error;
-
- if (getachost(hoststr, MAXHOSTNAMELEN) != 0) {
- syslog(LOG_WARNING,
- "warning: failed to read 'host' param in control file");
+ case AUDIT_TRIGGER_CLOSE_AND_DIE:
+ auditd_log_info("Got close and die trigger");
+ if (au_state == AUD_STATE_ENABLED)
+ err = close_all();
/*
- * To maintain reverse compatability with older audit_control
- * files, simply drop a warning if the host parameter has not
- * been set. However, we will explicitly disable the
- * generation of extended audit header by passing in a zeroed
- * termid structure.
+ * Running under launchd don't exit. Wait for launchd to
+ * send SIGTERM.
*/
- bzero(&aia, sizeof(aia));
- aia.ai_termid.at_type = AU_IPv4;
- error = auditon(A_SETKAUDIT, &aia, sizeof(aia));
- if (error < 0 && errno == ENOSYS)
- return (0);
- else if (error < 0) {
- syslog(LOG_ERR,
- "Failed to set audit host info");
- return (-1);
+ if (!launchd_flag) {
+ auditd_log_info("auditd exiting.");
+ exit (err);
}
- return (0);
- }
- error = getaddrinfo(hoststr, NULL, NULL, &res);
- if (error) {
- syslog(LOG_ERR, "Failed to lookup hostname: %s", hoststr);
- return (-1);
- }
- switch (res->ai_family) {
- case PF_INET6:
- sin6 = (struct sockaddr_in6 *) res->ai_addr;
- bcopy(&sin6->sin6_addr.s6_addr,
- &aia.ai_termid.at_addr[0], sizeof(struct in6_addr));
- aia.ai_termid.at_type = AU_IPv6;
break;
- case PF_INET:
- sin = (struct sockaddr_in *) res->ai_addr;
- bcopy(&sin->sin_addr.s_addr,
- &aia.ai_termid.at_addr[0], sizeof(struct in_addr));
- aia.ai_termid.at_type = AU_IPv4;
+
+ case AUDIT_TRIGGER_INITIALIZE:
+ auditd_log_info("Got audit initialize trigger");
+ if (au_state == AUD_STATE_DISABLED)
+ audit_setup();
break;
+
default:
- syslog(LOG_ERR,
- "Un-supported address family in host parameter");
- return (-1);
- }
- if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) {
- syslog(LOG_ERR,
- "auditon: failed to set audit host information");
- return (-1);
+ auditd_log_err("Got unknown trigger %d", trigger);
+ break;
}
- return (0);
}
/*
* Reap our children.
*/
-static void
-reap_children(void)
+void
+auditd_reap_children(void)
{
pid_t child;
int wstatus;
@@ -845,7 +568,7 @@ reap_children(void)
while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
if (!wstatus)
continue;
- syslog(LOG_INFO, "warn process [pid=%d] %s %d.", child,
+ auditd_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) :
@@ -853,287 +576,121 @@ reap_children(void)
}
}
-static void
-handle_sigchld(void)
-{
-
- sigchlds_handled = sigchlds;
- reap_children();
-}
-
/*
- * Read the control file for triggers/signals and handle appropriately.
+ * Reap any children and terminate. If under launchd don't shutdown auditing
+ * but just the other stuff.
*/
-#ifdef USE_MACH_IPC
-#define MAX_MSG_SIZE 4096
-
-static boolean_t
-auditd_combined_server(mach_msg_header_t *InHeadP,
- mach_msg_header_t *OutHeadP)
-{
- mach_port_t local_port = InHeadP->msgh_local_port;
-
- if (local_port == signal_port) {
- int signo = InHeadP->msgh_id;
- int ret;
-
- switch(signo) {
- case SIGTERM:
- ret = close_all();
- exit(ret);
-
- case SIGCHLD:
- handle_sigchld();
- return (TRUE);
-
- case SIGHUP:
- handle_sighup();
- return (TRUE);
-
- default:
- syslog(LOG_INFO, "Received signal %d", signo);
- return (TRUE);
- }
- } else if (local_port == control_port) {
- boolean_t result;
-
- result = audit_triggers_server(InHeadP, OutHeadP);
- if (!result)
- result = auditd_control_server(InHeadP, OutHeadP);
- return (result);
- }
- syslog(LOG_INFO, "Recevied msg on bad port 0x%x.", local_port);
- return (FALSE);
-}
-
-static int
-wait_for_events(void)
+void
+auditd_terminate(void)
{
- kern_return_t result;
-
- result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
- port_set, MACH_MSG_OPTION_NONE);
- syslog(LOG_ERR, "abnormal exit\n");
- return (close_all());
-}
-
-#else /* ! USE_MACH_IPC */
+ int ret;
-static int
-wait_for_events(void)
-{
- int num;
- unsigned int trigger;
+ auditd_reap_children();
+
+ if (launchd_flag)
+ ret = close_misc();
+ else
+ ret = close_all();
- for (;;) {
- num = read(triggerfd, &trigger, sizeof(trigger));
- if ((num == -1) && (errno != EINTR)) {
- syslog(LOG_ERR, "%s: error %d", __FUNCTION__, errno);
- return (-1);
- }
- if (sigterms != sigterms_handled) {
- syslog(LOG_DEBUG, "%s: SIGTERM", __FUNCTION__);
- break;
- }
- if (sigchlds != sigchlds_handled)
- handle_sigchld();
- if (sighups != sighups_handled) {
- syslog(LOG_DEBUG, "%s: SIGHUP", __FUNCTION__);
- handle_sighup();
- }
- if ((num == -1) && (errno == EINTR))
- continue;
- if (num == 0) {
- syslog(LOG_ERR, "%s: read EOF", __FUNCTION__);
- return (-1);
- }
- if (trigger == AUDIT_TRIGGER_CLOSE_AND_DIE)
- break;
- else
- (void)handle_audit_trigger(trigger);
- }
- return (close_all());
+ exit(ret);
}
-#endif /* ! USE_MACH_IPC */
/*
* Configure the audit controls in the kernel: the event to class mapping,
* kernel preselection mask, etc.
*/
-static int
-config_audit_controls(void)
+int
+auditd_config_controls(void)
{
- au_event_ent_t ev, *evp;
- au_evclass_map_t evc_map;
- au_mask_t aumask;
- int ctr = 0;
- char naeventstr[NA_EVENT_STR_SIZE];
- char polstr[POL_STR_SIZE];
- long policy;
- au_fstat_t au_fstat;
- size_t filesz;
-
- /*
- * Process the audit event file, obtaining a class mapping for each
- * event, and send that mapping into the kernel.
- *
- * XXX There's a risk here that the BSM library will return NULL
- * for an event when it can't properly map it to a class. In that
- * case, we will not process any events beyond the one that failed,
- * but should. We need a way to get a count of the events.
- */
- ev.ae_name = (char *)malloc(AU_EVENT_NAME_MAX);
- ev.ae_desc = (char *)malloc(AU_EVENT_DESC_MAX);
- if ((ev.ae_name == NULL) || (ev.ae_desc == NULL)) {
- if (ev.ae_name != NULL)
- free(ev.ae_name);
- syslog(LOG_ERR,
- "Memory allocation error when configuring audit controls.");
- return (-1);
- }
+ int cnt, err;
+ int ret = 0;
/*
- * XXXRW: Currently we have no way to remove mappings from the kernel
- * when they are removed from the file-based mappings.
- */
- evp = &ev;
- setauevent();
- while ((evp = getauevent_r(evp)) != NULL) {
- evc_map.ec_number = evp->ae_number;
- evc_map.ec_class = evp->ae_class;
- if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t))
- != 0)
- syslog(LOG_ERR,
- "Failed to register class mapping for event %s",
- evp->ae_name);
- else
- ctr++;
- }
- endauevent();
- free(ev.ae_name);
- free(ev.ae_desc);
- if (ctr == 0)
- syslog(LOG_ERR, "No events to class mappings registered.");
- else
- syslog(LOG_DEBUG, "Registered %d event to class mappings.",
- ctr);
-
- /*
- * Get the non-attributable event string and set the kernel mask from
- * that.
- */
- if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0) &&
- (getauditflagsbin(naeventstr, &aumask) == 0)) {
- if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t)))
- syslog(LOG_ERR,
- "Failed to register non-attributable event mask.");
- else
- syslog(LOG_DEBUG,
- "Registered non-attributable event mask.");
+ * Configure event to class mappings in kernel.
+ */
+ cnt = auditd_set_evcmap();
+ if (cnt < 0) {
+ auditd_log_err("auditd_set_evcmap() failed: %m");
+ ret = -1;
+ } else if (cnt == 0) {
+ auditd_log_err("No events to class mappings registered.");
+ ret = -1;
} else
- syslog(LOG_ERR,
- "Failed to obtain non-attributable event mask.");
+ auditd_log_debug("Registered %d event to class mappings.", cnt);
/*
- * If a policy is configured in audit_control(5), implement the
- * policy. However, if one isn't defined, set AUDIT_CNT to avoid
- * leaving the system in a fragile state.
+ * Configure non-attributable event mask in kernel.
*/
- if ((getacpol(polstr, POL_STR_SIZE) == 0) &&
- (au_strtopol(polstr, &policy) == 0)) {
- if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
- syslog(LOG_ERR, "Failed to set audit policy: %m");
- } else {
- syslog(LOG_ERR, "Failed to obtain policy flags: %m");
- policy = AUDIT_CNT;
- if (auditon(A_SETPOLICY, &policy, sizeof(policy)))
- syslog(LOG_ERR,
- "Failed to set default audit policy: %m");
- }
+ err = auditd_set_namask();
+ if (err) {
+ auditd_log_err("auditd_set_namask() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug("Registered non-attributable event mask.");
/*
- * Set trail rotation size.
+ * Configure audit policy in kernel.
*/
- if (getacfilesz(&filesz) == 0) {
- bzero(&au_fstat, sizeof(au_fstat));
- au_fstat.af_filesz = filesz;
- if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0)
- syslog(LOG_ERR, "Failed to set filesz: %m");
+ err = auditd_set_policy();
+ if (err) {
+ auditd_log_err("auditd_set_policy() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
} else
- syslog(LOG_ERR, "Failed to obtain filesz: %m");
-
- return (config_audit_host());
-}
-
-#ifdef USE_MACH_IPC
-static void
-mach_setup(void)
-{
- mach_msg_type_name_t poly;
-
+ auditd_log_debug("Set audit policy in kernel.");
+
/*
- * Allocate a port set
+ * Configure audit trail log size in kernel.
*/
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
- &port_set) != KERN_SUCCESS) {
- syslog(LOG_ERR, "Allocation of port set failed");
- fail_exit();
- }
-
+ err = auditd_set_fsize();
+ if (err) {
+ auditd_log_err("audit_set_fsize() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug("Set audit trail size in kernel.");
+
/*
- * Allocate a signal reflection port
+ * Configure audit trail volume minimum free percentage of blocks in
+ * kernel.
*/
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
- &signal_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(), signal_port, port_set) !=
- KERN_SUCCESS) {
- syslog(LOG_ERR, "Allocation of signal port failed");
- fail_exit();
- }
+ err = auditd_set_minfree();
+ if (err) {
+ auditd_log_err("auditd_set_minfree() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
+ } else
+ auditd_log_debug(
+ "Set audit trail min free percent in kernel.");
/*
- * Allocate a trigger port
- */
- if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
- &control_port) != KERN_SUCCESS ||
- mach_port_move_member(mach_task_self(), control_port, port_set)
- != KERN_SUCCESS)
- syslog(LOG_ERR, "Allocation of trigger port failed");
-
- /*
- * Create a send right on our trigger port.
- */
- mach_port_extract_right(mach_task_self(), control_port,
- MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
-
- /*
- * Register the trigger port with the kernel.
+ * Configure host address in the audit kernel information.
*/
- if (host_set_audit_control_port(mach_host_self(), control_port) !=
- KERN_SUCCESS) {
- syslog(LOG_ERR, "Cannot set Mach control port");
- fail_exit();
+ err = auditd_set_host();
+ if (err) {
+ auditd_log_err("auditd_set_host() %s: %m",
+ auditd_strerror(err));
+ ret = -1;
} else
- syslog(LOG_DEBUG, "Mach control port registered");
+ auditd_log_debug(
+ "Set audit host address information in kernel.");
+
+ return (ret);
}
-#endif /* USE_MACH_IPC */
+/*
+ * Setup and initialize auditd.
+ */
static void
setup(void)
{
- struct auditinfo ai;
- auditinfo_t auinfo;
- int aufd;
- token_t *tok;
-
-#ifdef USE_MACH_IPC
- mach_setup();
-#else
- if ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)) < 0) {
- syslog(LOG_ERR, "Error opening trigger file");
+ int err;
+
+ if (auditd_open_trigger(launchd_flag) < 0) {
+ auditd_log_err("Error opening trigger messaging mechanism");
fail_exit();
}
-#endif
/*
* To prevent event feedback cycles and avoid auditd becoming
@@ -1142,49 +699,25 @@ setup(void)
* 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");
+ err = auditd_prevent_audit();
+ if (err) {
+ auditd_log_err("auditd_prevent_audit() %s: %m",
+ auditd_strerror(err));
fail_exit();
}
- TAILQ_INIT(&dir_q);
- if (read_control_file() == -1) {
- 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.");
- else {
- /*
- * XXXCSJP Perhaps we want more robust audit records for
- * audit start up and shutdown. This might include capturing
- * failures to initialize the audit subsystem?
- */
- bzero(&ai, sizeof(ai));
- if ((tok = au_to_subject32(getuid(), geteuid(), getegid(),
- getuid(), getgid(), getpid(), getpid(), &ai.ai_termid))
- != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_text("auditd::Audit startup")) != NULL)
- au_write(aufd, tok);
- if ((tok = au_to_return32(0, 0)) != NULL)
- au_write(aufd, tok);
- if (au_close(aufd, 1, AUE_audit_startup) == -1)
- syslog(LOG_ERR,
- "Could not close audit startup event.");
- }
+ /*
+ * Make sure auditd auditing state is correct.
+ */
+ auditd_set_state(AUD_STATE_INIT);
- if (config_audit_controls() == 0)
- syslog(LOG_INFO, "Audit controls init successful");
- else
- syslog(LOG_ERR, "Audit controls init failed");
+ /*
+ * If under launchd, don't start auditing. Wait for a trigger to
+ * do so.
+ */
+ if (!launchd_flag)
+ audit_setup();
}
int
@@ -1192,48 +725,73 @@ main(int argc, char **argv)
{
int ch;
int debug = 0;
- int rc, logopts;
+#ifdef AUDIT_REVIEW_GROUP
+ struct group *grp;
+#endif
- while ((ch = getopt(argc, argv, "d")) != -1) {
+ while ((ch = getopt(argc, argv, "dl")) != -1) {
switch(ch) {
case 'd':
/* Debug option. */
debug = 1;
break;
+ case 'l':
+ /* Be launchd friendly. */
+ launchd_flag = 1;
+ break;
+
case '?':
default:
(void)fprintf(stderr,
- "usage: auditd [-d] \n");
+ "usage: auditd [-d] [-l]\n");
exit(1);
}
}
- logopts = LOG_CONS | LOG_PID;
- if (debug != 0)
- logopts |= LOG_PERROR;
+ audit_review_gid = getgid();
-#ifdef LOG_SECURITY
- openlog("auditd", logopts, LOG_SECURITY);
-#else
- openlog("auditd", logopts, LOG_AUTH);
+#ifdef AUDIT_REVIEW_GROUP
+ /*
+ * XXXRW: Currently, this code falls back to the daemon gid, which is
+ * likely the wheel group. Is there a better way to deal with this?
+ */
+ grp = getgrnam(AUDIT_REVIEW_GROUP);
+ if (grp != NULL)
+ audit_review_gid = grp->gr_gid;
#endif
- syslog(LOG_INFO, "starting...");
- if (debug == 0 && daemon(0, 0) == -1) {
- syslog(LOG_ERR, "Failed to daemonize");
+ auditd_openlog(debug, audit_review_gid);
+
+ if (launchd_flag)
+ auditd_log_info("started by launchd...");
+ else
+ auditd_log_info("starting...");
+
+#ifdef AUDIT_REVIEW_GROUP
+ if (grp == NULL)
+ auditd_log_info(
+ "Audit review group '%s' not available, using daemon gid (%d)",
+ AUDIT_REVIEW_GROUP, audit_review_gid);
+#endif
+ if (debug == 0 && launchd_flag == 0 && daemon(0, 0) == -1) {
+ auditd_log_err("Failed to daemonize");
exit(1);
}
if (register_daemon() == -1) {
- syslog(LOG_ERR, "Could not register as daemon");
+ auditd_log_err("Could not register as daemon");
exit(1);
}
setup();
- rc = wait_for_events();
- syslog(LOG_INFO, "auditd exiting.");
+ /*
+ * auditd_wait_for_events() shouldn't return unless something is wrong.
+ */
+ auditd_wait_for_events();
- exit(rc);
+ auditd_log_err("abnormal exit.");
+ close_all();
+ exit(-1);
}
diff --git a/contrib/openbsm/bin/auditd/auditd.h b/contrib/openbsm/bin/auditd/auditd.h
index 688aea3..0351a0e 100644
--- a/contrib/openbsm/bin/auditd/auditd.h
+++ b/contrib/openbsm/bin/auditd/auditd.h
@@ -26,7 +26,7 @@
* (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/auditd/auditd.h#11 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditd/auditd.h#12 $
*/
#ifndef _AUDITD_H_
@@ -46,17 +46,6 @@
*/
#define AUDIT_REVIEW_GROUP "audit"
-#define NOT_TERMINATED "not_terminated"
-#define POSTFIX_LEN (sizeof("YYYYMMDDhhmmss") - 1)
-#define FILENAME_LEN ((2 * POSTFIX_LEN) + 2)
-#define TIMESTAMP_LEN (POSTFIX_LEN + 1)
-
-struct dir_ent {
- char *dirname;
- char softlim;
- TAILQ_ENTRY(dir_ent) dirs;
-};
-
#define HARDLIM_ALL_WARN "allhard"
#define SOFTLIM_ALL_WARN "allsoft"
#define AUDITOFF_WARN "auditoff"
@@ -72,7 +61,11 @@ struct dir_ent {
#define AUDITWARN_SCRIPT "/etc/security/audit_warn"
#define AUDITD_PIDFILE "/var/run/auditd.pid"
-int audit_warn_allhard(int count);
+#define AUD_STATE_INIT -1
+#define AUD_STATE_DISABLED 0
+#define AUD_STATE_ENABLED 1
+
+int audit_warn_allhard(void);
int audit_warn_allsoft(void);
int audit_warn_auditoff(void);
int audit_warn_closefile(char *filename);
@@ -84,4 +77,24 @@ int audit_warn_postsigterm(void);
int audit_warn_soft(char *filename);
int audit_warn_tmpfile(void);
+void auditd_openlog(int debug, gid_t gid);
+void auditd_log_err(const char *fmt, ...);
+void auditd_log_debug(const char *fmt, ...);
+void auditd_log_info(const char *fmt, ...);
+void auditd_log_notice(const char *fmt, ...);
+
+void auditd_set_state(int state);
+int auditd_get_state(void);
+
+int auditd_open_trigger(int launchd_flag);
+int auditd_close_trigger(void);
+void auditd_handle_trigger(int trigger);
+
+void auditd_wait_for_events(void);
+void auditd_relay_signal(int signal);
+void auditd_terminate(void);
+int auditd_config_controls(void);
+void auditd_reap_children(void);
+
+
#endif /* !_AUDITD_H_ */
diff --git a/contrib/openbsm/bin/auditd/auditd_darwin.c b/contrib/openbsm/bin/auditd/auditd_darwin.c
new file mode 100644
index 0000000..55d79f4
--- /dev/null
+++ b/contrib/openbsm/bin/auditd/auditd_darwin.c
@@ -0,0 +1,484 @@
+/*-
+ * Copyright (c) 2004-2008 Apple Inc.
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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/auditd/auditd_darwin.c#2 $
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
+#include <bsm/libbsm.h>
+
+#include <asl.h>
+#include <launch.h>
+#include <notify.h>
+#include <mach/port.h>
+#include <mach/mach_error.h>
+#include <mach/mach_traps.h>
+#include <mach/mach.h>
+#include <mach/host_special_ports.h>
+
+#include "auditd.h"
+
+#include "auditd_controlServer.h"
+#include "audit_triggersServer.h"
+
+/*
+ * Apple System Logger Handles.
+ */
+static aslmsg au_aslmsg = NULL;
+static aslclient au_aslclient = NULL;
+
+static mach_port_t control_port = MACH_PORT_NULL;
+static mach_port_t signal_port = MACH_PORT_NULL;
+static mach_port_t port_set = MACH_PORT_NULL;
+
+/*
+ * Current auditing state (cache).
+ */
+static int auditing_state = AUD_STATE_INIT;
+
+/*
+ * Maximum idle time before auditd terminates under launchd.
+ * If it is zero then auditd does not timeout while idle.
+ */
+static int max_idletime = 0;
+
+#ifndef __BSM_INTERNAL_NOTIFY_KEY
+#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
+#endif /* __BSM_INTERNAL_NOTIFY_KEY */
+
+#ifndef __AUDIT_LAUNCHD_LABEL
+#define __AUDIT_LAUNCHD_LABEL "org.trustedbsd.auditd"
+#endif /* __AUDIT_LAUNCHD_LABEL */
+
+#define MAX_MSG_SIZE 4096
+
+/*
+ * Open and set up system logging.
+ */
+void
+auditd_openlog(int debug, gid_t gid)
+{
+ uint32_t opt = 0;
+ char *cp = NULL;
+
+ if (debug)
+ opt = ASL_OPT_STDERR;
+
+ au_aslclient = asl_open("auditd", "org.trustedbsd.auditd", opt);
+ au_aslmsg = asl_new(ASL_TYPE_MSG);
+
+#ifdef ASL_KEY_READ_UID
+ /*
+ * Make it only so the audit administrator and members of the audit
+ * review group (if used) have access to the auditd system log messages.
+ */
+ asl_set(au_aslmsg, ASL_KEY_READ_UID, "0");
+ asprintf(&cp, "%u", gid);
+ if (cp != NULL) {
+#ifdef ASL_KEY_READ_GID
+ asl_set(au_aslmsg, ASL_KEY_READ_GID, cp);
+#endif
+ free(cp);
+ }
+#endif
+
+ /*
+ * Set the client-side system log filtering.
+ */
+ if (debug)
+ asl_set_filter(au_aslclient,
+ ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));
+ else
+ asl_set_filter(au_aslclient,
+ ASL_FILTER_MASK_UPTO(ASL_LEVEL_INFO));
+}
+
+/*
+ * Log messages at different priority levels.
+ */
+void
+auditd_log_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_ERR, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_NOTICE, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_info(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_INFO, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_debug(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ asl_vlog(au_aslclient, au_aslmsg, ASL_LEVEL_DEBUG, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Get the auditing state from the kernel and cache it.
+ */
+static void
+init_audit_state(void)
+{
+ long au_cond;
+
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ if (errno != ENOSYS) {
+ auditd_log_err("Audit status check failed (%s)",
+ strerror(errno));
+ }
+ auditing_state = AUD_STATE_DISABLED;
+ } else
+ if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED)
+ auditing_state = AUD_STATE_DISABLED;
+ else
+ auditing_state = AUD_STATE_ENABLED;
+}
+
+/*
+ * Update the cached auditing state. Let other tasks that may be caching it
+ * as well to update their state via notify(3).
+ */
+void
+auditd_set_state(int state)
+{
+ int old_auditing_state = auditing_state;
+
+ if (state == AUD_STATE_INIT)
+ init_audit_state();
+ else
+ auditing_state = state;
+
+ if (auditing_state != old_auditing_state) {
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+
+ if (auditing_state == AUD_STATE_ENABLED)
+ auditd_log_notice("Auditing enabled");
+ if (auditing_state == AUD_STATE_DISABLED)
+ auditd_log_notice("Auditing disabled");
+ }
+}
+
+/*
+ * Get the cached auditing state.
+ */
+int
+auditd_get_state(void)
+{
+
+ if (auditing_state == AUD_STATE_INIT) {
+ init_audit_state();
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+ }
+
+ return (auditing_state);
+}
+
+/*
+ * Lookup the audit mach port in the launchd dictionary.
+ */
+static mach_port_t
+lookup_machport(const char *label)
+{
+ launch_data_t msg, msd, ld, cdict, to;
+ mach_port_t mp = MACH_PORT_NULL;
+
+ msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
+
+ cdict = launch_msg(msg);
+ if (cdict == NULL) {
+ auditd_log_err("launch_msg(\"" LAUNCH_KEY_CHECKIN
+ "\") IPC failure: %m");
+ return (MACH_PORT_NULL);
+ }
+
+ if (launch_data_get_type(cdict) == LAUNCH_DATA_ERRNO) {
+ errno = launch_data_get_errno(cdict);
+ auditd_log_err("launch_data_get_type() can't get dict: %m");
+ return (MACH_PORT_NULL);
+ }
+
+ to = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_TIMEOUT);
+ if (to) {
+ max_idletime = launch_data_get_integer(to);
+ auditd_log_debug("launchd timeout set to %d", max_idletime);
+ } else {
+ auditd_log_debug("launchd timeout not set, setting to 60");
+ max_idletime = 60;
+ }
+
+ msd = launch_data_dict_lookup(cdict, LAUNCH_JOBKEY_MACHSERVICES);
+ if (msd == NULL) {
+ auditd_log_err(
+ "launch_data_dict_lookup() can't get mach services");
+ return (MACH_PORT_NULL);
+ }
+
+ ld = launch_data_dict_lookup(msd, label);
+ if (ld == NULL) {
+ auditd_log_err("launch_data_dict_lookup can't find %s", label);
+ return (MACH_PORT_NULL);
+ }
+
+ mp = launch_data_get_machport(ld);
+
+ return (mp);
+}
+
+static int
+mach_setup(int launchd_flag)
+{
+ mach_msg_type_name_t poly;
+
+ /*
+ * Allocate a port set.
+ */
+ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_PORT_SET,
+ &port_set) != KERN_SUCCESS) {
+ auditd_log_err("Allocation of port set failed");
+ return (-1);
+ }
+
+
+ /*
+ * Allocate a signal reflection port.
+ */
+ if (mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE,
+ &signal_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(), signal_port, port_set) !=
+ KERN_SUCCESS) {
+ auditd_log_err("Allocation of signal port failed");
+ return (-1);
+ }
+
+ /*
+ * Allocate a trigger port.
+ */
+ if (launchd_flag) {
+ /*
+ * If started under launchd, lookup port in launchd dictionary.
+ */
+ if ((control_port = lookup_machport(__AUDIT_LAUNCHD_LABEL)) ==
+ MACH_PORT_NULL || mach_port_move_member(mach_task_self(),
+ control_port, port_set) != KERN_SUCCESS) {
+ auditd_log_err("Cannot get Mach control port"
+ " via launchd");
+ return (-1);
+ } else
+ auditd_log_debug("Mach control port registered"
+ " via launchd");
+ } else {
+ /*
+ * If not started under launchd, allocate port and register.
+ */
+ if (mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE, &control_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(), control_port,
+ port_set) != KERN_SUCCESS)
+ auditd_log_err("Allocation of trigger port failed");
+
+ /*
+ * Create a send right on our trigger port.
+ */
+ mach_port_extract_right(mach_task_self(), control_port,
+ MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
+
+ /*
+ * Register the trigger port with the kernel.
+ */
+ if (host_set_audit_control_port(mach_host_self(),
+ control_port) != KERN_SUCCESS) {
+ auditd_log_err("Cannot set Mach control port");
+ return (-1);
+ } else
+ auditd_log_debug("Mach control port registered");
+ }
+
+ return (0);
+}
+
+/*
+ * Open the trigger messaging mechanism.
+ */
+int
+auditd_open_trigger(int launchd_flag)
+{
+
+ return (mach_setup(launchd_flag));
+}
+
+/*
+ * Close the trigger messaging mechanism.
+ */
+int
+auditd_close_trigger(void)
+{
+
+ return (0);
+}
+
+/*
+ * Combined server handler. Called by the mach message loop when there is
+ * a trigger or signal message.
+ */
+static boolean_t
+auditd_combined_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
+{
+ mach_port_t local_port = InHeadP->msgh_local_port;
+
+ /* Reset the idle time alarm, if used. */
+ if (max_idletime)
+ alarm(max_idletime);
+
+ if (local_port == signal_port) {
+ int signo = InHeadP->msgh_id;
+
+ switch(signo) {
+ case SIGTERM:
+ case SIGALRM:
+ auditd_terminate();
+ /* Not reached. */
+
+ case SIGCHLD:
+ auditd_reap_children();
+ return (TRUE);
+
+ case SIGHUP:
+ auditd_config_controls();
+ return (TRUE);
+
+ default:
+ auditd_log_info("Received signal %d", signo);
+ return (TRUE);
+ }
+ } else if (local_port == control_port) {
+ boolean_t result;
+
+ result = audit_triggers_server(InHeadP, OutHeadP);
+ if (!result)
+ result = auditd_control_server(InHeadP, OutHeadP);
+ return (result);
+ }
+ auditd_log_info("Recevied msg on bad port 0x%x.", local_port);
+ return (FALSE);
+}
+
+/*
+ * The main event loop. Wait for trigger messages or signals and handle them.
+ * It should not return unless there is a problem.
+ */
+void
+auditd_wait_for_events(void)
+{
+ kern_return_t result;
+
+ /*
+ * Call the mach messaging server loop.
+ */
+ result = mach_msg_server(auditd_combined_server, MAX_MSG_SIZE,
+ port_set, MACH_MSG_OPTION_NONE);
+}
+
+/*
+ * Implementation of the audit_triggers() MIG simpleroutine. Simply a
+ * wrapper function. This handles input from the kernel on the host
+ * special mach port.
+ */
+kern_return_t
+audit_triggers(mach_port_t __unused audit_port, int trigger)
+{
+
+ auditd_handle_trigger(trigger);
+
+ return (KERN_SUCCESS);
+}
+
+/*
+ * Implementation of the auditd_control() MIG simpleroutine. Simply a
+ * wrapper function. This handles input from the audit(1) tool.
+ */
+kern_return_t
+auditd_control(mach_port_t __unused auditd_port, int trigger)
+{
+
+ auditd_handle_trigger(trigger);
+
+ return (KERN_SUCCESS);
+}
+
+/*
+ * When we get a signal, we are often not at a clean point. So, little can
+ * be done in the signal handler itself. Instead, we send a message to the
+ * main servicing loop to do proper handling from a non-signal-handler
+ * context.
+ */
+void
+auditd_relay_signal(int signal)
+{
+ mach_msg_empty_send_t msg;
+
+ msg.header.msgh_id = signal;
+ msg.header.msgh_remote_port = signal_port;
+ msg.header.msgh_local_port = MACH_PORT_NULL;
+ msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+ mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
+ 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+}
diff --git a/contrib/openbsm/bin/auditd/auditd_fbsd.c b/contrib/openbsm/bin/auditd/auditd_fbsd.c
new file mode 100644
index 0000000..945e6d2
--- /dev/null
+++ b/contrib/openbsm/bin/auditd/auditd_fbsd.c
@@ -0,0 +1,272 @@
+/*-
+ * Copyright (c) 2004-2008 Apple Inc.
+ * 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.
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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/auditd/auditd_fbsd.c#1 $
+ */
+
+#include <sys/types.h>
+
+#include <config/config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <syslog.h>
+#include <stdarg.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/auditd_lib.h>
+#include <bsm/libbsm.h>
+
+#include "auditd.h"
+
+/*
+ * Current auditing state (cache).
+ */
+static int auditing_state = AUD_STATE_INIT;
+
+/*
+ * Maximum idle time before auditd terminates under launchd.
+ * If it is zero then auditd does not timeout while idle.
+ */
+static int max_idletime = 0;
+
+static int sigchlds, sigchlds_handled;
+static int sighups, sighups_handled;
+static int sigterms, sigterms_handled;
+static int sigalrms, sigalrms_handled;
+
+static int triggerfd = 0;
+
+/*
+ * Open and set up system logging.
+ */
+void
+auditd_openlog(int debug, gid_t __unused gid)
+{
+ int logopts = LOG_CONS | LOG_PID;
+
+ if (debug)
+ logopts |= LOG_PERROR;
+
+#ifdef LOG_SECURITY
+ openlog("auditd", logopts, LOG_SECURITY);
+#else
+ openlog("auditd", logopts, LOG_AUTH);
+#endif
+}
+
+/*
+ * Log messages at different priority levels.
+ */
+void
+auditd_log_err(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_notice(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_NOTICE, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_info(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_INFO, fmt, ap);
+ va_end(ap);
+}
+
+void
+auditd_log_debug(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsyslog(LOG_DEBUG, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Get the auditing state from the kernel and cache it.
+ */
+static void
+init_audit_state(void)
+{
+ long au_cond;
+
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ if (errno != ENOSYS) {
+ auditd_log_err("Audit status check failed (%s)",
+ strerror(errno));
+ }
+ auditing_state = AUD_STATE_DISABLED;
+ } else
+ if (au_cond == AUC_NOAUDIT || au_cond == AUC_DISABLED)
+ auditing_state = AUD_STATE_DISABLED;
+ else
+ auditing_state = AUD_STATE_ENABLED;
+}
+
+/*
+ * Update the cached auditing state.
+ */
+void
+auditd_set_state(int state)
+{
+ int old_auditing_state = auditing_state;
+
+ if (state == AUD_STATE_INIT)
+ init_audit_state();
+ else
+ auditing_state = state;
+
+ if (auditing_state != old_auditing_state) {
+ if (auditing_state == AUD_STATE_ENABLED)
+ auditd_log_notice("Auditing enabled");
+ if (auditing_state == AUD_STATE_DISABLED)
+ auditd_log_notice("Auditing disabled");
+ }
+}
+
+/*
+ * Get the cached auditing state.
+ */
+int
+auditd_get_state(void)
+{
+
+ if (auditing_state == AUD_STATE_INIT)
+ init_audit_state();
+
+ return (auditing_state);
+}
+
+/*
+ * Open the trigger messaging mechanism.
+ */
+int
+auditd_open_trigger(int __unused launchd_flag)
+{
+
+ return ((triggerfd = open(AUDIT_TRIGGER_FILE, O_RDONLY, 0)));
+}
+
+/*
+ * Close the trigger messaging mechanism.
+ */
+int
+auditd_close_trigger(void)
+{
+
+ return (close(triggerfd));
+}
+
+/*
+ * The main event loop. Wait for trigger messages or signals and handle them.
+ * It should not return unless there is a problem.
+ */
+void
+auditd_wait_for_events(void)
+{
+ int num;
+ unsigned int trigger;
+
+ for (;;) {
+ num = read(triggerfd, &trigger, sizeof(trigger));
+ if ((num == -1) && (errno != EINTR)) {
+ auditd_log_err("%s: error %d", __FUNCTION__, errno);
+ return;
+ }
+
+ /* Reset the idle time alarm, if used. */
+ if (max_idletime)
+ alarm(max_idletime);
+
+ if (sigterms != sigterms_handled) {
+ auditd_log_debug("%s: SIGTERM", __FUNCTION__);
+ auditd_terminate();
+ /* not reached */
+ }
+ if (sigalrms != sigalrms_handled) {
+ auditd_log_debug("%s: SIGALRM", __FUNCTION__);
+ auditd_terminate();
+ /* not reached */
+ }
+ if (sigchlds != sigchlds_handled) {
+ sigchlds_handled = sigchlds;
+ auditd_reap_children();
+ }
+ if (sighups != sighups_handled) {
+ auditd_log_debug("%s: SIGHUP", __FUNCTION__);
+ sighups_handled = sighups;
+ auditd_config_controls();
+ }
+
+ if ((num == -1) && (errno == EINTR))
+ continue;
+ if (num == 0) {
+ auditd_log_err("%s: read EOF", __FUNCTION__);
+ return;
+ }
+ auditd_handle_trigger(trigger);
+ }
+}
+
+/*
+ * When we get a signal, we are often not at a clean point. So, little can
+ * be done in the signal handler itself. Instead, we send a message to the
+ * main servicing loop to do proper handling from a non-signal-handler
+ * context.
+ */
+void
+auditd_relay_signal(int signal)
+{
+ if (signal == SIGHUP)
+ sighups++;
+ if (signal == SIGTERM)
+ sigterms++;
+ if (signal == SIGCHLD)
+ sigchlds++;
+ if (signal == SIGALRM)
+ sigalrms++;
+}
+
diff --git a/contrib/openbsm/bin/auditfilterd/Makefile.in b/contrib/openbsm/bin/auditfilterd/Makefile.in
index 874e106..07926da 100644
--- a/contrib/openbsm/bin/auditfilterd/Makefile.in
+++ b/contrib/openbsm/bin/auditfilterd/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.in#6 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditfilterd/Makefile.in#7 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/bin/auditreduce/Makefile.in b/contrib/openbsm/bin/auditreduce/Makefile.in
index b18513f..1030a83 100644
--- a/contrib/openbsm/bin/auditreduce/Makefile.in
+++ b/contrib/openbsm/bin/auditreduce/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/Makefile.in#9 $
#
VPATH = @srcdir@
diff --git a/contrib/openbsm/bin/auditreduce/auditreduce.c b/contrib/openbsm/bin/auditreduce/auditreduce.c
index f22f454..2158525 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#28 $
+ * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#29 $
*/
/*
@@ -567,7 +567,7 @@ select_records(FILE *fp)
* The -o option has the form object_type=object_value. Identify the object
* components.
*/
-void
+static void
parse_object_type(char *name, char *val)
{
if (val == NULL)
diff --git a/contrib/openbsm/bin/praudit/Makefile.in b/contrib/openbsm/bin/praudit/Makefile.in
index 4472757..025b48f 100644
--- a/contrib/openbsm/bin/praudit/Makefile.in
+++ b/contrib/openbsm/bin/praudit/Makefile.in
@@ -15,7 +15,7 @@
@SET_MAKE@
#
-# $P4: //depot/projects/trustedbsd/openbsm/bin/praudit/Makefile.in#8 $
+# $P4: //depot/projects/trustedbsd/openbsm/bin/praudit/Makefile.in#9 $
#
VPATH = @srcdir@
OpenPOWER on IntegriCloud