diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2008-12-28 22:40:42 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2008-12-28 22:40:42 +0000 |
commit | 980b6e45aaf200a759c883374991028300774958 (patch) | |
tree | 8026680e57e152bff629fb5733fa531adc5dd323 | |
parent | a5c6cfa00d9aad0a0da65a940ac6d782edfa841e (diff) |
Notes
125 files changed, 4893 insertions, 1184 deletions
diff --git a/Makefile.am b/Makefile.am index 60fbea972cc0..55849cc54354 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,15 +1,23 @@ # -# $P4: //depot/projects/trustedbsd/openbsm/Makefile.am#3 $ +# $P4: //depot/projects/trustedbsd/openbsm/Makefile.am#4 $ # SUBDIRS = \ - bsm \ + bsm + +if HAVE_AUDIT_SYSCALLS +SUBDIRS += \ + libauditd +endif + +SUBDIRS += \ libbsm \ bin \ man \ modules \ sys + EXTRA_DIST = \ CHANGELOG \ LICENSE \ diff --git a/Makefile.in b/Makefile.in index 9068b4c80594..0cc909537257 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/Makefile.in#8 $ +# $P4: //depot/projects/trustedbsd/openbsm/Makefile.in#9 $ # VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ @@ -35,6 +35,9 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +@HAVE_AUDIT_SYSCALLS_TRUE@am__append_1 = \ +@HAVE_AUDIT_SYSCALLS_TRUE@ libauditd + subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/config/config.h.in \ @@ -63,7 +66,7 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = $(SUBDIRS) +DIST_SUBDIRS = bsm libauditd libbsm bin man modules sys DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -183,14 +186,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUBDIRS = \ - bsm \ - libbsm \ - bin \ - man \ - modules \ - sys - +SUBDIRS = bsm $(am__append_1) libbsm bin man modules sys EXTRA_DIST = \ CHANGELOG \ LICENSE \ @@ -1,5 +1,50 @@ OpenBSM Version History +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 bug resulted in "unknown" tokens being printed + after the exec args/env tokens. +- Support for AUT_SOCKET_EX extended socket tokens, which describe a socket + using a pair of IPv4/IPv6 and port tuples. +- OpenBSM BSM file header version bumped for 1.1 release. +- Deprecated Darwin constants, such as TRAILER_PAD_MAGIC, removed. + OpenBSM 1.1 alpha 2 - Include files in OpenBSM are now broken out into two parts: library builds @@ -348,4 +393,4 @@ OpenBSM 1.0 alpha 1 to support reloading of kernel event table. - Allow comments in /etc/security configuration files. -$P4: //depot/projects/trustedbsd/openbsm/NEWS#9 $ +$P4: //depot/projects/trustedbsd/openbsm/NEWS#21 $ @@ -1,4 +1,4 @@ -OpenBSM 1.1 alpha 1 +OpenBSM 1.1 alpha 4 Introduction @@ -19,6 +19,7 @@ OpenBSM consists of several directories: bsm/ Library include files for BSM compat/ Compatibility code to build on various OS's etc/ Sample /etc/security configuration files + libauditd Common audit management functions for auditd and launchd libbsm/ Implementation of BSM library interfaces and man pages man/ System call and configuration file man pages modules/ Directory for auditfilterd module source @@ -55,4 +56,4 @@ Information on TrustedBSD may be found on the TrustedBSD home page: http://www.TrustedBSD.org/ -$P4: //depot/projects/trustedbsd/openbsm/README#32 $ +$P4: //depot/projects/trustedbsd/openbsm/README#34 $ @@ -20,5 +20,7 @@ OpenBSM TODO - Document audit_warn event arguments. - Allow the path /etc/security to be configured at configure-time so that alternative locations can be used. +- NLS support for au_strerror(3), which provides error strings for BSM errors + not available on the local OS platform. -$P4: //depot/projects/trustedbsd/openbsm/TODO#11 $ +$P4: //depot/projects/trustedbsd/openbsm/TODO#12 $ @@ -1 +1 @@ -OPENBSM_1_1_ALPHA_2 +OPENBSM_1_1_ALPHA_4 diff --git a/bin/Makefile.in b/bin/Makefile.in index ddace5819f42..06ef9a75dc47 100644 --- a/bin/Makefile.in +++ b/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/bin/audit/Makefile.am b/bin/audit/Makefile.am index ed62929ca00e..1b5d554ac62b 100644 --- a/bin/audit/Makefile.am +++ b/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/bin/audit/Makefile.in b/bin/audit/Makefile.in index edaf018170cd..ae2dd6ec6bcf 100644 --- a/bin/audit/Makefile.in +++ b/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/bin/audit/audit.8 b/bin/audit/audit.8 index 4aaa494b30da..b0276d40da6a 100644 --- a/bin/audit/audit.8 +++ b/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/bin/audit/audit.c b/bin/audit/audit.c index b1415a64a80b..3a07aa75966d 100644 --- a/bin/audit/audit.c +++ b/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/bin/auditd/Makefile.am b/bin/auditd/Makefile.am index f65b1556bdff..2372fa6e7fd1 100644 --- a/bin/auditd/Makefile.am +++ b/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/bin/auditd/Makefile.in b/bin/auditd/Makefile.in index 731607cc54f4..44240d6be37c 100644 --- a/bin/auditd/Makefile.in +++ b/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/bin/auditd/audit_warn.c b/bin/auditd/audit_warn.c index 7bc7a14572b7..6dfb3bd2f7b0 100644 --- a/bin/auditd/audit_warn.c +++ b/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/bin/auditd/auditd.8 b/bin/auditd/auditd.8 index 199b9ccbdbe3..49cf9eaeaf5e 100644 --- a/bin/auditd/auditd.8 +++ b/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/bin/auditd/auditd.c b/bin/auditd/auditd.c index e0c03d0bf6a1..316402a85b02 100644 --- a/bin/auditd/auditd.c +++ b/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/bin/auditd/auditd.h b/bin/auditd/auditd.h index 688aea39400f..0351a0ec1507 100644 --- a/bin/auditd/auditd.h +++ b/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/bin/auditd/auditd_darwin.c b/bin/auditd/auditd_darwin.c new file mode 100644 index 000000000000..55d79f4f155a --- /dev/null +++ b/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/bin/auditd/auditd_fbsd.c b/bin/auditd/auditd_fbsd.c new file mode 100644 index 000000000000..945e6d2b9e6e --- /dev/null +++ b/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/bin/auditfilterd/Makefile.in b/bin/auditfilterd/Makefile.in index 874e1062cd46..07926da574e5 100644 --- a/bin/auditfilterd/Makefile.in +++ b/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/bin/auditreduce/Makefile.in b/bin/auditreduce/Makefile.in index b18513f2c84e..1030a837a791 100644 --- a/bin/auditreduce/Makefile.in +++ b/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/bin/auditreduce/auditreduce.c b/bin/auditreduce/auditreduce.c index f22f4546a4ef..215852563dc8 100644 --- a/bin/auditreduce/auditreduce.c +++ b/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/bin/praudit/Makefile.in b/bin/praudit/Makefile.in index 447275750644..025b48fbb862 100644 --- a/bin/praudit/Makefile.in +++ b/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@ diff --git a/bsm/Makefile.am b/bsm/Makefile.am index cad411547411..b92f9cdd55f6 100644 --- a/bsm/Makefile.am +++ b/bsm/Makefile.am @@ -1,5 +1,5 @@ # -# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.am#3 $ +# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.am#4 $ # openbsmdir = $(includedir)/bsm @@ -7,5 +7,6 @@ openbsmdir = $(includedir)/bsm openbsm_HEADERS = \ audit_filter.h \ audit_uevents.h \ + auditd_lib.h \ libbsm.h diff --git a/bsm/Makefile.in b/bsm/Makefile.in index ed82a3b4b73b..5ea5ee274df5 100644 --- a/bsm/Makefile.in +++ b/bsm/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.in#8 $ +# $P4: //depot/projects/trustedbsd/openbsm/bsm/Makefile.in#9 $ # VPATH = @srcdir@ @@ -172,6 +172,7 @@ openbsmdir = $(includedir)/bsm openbsm_HEADERS = \ audit_filter.h \ audit_uevents.h \ + auditd_lib.h \ libbsm.h all: all-am diff --git a/bsm/audit_uevents.h b/bsm/audit_uevents.h index 03d0f9b9995d..53c56164ee02 100644 --- a/bsm/audit_uevents.h +++ b/bsm/audit_uevents.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2004-2008 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,22 +26,14 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit_uevents.h#8 $ + * $P4: //depot/projects/trustedbsd/openbsm/bsm/audit_uevents.h#10 $ */ #ifndef _BSM_AUDIT_UEVENTS_H_ #define _BSM_AUDIT_UEVENTS_H_ -/*- - * User level audit event numbers - * - * Range of audit event numbers: - * 0 Reserved, invalid - * 1 - 2047 Reserved for kernel events - * 2048 - 32767 Defined by BSM for user events - * 32768 - 36864 Reserved for Mac OS-X applications - * 36865 - 65535 Reserved for applications - * +/* + * Solaris userspace events. */ #define AUE_at_create 6144 #define AUE_at_delete 6145 @@ -70,8 +62,13 @@ #define AUE_shutdown 6168 #define AUE_poweroff 6169 #define AUE_crontab_mod 6170 -#define AUE_audit_startup 6171 -#define AUE_audit_shutdown 6172 +#define AUE_ftpd_logout 6171 +#define AUE_ssh 6172 +#define AUE_role_login 6173 +#define AUE_prof_cmd 6180 +#define AUE_filesystem_add 6181 +#define AUE_filesystem_delete 6182 +#define AUE_filesystem_modify 6183 #define AUE_allocate_succ 6200 #define AUE_allocate_fail 6201 #define AUE_deallocate_succ 6202 @@ -83,20 +80,63 @@ #define AUE_delete_user 6209 #define AUE_disable_user 6210 #define AUE_enable_user 6211 -#define AUE_sudo 6300 -#define AUE_modify_password 6501 /* Not assigned by Sun. */ -#define AUE_create_group 6511 /* Not assigned by Sun. */ -#define AUE_delete_group 6512 /* Not assigned by Sun. */ -#define AUE_modify_group 6513 /* Not assigned by Sun. */ -#define AUE_add_to_group 6514 /* Not assigned by Sun. */ -#define AUE_remove_from_group 6515 /* Not assigned by Sun. */ -#define AUE_revoke_obj 6521 /* Not assigned by Sun; not used. */ -#define AUE_lw_login 6600 /* Not assigned by Sun; tentative. */ -#define AUE_lw_logout 6601 /* Not assigned by Sun; tentative. */ -#define AUE_auth_user 7000 /* Not assigned by Sun. */ -#define AUE_ssconn 7001 /* Not assigned by Sun. */ -#define AUE_ssauthorize 7002 /* Not assigned by Sun. */ -#define AUE_ssauthint 7003 /* Not assigned by Sun. */ +#define AUE_newgrp_login 6212 +#define AUE_admin_authentication 6213 +#define AUE_kadmind_auth 6214 +#define AUE_kadmind_unauth 6215 +#define AUE_krb5kdc_as_req 6216 +#define AUE_krb5kdc_tgs_req 6217 +#define AUE_krb5kdc_tgs_req_2ndtktmm 6218 +#define AUE_krb5kdc_tgs_req_alt_tgt 6219 + +/* + * Historic Darwin use of the low event numbering space, which collided with + * the Solaris event space. Now obsoleted and new, higher, event numbers + * assigned to make it easier to interpret Solaris events using the OpenBSM + * tools. + */ +#define AUE_DARWIN_audit_startup 6171 +#define AUE_DARWIN_audit_shutdown 6172 +#define AUE_DARWIN_sudo 6300 +#define AUE_DARWIN_modify_password 6501 +#define AUE_DARWIN_create_group 6511 +#define AUE_DARWIN_delete_group 6512 +#define AUE_DARWIN_modify_group 6513 +#define AUE_DARWIN_add_to_group 6514 +#define AUE_DARWIN_remove_from_group 6515 +#define AUE_DARWIN_revoke_obj 6521 +#define AUE_DARWIN_lw_login 6600 +#define AUE_DARWIN_lw_logout 6601 +#define AUE_DARWIN_auth_user 7000 +#define AUE_DARWIN_ssconn 7001 +#define AUE_DARWIN_ssauthorize 7002 +#define AUE_DARWIN_ssauthint 7003 + +/* + * Historic/third-party appliation allocations of event idenfiers. + */ #define AUE_openssh 32800 +/* + * OpenBSM-managed application event space. + */ +#define AUE_audit_startup 45000 /* Darwin-specific. */ +#define AUE_audit_shutdown 45001 /* Darwin-specific. */ +#define AUE_modify_password 45014 /* Darwin-specific. */ +#define AUE_create_group 45015 /* Darwin-specific. */ +#define AUE_delete_group 45016 /* Darwin-specific. */ +#define AUE_modify_group 45017 /* Darwin-specific. */ +#define AUE_add_to_group 45018 /* Darwin-specific. */ +#define AUE_remove_from_group 45019 /* Darwin-specific. */ +#define AUE_revoke_obj 45020 /* Darwin-specific. */ +#define AUE_lw_login 45021 /* Darwin-specific. */ +#define AUE_lw_logout 45022 /* Darwin-specific. */ +#define AUE_auth_user 45023 /* Darwin-specific. */ +#define AUE_ssconn 45024 /* Darwin-specific. */ +#define AUE_ssauthorize 45025 /* Darwin-specific. */ +#define AUE_ssauthint 45026 /* Darwin-specific. */ +#define AUE_calife 45027 /* OpenBSM-allocated. */ +#define AUE_sudo 45028 /* OpenBSM-allocated. */ +#define AUE_audit_recovery 45029 /* OpenBSM-allocated. */ + #endif /* !_BSM_AUDIT_UEVENTS_H_ */ diff --git a/bsm/auditd_lib.h b/bsm/auditd_lib.h new file mode 100644 index 000000000000..77acff7d2059 --- /dev/null +++ b/bsm/auditd_lib.h @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 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/bsm/auditd_lib.h#2 $ + */ + +#ifndef _BSM_AUDITD_LIB_H_ +#define _BSM_AUDITD_LIB_H_ + +/* + * Lengths for audit trail file components. + */ +#define NOT_TERMINATED "not_terminated" +#define CRASH_RECOVERY "crash_recovery" +#define POSTFIX_LEN (sizeof("YYYYMMDDhhmmss") - 1) +#define FILENAME_LEN ((2 * POSTFIX_LEN) + 2) +#define TIMESTAMP_LEN (POSTFIX_LEN + 1) + +/* + * Macro to generate the timestamp string for trail file. + */ +#define getTSstr(t, b, l) \ + ( (((t) = time(0)) == (time_t)-1 ) || \ + !strftime((b), (l), "%Y%m%d%H%M%S", gmtime(&(t)) ) ) ? -1 : 0 + +/* + * The symbolic link to the currently active audit trail file. + */ +#define AUDIT_CURRENT_LINK "/var/audit/current" + +/* + * Path of auditd plist file for launchd. + */ +#define AUDITD_PLIST_FILE \ + "/System/Library/LaunchDaemons/org.trustedbsd.auditd.plist" + +/* + * Error return codes for auditd_lib functions. + */ +#define ADE_NOERR 0 /* No Error or Success. */ +#define ADE_PARSE -1 /* Error parsing audit_control(5). */ +#define ADE_AUDITON -2 /* auditon(2) call failed. */ +#define ADE_NOMEM -3 /* Error allocating memory. */ +#define ADE_SOFTLIM -4 /* All audit log directories over soft limit. */ +#define ADE_HARDLIM -5 /* All audit log directories over hard limit. */ +#define ADE_STRERR -6 /* Error creating file name string. */ +#define ADE_AU_OPEN -7 /* au_open(3) failed. */ +#define ADE_AU_CLOSE -8 /* au_close(3) failed. */ +#define ADE_SETAUDIT -9 /* setaudit(2) or setaudit_addr(2) failed. */ +#define ADE_ACTL -10 /* "Soft" error with auditctl(2). */ +#define ADE_ACTLERR -11 /* "Hard" error with auditctl(2). */ +#define ADE_SWAPERR -12 /* The audit trail file could not be swap. */ +#define ADE_RENAME -13 /* Error renaming crash recovery file. */ +#define ADE_READLINK -14 /* Error reading 'current' link. */ +#define ADE_SYMLINK -15 /* Error creating 'current' link. */ +#define ADE_INVAL -16 /* Invalid argument. */ +#define ADE_GETADDR -17 /* Error resolving address from hostname. */ +#define ADE_ADDRFAM -18 /* Address family not supported. */ + +/* + * auditd_lib functions. + */ +const char *auditd_strerror(int errcode); +int auditd_set_minfree(void); +int auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *)); +void auditd_close_dirs(void); +int auditd_set_evcmap(void); +int auditd_set_namask(void); +int auditd_set_policy(void); +int auditd_set_fsize(void); +int auditd_set_host(void); +int auditd_swap_trail(char *TS, char **newfile, gid_t gid, + int (*warn_getacdir)(char *)); +int auditd_prevent_audit(void); +int auditd_gen_record(int event, char *path); +int auditd_new_curlink(char *curfile); +int audit_quick_start(void); +int audit_quick_stop(void); + +#endif /* !_BSM_AUDITD_LIB_H_ */ diff --git a/bsm/libbsm.h b/bsm/libbsm.h index 97b953072e15..ba96e9d42393 100644 --- a/bsm/libbsm.h +++ b/bsm/libbsm.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2004-2008 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -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/bsm/libbsm.h#35 $ + * $P4: //depot/projects/trustedbsd/openbsm/bsm/libbsm.h#40 $ */ #ifndef _LIBBSM_H_ @@ -547,13 +547,13 @@ typedef struct { * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address) */ typedef struct { + u_int16_t domain; u_int16_t type; + u_int16_t atype; u_int16_t l_port; - u_int32_t l_ad_type; - u_int32_t l_addr; + u_int32_t l_addr[4]; u_int32_t r_port; - u_int32_t r_ad_type; - u_int32_t r_addr; + u_int32_t r_addr[4]; } au_socket_ex32_t; /* @@ -824,6 +824,13 @@ void au_print_xml_footer(FILE *outfp); __END_DECLS /* + * Functions relating to BSM<->errno conversion. + */ +int au_bsm_to_errno(u_char bsm_error, int *errorp); +u_char au_errno_to_bsm(int error); +const char *au_strerror(u_char bsm_error); + +/* * The remaining APIs are associated with Apple's BSM implementation, in * particular as relates to Mach IPC auditing and triggers passed via Mach * IPC. @@ -930,6 +937,19 @@ void au_free_token(token_t *tok); * XXXRW: In Apple's bsm-8, these are marked __APPLE_API_PRIVATE. */ int au_get_state(void); + +/* + * Initialize the audit notification. If it has not already been initialized + * it will automatically on the first call of au_get_state(). + */ +uint32_t au_notify_initialize(void); + +/* + * Cancel audit notification and free the resources associated with it. + * Responsible code that no longer needs to use au_get_state() should call + * this. + */ +int au_notify_terminate(void); __END_DECLS /* OpenSSH compatibility */ diff --git a/compat/endian.h b/compat/endian.h index 83762e4b4764..6ef1d15b3d54 100644 --- a/compat/endian.h +++ b/compat/endian.h @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * Derived from FreeBSD src/sys/sys/endian.h:1.6. - * $P4: //depot/projects/trustedbsd/openbsm/compat/endian.h#7 $ + * $P4: //depot/projects/trustedbsd/openbsm/compat/endian.h#8 $ */ #ifndef _COMPAT_ENDIAN_H_ @@ -35,7 +35,9 @@ * Some systems will have the uint/int types defined here already, others * will need stdint.h. */ +#ifdef HAVE_STDINT_H #include <stdint.h> +#endif /* * Some operating systems do not yet have the more recent endian APIs that diff --git a/config/config.h.in b/config/config.h.in index 5ac71ab2c8a4..bc30aaa2098e 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -6,6 +6,9 @@ /* Define if audit system calls present */ #undef HAVE_AUDIT_SYSCALLS +/* Define if be32enc is present */ +#undef HAVE_BE32ENC + /* Define to 1 if you have the `bzero' function. */ #undef HAVE_BZERO @@ -67,6 +70,9 @@ /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET +/* Define to 1 if you have the `pthread_mutex_lock' function. */ +#undef HAVE_PTHREAD_MUTEX_LOCK + /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG diff --git a/configure b/configure index e6cb1ce4e4f2..1a68735338c0 100755 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #! /bin/sh -# From configure.ac P4: //depot/projects/trustedbsd/openbsm/configure.ac#41 . +# From configure.ac P4: //depot/projects/trustedbsd/openbsm/configure.ac#47 . # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for OpenBSM 1.1alpha2. +# Generated by GNU Autoconf 2.61 for OpenBSM 1.1alpha4. # # Report bugs to <trustedbsd-audit@TrustesdBSD.org>. # @@ -729,8 +729,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='OpenBSM' PACKAGE_TARNAME='openbsm' -PACKAGE_VERSION='1.1alpha2' -PACKAGE_STRING='OpenBSM 1.1alpha2' +PACKAGE_VERSION='1.1alpha4' +PACKAGE_STRING='OpenBSM 1.1alpha4' PACKAGE_BUGREPORT='trustedbsd-audit@TrustesdBSD.org' ac_unique_file="bin/auditreduce/auditreduce.c" @@ -1404,7 +1404,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures OpenBSM 1.1alpha2 to adapt to many kinds of systems. +\`configure' configures OpenBSM 1.1alpha4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1474,7 +1474,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of OpenBSM 1.1alpha2:";; + short | recursive ) echo "Configuration of OpenBSM 1.1alpha4:";; esac cat <<\_ACEOF @@ -1580,7 +1580,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -OpenBSM configure 1.1alpha2 +OpenBSM configure 1.1alpha4 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1594,7 +1594,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by OpenBSM $as_me 1.1alpha2, which was +It was created by OpenBSM $as_me 1.1alpha4, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -19076,7 +19076,7 @@ fi # Define the identity of the package. PACKAGE=OpenBSM - VERSION=1.1alpha2 + VERSION=1.1alpha4 cat >>confdefs.h <<_ACEOF @@ -19852,7 +19852,8 @@ fi -for ac_header in endian.h mach/mach.h machine/endian.h sys/endian.h + +for ac_header in endian.h mach/mach.h machine/endian.h sys/endian.h stdint.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -22802,7 +22803,8 @@ done -for ac_func in bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul + +for ac_func in bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul pthread_mutex_lock do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 @@ -22969,7 +22971,7 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include <stdlib.h> + #include <stddef.h> extern int auditon(int, void *, int); @@ -23031,6 +23033,66 @@ else fi +# +# There are a wide variety of endian macros and functions in the wild; we try +# to use the native support if it defines be32enc(), but otherwise have to +# use our own. +# +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <sys/endian.h> + #include <stdlib.h> + +int +main () +{ + + be32enc(NULL, 1); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BE32ENC +_ACEOF + + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + # Check to see if Mach IPC is used for trigger messages. If so, use Mach IPC # instead of the default for sending trigger messages to the audit components. { echo "$as_me:$LINENO: checking for /usr/include/mach/audit_triggers.defs" >&5 @@ -23074,7 +23136,7 @@ else fi -ac_config_files="$ac_config_files Makefile bin/Makefile bin/audit/Makefile bin/auditd/Makefile bin/auditfilterd/Makefile bin/auditreduce/Makefile bin/praudit/Makefile bsm/Makefile libbsm/Makefile modules/Makefile modules/auditfilter_noop/Makefile man/Makefile sys/Makefile sys/bsm/Makefile test/Makefile test/bsm/Makefile tools/Makefile" +ac_config_files="$ac_config_files Makefile bin/Makefile bin/audit/Makefile bin/auditd/Makefile bin/auditfilterd/Makefile bin/auditreduce/Makefile bin/praudit/Makefile bsm/Makefile libauditd/Makefile libbsm/Makefile modules/Makefile modules/auditfilter_noop/Makefile man/Makefile sys/Makefile sys/bsm/Makefile test/Makefile test/bsm/Makefile tools/Makefile" cat >confcache <<\_ACEOF @@ -23522,7 +23584,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by OpenBSM $as_me 1.1alpha2, which was +This file was extended by OpenBSM $as_me 1.1alpha4, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -23575,7 +23637,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -OpenBSM config.status 1.1alpha2 +OpenBSM config.status 1.1alpha4 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -23699,6 +23761,7 @@ do "bin/auditreduce/Makefile") CONFIG_FILES="$CONFIG_FILES bin/auditreduce/Makefile" ;; "bin/praudit/Makefile") CONFIG_FILES="$CONFIG_FILES bin/praudit/Makefile" ;; "bsm/Makefile") CONFIG_FILES="$CONFIG_FILES bsm/Makefile" ;; + "libauditd/Makefile") CONFIG_FILES="$CONFIG_FILES libauditd/Makefile" ;; "libbsm/Makefile") CONFIG_FILES="$CONFIG_FILES libbsm/Makefile" ;; "modules/Makefile") CONFIG_FILES="$CONFIG_FILES modules/Makefile" ;; "modules/auditfilter_noop/Makefile") CONFIG_FILES="$CONFIG_FILES modules/auditfilter_noop/Makefile" ;; diff --git a/configure.ac b/configure.ac index 1da42cd019f8..9447684354f6 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([OpenBSM], [1.1alpha2], [trustedbsd-audit@TrustesdBSD.org],[openbsm]) -AC_REVISION([$P4: //depot/projects/trustedbsd/openbsm/configure.ac#42 $]) +AC_INIT([OpenBSM], [1.1alpha4], [trustedbsd-audit@TrustesdBSD.org],[openbsm]) +AC_REVISION([$P4: //depot/projects/trustedbsd/openbsm/configure.ac#48 $]) AC_CONFIG_SRCDIR([bin/auditreduce/auditreduce.c]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_HEADER([config/config.h]) @@ -35,7 +35,7 @@ AC_SEARCH_LIBS(clock_gettime, rt) # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([endian.h mach/mach.h machine/endian.h sys/endian.h]) +AC_CHECK_HEADERS([endian.h mach/mach.h machine/endian.h sys/endian.h stdint.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -83,7 +83,7 @@ AC_FUNC_MKTIME AC_TYPE_SIGNAL AC_FUNC_STAT AC_FUNC_STRFTIME -AC_CHECK_FUNCS([bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul]) +AC_CHECK_FUNCS([bzero clock_gettime ftruncate gettimeofday inet_ntoa memset strchr strerror strlcat strlcpy strrchr strstr strtol strtoul pthread_mutex_lock]) # sys/queue.h exists on most systems, but its capabilities vary a great deal. # test for LIST_FIRST and TAILQ_FOREACH_SAFE, which appears to not exist in @@ -106,7 +106,7 @@ AC_DEFINE(HAVE_FULL_QUEUE_H,, Define if queue.h includes LIST_FIRST) # depend on them or it will generate link-time or run-time errors. Test for # just one. AC_TRY_LINK([ - #include <stdlib.h> + #include <stddef.h> extern int auditon(int, void *, int); ], [ @@ -121,6 +121,20 @@ have_audit_syscalls=false ]) AM_CONDITIONAL(HAVE_AUDIT_SYSCALLS, $have_audit_syscalls) +# +# There are a wide variety of endian macros and functions in the wild; we try +# to use the native support if it defines be32enc(), but otherwise have to +# use our own. +# +AC_TRY_LINK([ + #include <sys/endian.h> + #include <stdlib.h> +], [ + be32enc(NULL, 1); +], [ +AC_DEFINE(HAVE_BE32ENC,, Define if be32enc is present) +]) + # Check to see if Mach IPC is used for trigger messages. If so, use Mach IPC # instead of the default for sending trigger messages to the audit components. AC_CHECK_FILE([/usr/include/mach/audit_triggers.defs], [ @@ -139,6 +153,7 @@ AC_CONFIG_FILES([Makefile bin/auditreduce/Makefile bin/praudit/Makefile bsm/Makefile + libauditd/Makefile libbsm/Makefile modules/Makefile modules/auditfilter_noop/Makefile diff --git a/etc/audit_event b/etc/audit_event index 9b528f16f307..577d92af1784 100644 --- a/etc/audit_event +++ b/etc/audit_event @@ -1,5 +1,5 @@ # -# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_event#30 $ +# $P4: //depot/projects/trustedbsd/openbsm/etc/audit_event#34 $ # # The mapping between event identifiers and values is also hard-coded in # audit_kevents.h and audit_uevents.h, so changes must occur in both places, @@ -7,6 +7,20 @@ # those changes. It is advisable not to change the numbering or naming of # kernel audit events. # +# Allocation of BSM event identifier ranges: +# +# 0 Reserved and invalid +# 1 - 2047 Reserved for Solaris kernel events +# 2048 - 5999 Reserved and unallocated +# 6000 - 9999 Reserved for Solaris user events +# 10000 - 32767 Reserved and unallocated +# 32768 - 65535 Available for third party applications +# +# Of the third party range, OpenBSM allocates from the following ranges: +# +# 43000 - 44999 Reserved for OpenBSM kernel events +# 45000 - 46999 Reserved for OpenBSM application events +# 0:AUE_NULL:indir system call:no 1:AUE_EXIT:exit(2):pc 2:AUE_FORK:fork(2):pc @@ -185,6 +199,7 @@ 205:AUE_SETGID:setgid(2):pc 206:AUE_READL:readl(2):no 207:AUE_READVL:readvl(2):no +208:AUE_FSTAT:fstat(2):fa 209:AUE_DUP2:dup2(2):no 210:AUE_MMAP:mmap(2):no 211:AUE_AUDIT:audit(2):ot @@ -534,33 +549,107 @@ 43187:AUE_CAP_GETRIGHTS:cap_getrights(2):fm 43188:AUE_CAP_ENTER:cap_enter(2):pc 43189:AUE_CAP_GETMODE:cap_getmode(2):pc +43190:AUE_POSIX_SPAWN:posix_spawn(2):pc +43191:AUE_FSGETPATH:fsgetpath(2):ot # -# User space system events. +# Solaris userspace events. # +6144:AUE_at_create:at-create atjob:ad +6145:AUE_at_delete:at-delete atjob (at or atrm):ad +6146:AUE_at_perm:at-permission:no +6147:AUE_cron_invoke:cron-invoke:ad +6148:AUE_crontab_create:crontab-crontab created:ad +6149:AUE_crontab_delete:crontab-crontab deleted:ad +6150:AUE_crontab_perm:crontab-permission:no +6151:AUE_inetd_connect:inetd connection:na 6152:AUE_login:login - local:lo 6153:AUE_logout:logout - local:lo +6154:AUE_telnet:login - telnet:lo +6155:AUE_rlogin:login - rlogin:lo +6156:AUE_mountd_mount:mount:na +6157:AUE_mountd_umount:unmount:na +6158:AUE_rshd:rsh access:lo 6159:AUE_su:su(1):lo 6160:AUE_halt:system halt:ad +6161:AUE_reboot:system reboot:ad +6162:AUE_rexecd:rexecd:lo +6163:AUE_passwd:passwd:lo +6164:AUE_rexd:rexd:lo +6165:AUE_ftpd:ftp access:lo +6166:AUE_init:init:lo +6167:AUE_uadmin:uadmin:no 6168:AUE_shutdown:system shutdown:ad -6171:AUE_audit_startup:audit startup:ad -6172:AUE_audit_shutdown:audit shutdown:ad +6168:AUE_poweroff:system poweroff:ad +6170:AUE_crontab_mod:crontab-modify:ad +6171:AUE_ftpd_logout:ftp logout:lo +6172:AUE_ssh:login - ssh:lo +6173:AUE_role_login:role login:lo +6180:AUE_prof_cmd: profile command:ad +6181:AUE_filesystem_add:add filesystem:ad +6182:AUE_filesystem_delete:delete filesystem:ad +6183:AUE_filesystem_modify:modify filesystem:ad +6200:AUE_allocate_succ:allocate-device success:ot +6201:AUE_allocate_fail:allocate-device failure:ot +6202:AUE_deallocate_succ:deallocate-device success:ot +6203:AUE_deallocate_fail:deallocate-device failure:ot +6204:AUE_listdevice_succ:allocate-list devices success:ot +6205:AUE_listdevice_fail:allocate-list devices failure:ot 6207:AUE_create_user:create user:ad 6208:AUE_modify_user:modify user:ad 6209:AUE_delete_user:delete user:ad 6210:AUE_disable_user:disable user:ad -6211:AUE_enable_user::ad -6300:AUE_sudo:sudo(1):ad -6501:AUE_modify_password:modify password:ad -6511:AUE_create_group:create group:ad -6512:AUE_delete_group:delete group:ad -6513:AUE_modify_group:modify group:ad -6514:AUE_add_to_group:add to group:ad -6515:AUE_remove_from_group:remove from group:ad -6521:AUE_revoke_obj:revoke object priv:fm -6600:AUE_lw_login:loginwindow login:lo -6601:AUE_lw_logout:loginwindow logout:lo -7000:AUE_auth_user:user authentication:ad -7001:AUE_ssconn:SecSrvr connection setup:ad -7002:AUE_ssauthorize:SecSrvr AuthEngine:ad -7003:AUE_ssauthint:SecSrvr authinternal mech:ad +6211:AUE_enable_user:enable users:ad +6212:AUE_newgrp_login:newgrp login:lo +6213:AUE_admin_authenticate:admin login:lo +6214:AUE_kadmind_auth:authenticated kadmind request:ua +6215:AUE_kadmind_unauth:unauthenticated kadmind req:ua +6216:AUE_krb5kdc_as_req:kdc authentication svc request:ap +6217:AUE_krb5kdc_tgs_req:kdc tkt-grant svc request:ap +6218:AUE_krb5kdc_tgs_req_2ndtktmm:kdc tgs 2ndtkt mismtch:ap +6219:AUE_krb5kdc_tgs_req_alt_tgt:kdc tgs issue alt tgt:ap +# +# Historic Darwin use of low event numbering space, which collided with the +# Solaris event space. Now obsoleted and new, higher, event numbers assigned +# to make it easier to interpret Solaris events using the OpenBSM tools. +# +6171:AUE_DARWIN_audit_startup:audit startup:ad +6172:AUE_DARWIN_audit_shutdown:audit shutdown:ad +6300:AUE_DARWIN_sudo:sudo(1):ad +6501:AUE_DARWIN_modify_password:modify password:ad +6511:AUE_DARWIN_create_group:create group:ad +6512:AUE_DARWIN_delete_group:delete group:ad +6513:AUE_DARWIN_modify_group:modify group:ad +6514:AUE_DARWIN_add_to_group:add to group:ad +6515:AUE_DARWIN_remove_from_group:remove from group:ad +6521:AUE_DARWIN_revoke_obj:revoke object priv:fm +6600:AUE_DARWIN_lw_login:loginwindow login:lo +6601:AUE_DARWIN_lw_logout:loginwindow logout:lo +7000:AUE_DARWIN_auth_user:user authentication:ad +7001:AUE_DARWIN_ssconn:SecSrvr connection setup:ad +7002:AUE_DARWIN_ssauthorize:SecSrvr AuthEngine:ad +7003:AUE_DARWIN_ssauthint:SecSrvr authinternal mech:ad +# +# Historic/third-party application allocations of event identifiers. +# 32800:AUE_openssh:OpenSSH login:lo +# +# OpenBSM-managed application event space. +# +45000:AUE_audit_startup:audit startup:ad +45001:AUE_audit_shutdown:audit shutdown:ad +45014:AUE_modify_password:modify password:ad +45015:AUE_create_group:create group:ad +45016:AUE_delete_group:delete group:ad +45017:AUE_modify_group:modify group:ad +45018:AUE_add_to_group:add to group:ad +45019:AUE_remove_from_group:remove from group:ad +45020:AUE_revoke_obj:revoke object priv:fm +45021:AUE_lw_login:loginwindow login:lo +45022:AUE_lw_logout:loginwindow logout:lo +45023:AUE_auth_user:user authentication:ad +45024:AUE_ssconn:SecSrvr connection setup:ad +45025:AUE_ssauthorize:SecSrvr AuthEngine:ad +45026:AUE_ssauthint:SecSrvr authinternal mech:ad +45027:AUE_calife:Calife:ad +45028:AUE_sudo:sudo(1):ad +45029:AUE_audit_recovery:audit crash recovery:ad diff --git a/libauditd/Makefile.am b/libauditd/Makefile.am new file mode 100644 index 000000000000..6fab2670d4b6 --- /dev/null +++ b/libauditd/Makefile.am @@ -0,0 +1,17 @@ +# +# $P4: //depot/projects/trustedbsd/openbsm/libauditd/Makefile.am#1 $ +# + +if USE_NATIVE_INCLUDES +INCLUDES = -I$(top_builddir) -I$(top_srcdir) +else +INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/sys +endif + +lib_LTLIBRARIES = libauditd.la + +libauditd_la_SOURCES = \ + auditd_lib.c + +#man3_MANS = \ +# libauditd.3 diff --git a/libauditd/Makefile.in b/libauditd/Makefile.in new file mode 100644 index 000000000000..561e78fc7884 --- /dev/null +++ b/libauditd/Makefile.in @@ -0,0 +1,474 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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/libauditd/Makefile.in#1 $ +# + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +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@ +subdir = libauditd +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__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__installdirs = "$(DESTDIR)$(libdir)" +libLTLIBRARIES_INSTALL = $(INSTALL) +LTLIBRARIES = $(lib_LTLIBRARIES) +libauditd_la_LIBADD = +am_libauditd_la_OBJECTS = auditd_lib.lo +libauditd_la_OBJECTS = $(am_libauditd_la_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@ +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 $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libauditd_la_SOURCES) +DIST_SOURCES = $(libauditd_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +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@ +GREP = @GREP@ +INSTALL = @INSTALL@ +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@ +MAKEINFO = @MAKEINFO@ +MIG = @MIG@ +MKDIR_P = @MKDIR_P@ +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@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +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@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +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) +lib_LTLIBRARIES = libauditd.la +libauditd_la_SOURCES = \ + auditd_lib.c + +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 libauditd/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign libauditd/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-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + f=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + p=$(am__strip_dir) \ + echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ + $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libauditd.la: $(libauditd_la_OBJECTS) $(libauditd_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libauditd_la_OBJECTS) $(libauditd_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auditd_lib.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@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@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@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 + +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)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + 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 $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; 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-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +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-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool 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-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-pdf install-pdf-am \ + install-ps install-ps-am 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-libLTLIBRARIES + + +#man3_MANS = \ +# libauditd.3 +# 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/libauditd/auditd_lib.c b/libauditd/auditd_lib.c new file mode 100644 index 000000000000..d3bee65d3bf7 --- /dev/null +++ b/libauditd/auditd_lib.c @@ -0,0 +1,867 @@ +/*- + * Copyright (c) 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/libauditd/auditd_lib.c#1 $ + */ + +#include <sys/param.h> + +#include <config/config.h> + +#include <sys/dirent.h> +#include <sys/mount.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/stat.h> +#include <sys/time.h> + +#include <netinet/in.h> + +#include <bsm/audit.h> +#include <bsm/audit_uevents.h> +#include <bsm/auditd_lib.h> +#include <bsm/libbsm.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <netdb.h> + +#ifdef __APPLE__ +#include <notify.h> +#ifndef __BSM_INTERNAL_NOTIFY_KEY +#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change" +#endif /* __BSM_INTERNAL_NOTIFY_KEY */ +#endif /* __APPLE__ */ + +/* + * XXX This is temporary until this is moved to <bsm/audit.h> and shared with + * the kernel. + */ +#ifndef AUDIT_HARD_LIMIT_FREE_BLOCKS +#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 +#endif + +struct dir_ent { + char *dirname; + uint8_t softlim; + uint8_t hardlim; + TAILQ_ENTRY(dir_ent) dirs; +}; + +static TAILQ_HEAD(, dir_ent) dir_q; +static int minval = -1; + +static char *auditd_errmsg[] = { + "no error", /* ADE_NOERR ( 0) */ + "could not parse audit_control(5) file", /* ADE_PARSE ( 1) */ + "auditon(2) failed", /* ADE_AUDITON ( 2) */ + "malloc(3) failed", /* ADE_NOMEM ( 3) */ + "all audit log directories over soft limit", /* ADE_SOFTLIM ( 4) */ + "all audit log directories over hard limit", /* ADE_HARDLIM ( 5) */ + "could not create file name string", /* ADE_STRERR ( 6) */ + "could not open audit record", /* ADE_AU_OPEN ( 7) */ + "could not close audit record", /* ADE_AU_CLOSE ( 8) */ + "could not set active audit session state", /* ADE_SETAUDIT ( 9) */ + "auditctl(2) failed (trail still swapped)", /* ADE_ACTL (10) */ + "auditctl(2) failed (trail not swapped)", /* ADE_ACTLERR (11) */ + "could not swap audit trail file", /* ADE_SWAPERR (12) */ + "could not rename crash recovery file", /* ADE_RENAME (13) */ + "could not read 'current' link file", /* ADE_READLINK (14) */ + "could not create 'current' link file", /* ADE_SYMLINK (15) */ + "invalid argument", /* ADE_INVAL (16) */ + "could not resolve hostname to address", /* ADE_GETADDR (17) */ + "address family not supported", /* ADE_ADDRFAM (18) */ +}; + +#define MAXERRCODE (sizeof(auditd_errmsg) / sizeof(auditd_errmsg[0])) + +#define NA_EVENT_STR_SIZE 25 +#define POL_STR_SIZE 128 + + +/* + * Look up and return the error string for the given audit error code. + */ +const char * +auditd_strerror(int errcode) +{ + int idx = -errcode; + + if (idx < 0 || idx > (int)MAXERRCODE) + return ("Invalid auditd error code"); + + return (auditd_errmsg[idx]); +} + + +/* + * Free our local list of directory names and init list + */ +static void +free_dir_q(void) +{ + struct dir_ent *d1, *d2; + + d1 = TAILQ_FIRST(&dir_q); + while (d1 != NULL) { + d2 = TAILQ_NEXT(d1, dirs); + free(d1->dirname); + free(d1); + d1 = d2; + } + TAILQ_INIT(&dir_q); +} + +/* + * Concat the directory name to the given file name. + * XXX We should affix the hostname also + */ +static char * +affixdir(char *name, struct dir_ent *dirent) +{ + char *fn = NULL; + + /* + * Sanity check on file name. + */ + if (strlen(name) != (FILENAME_LEN - 1)) { + errno = EINVAL; + return (NULL); + } + + asprintf(&fn, "%s/%s", dirent->dirname, name); + return (fn); +} + +/* + * Insert the directory entry in the list by the way they are ordered in + * audit_control(5). Move the entries that are over the soft and hard limits + * toward the tail. + */ +static void +insert_orderly(struct dir_ent *denew) +{ + struct dir_ent *dep; + + TAILQ_FOREACH(dep, &dir_q, dirs) { + if (dep->softlim == 1 && denew->softlim == 0) { + TAILQ_INSERT_BEFORE(dep, denew, dirs); + return; + } + if (dep->hardlim == 1 && denew->hardlim == 0) { + TAILQ_INSERT_BEFORE(dep, denew, dirs); + return; + } + } + TAILQ_INSERT_TAIL(&dir_q, denew, dirs); +} + +/* + * Get the host from audit_control(5) and set it in the audit kernel + * information. Return: + * ADE_NOERR on success. + * ADE_PARSE error parsing audit_control(5). + * ADE_AUDITON error getting/setting auditon(2) value. + * ADE_GETADDR error getting address info for host. + * ADE_ADDRFAM un-supported address family. + */ +int +auditd_set_host(void) +{ + char hoststr[MAXHOSTNAMELEN]; + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin; + struct addrinfo *res; + struct auditinfo_addr aia; + int error, ret = ADE_NOERR; + + if (getachost(hoststr, MAXHOSTNAMELEN) != 0) { + + ret = ADE_PARSE; + + /* + * 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. + */ + bzero(&aia, sizeof(aia)); + aia.ai_termid.at_type = AU_IPv4; + error = auditon(A_SETKAUDIT, &aia, sizeof(aia)); + if (error < 0 && errno != ENOSYS) + ret = ADE_AUDITON; + return (ret); + } + error = getaddrinfo(hoststr, NULL, NULL, &res); + if (error) + return (ADE_GETADDR); + 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; + break; + + default: + /* Un-supported address family in host parameter. */ + errno = EAFNOSUPPORT; + return (ADE_ADDRFAM); + } + + if (auditon(A_SETKAUDIT, &aia, sizeof(aia)) < 0) + ret = ADE_AUDITON; + + return (ret); +} + +/* + * Get the min percentage of free blocks from audit_control(5) and that + * value in the kernel. Return: + * ADE_NOERR on success, + * ADE_PARSE error parsing audit_control(5), + * ADE_AUDITON error getting/setting auditon(2) value. + */ +int +auditd_set_minfree(void) +{ + au_qctrl_t qctrl; + + if (getacmin(&minval) != 0) + return (ADE_PARSE); + + if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) + return (ADE_AUDITON); + + if (qctrl.aq_minfree != minval) { + qctrl.aq_minfree = minval; + if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) + return (ADE_AUDITON); + } + + return (0); +} + +/* + * Parses the "dir" entry in audit_control(5) into an ordered list. Also, will + * set the minfree value if not already set. Arguments include function + * pointers to audit_warn functions for soft and hard limits. Returns: + * ADE_NOERR on success, + * ADE_PARSE error parsing audit_control(5), + * ADE_AUDITON error getting/setting auditon(2) value, + * ADE_NOMEM error allocating memory, + * ADE_SOFTLIM if all the directories are over the soft limit, + * ADE_HARDLIM if all the directories are over the hard limit, + */ +int +auditd_read_dirs(int (*warn_soft)(char *), int (*warn_hard)(char *)) +{ + char cur_dir[MAXNAMLEN]; + struct dir_ent *dirent; + struct statfs sfs; + int err; + char soft, hard; + int tcnt = 0; + int scnt = 0; + int hcnt = 0; + + if (minval == -1 && (err = auditd_set_minfree()) != 0) + return (err); + + /* + * Init directory q. Force a re-read of the file the next time. + */ + free_dir_q(); + endac(); + + /* + * Read the list of directories into an ordered linked list + * admin's preference, then those over soft limit and, finally, + * those over the hard limit. + * + * XXX We should use the reentrant interfaces once they are + * available. + */ + while (getacdir(cur_dir, MAXNAMLEN) >= 0) { + if (statfs(cur_dir, &sfs) < 0) + continue; /* XXX should warn */ + soft = (sfs.f_bfree < (sfs.f_blocks / (100 / minval))) ? 1 : 0; + hard = (sfs.f_bfree < AUDIT_HARD_LIMIT_FREE_BLOCKS) ? 1 : 0; + if (soft) { + if (warn_soft) + (*warn_soft)(cur_dir); + scnt++; + } + if (hard) { + if (warn_hard) + (*warn_hard)(cur_dir); + hcnt++; + } + dirent = (struct dir_ent *) malloc(sizeof(struct dir_ent)); + if (dirent == NULL) + return (ADE_NOMEM); + dirent->softlim = soft; + dirent->hardlim = hard; + dirent->dirname = (char *) malloc(MAXNAMLEN); + if (dirent->dirname == NULL) { + free(dirent); + return (ADE_NOMEM); + } + strlcpy(dirent->dirname, cur_dir, MAXNAMLEN); + insert_orderly(dirent); + tcnt++; + } + + if (hcnt == tcnt) + return (ADE_HARDLIM); + if (scnt == tcnt) + return (ADE_SOFTLIM); + return (0); +} + +void +auditd_close_dirs(void) +{ + free_dir_q(); + minval = -1; +} + + +/* + * Process the audit event file, obtaining a class mapping for each event, and + * set that mapping into the kernel. Return: + * n number of event mappings that were successfully processed, + * ADE_NOMEM if there was an error allocating memory. + */ +int +auditd_set_evcmap(void) +{ + au_event_ent_t ev, *evp; + au_evclass_map_t evc_map; + int ctr = 0; + + + /* + * 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); + return (ADE_NOMEM); + } + + /* + * 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) + ctr++; + } + endauevent(); + free(ev.ae_name); + free(ev.ae_desc); + + return (ctr); +} + +/* + * Get the non-attributable event string and set the kernel mask. Return: + * ADE_NOERR on success, + * ADE_PARSE error parsing audit_control(5), + * ADE_AUDITON error setting the mask using auditon(2). + */ +int +auditd_set_namask(void) +{ + au_mask_t aumask; + char naeventstr[NA_EVENT_STR_SIZE]; + + if ((getacna(naeventstr, NA_EVENT_STR_SIZE) != 0) || + (getauditflagsbin(naeventstr, &aumask) != 0)) + return (ADE_PARSE); + + if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))) + return (ADE_AUDITON); + + return (ADE_NOERR); +} + +/* + * Set the audit control policy if a policy is configured in audit_control(5), + * implement the policy. However, if one isn't defined or if there is an error + * parsing the control file, set AUDIT_CNT to avoid leaving the system in a + * fragile state. Return: + * ADE_NOERR on success, + * ADE_PARSE error parsing audit_control(5), + * ADE_AUDITON error setting policy using auditon(2). + */ +int +auditd_set_policy(void) +{ + long policy; + char polstr[POL_STR_SIZE]; + + if ((getacpol(polstr, POL_STR_SIZE) != 0) || + (au_strtopol(polstr, &policy) != 0)) { + policy = AUDIT_CNT; + if (auditon(A_SETPOLICY, &policy, sizeof(policy))) + return (ADE_AUDITON); + return (ADE_PARSE); + } + + if (auditon(A_SETPOLICY, &policy, sizeof(policy))) + return (ADE_AUDITON); + + return (ADE_NOERR); +} + +/* + * Set trail rotation size. Return: + * ADE_NOERR on success, + * ADE_PARSE error parsing audit_control(5), + * ADE_AUDITON error setting file size using auditon(2). + */ +int +auditd_set_fsize(void) +{ + size_t filesz; + au_fstat_t au_fstat; + + /* + * Set trail rotation size. + */ + if (getacfilesz(&filesz) != 0) + return (ADE_PARSE); + + bzero(&au_fstat, sizeof(au_fstat)); + au_fstat.af_filesz = filesz; + if (auditon(A_SETFSIZE, &au_fstat, sizeof(au_fstat)) < 0) + return (ADE_AUDITON); + + return (ADE_NOERR); +} + +/* + * Create the new audit file with appropriate permissions and ownership. Try + * to clean up if something goes wrong. + */ +static int +open_trail(char *fname, gid_t gid) +{ + int error, fd; + + fd = open(fname, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP); + if (fd < 0) + return (-1); + if (fchown(fd, -1, gid) < 0) { + error = errno; + close(fd); + (void)unlink(fname); + errno = error; + return (-1); + } + return (fd); +} + +/* + * Create the new audit trail file, swap with existing audit file. Arguments + * include timestamp for the filename, a pointer to a string for returning the + * new file name, GID for trail file, and audit_warn function pointer for + * 'getacdir()' errors. Returns: + * ADE_NOERR on success, + * ADE_STRERR if the file name string could not be created, + * ADE_SWAPERR if the audit trail file could not be swapped, + * ADE_ACTL if the auditctl(2) call failed but file swap still + * successful. + * ADE_ACTLERR if the auditctl(2) call failed and file swap failed. + * ADE_SYMLINK if symlink(2) failed updating the current link. + */ +int +auditd_swap_trail(char *TS, char **newfile, gid_t gid, + int (*warn_getacdir)(char *)) +{ + char timestr[FILENAME_LEN]; + char *fn; + struct dir_ent *dirent; + int fd; + int error; + int saverrno = 0; + + if (strlen(TS) != (TIMESTAMP_LEN - 1) || + snprintf(timestr, FILENAME_LEN, "%s.%s", TS, NOT_TERMINATED) < 0) { + errno = EINVAL; + return (ADE_STRERR); + } + + /* Try until we succeed. */ + while ((dirent = TAILQ_FIRST(&dir_q))) { + if (dirent->hardlim) + continue; + if ((fn = affixdir(timestr, dirent)) == NULL) + return (ADE_STRERR); + + /* + * Create and open the file; then close and pass to the + * kernel if all went well. + */ + fd = open_trail(fn, gid); + if (fd >= 0) { + error = auditctl(fn); + if (error) { + /* + * auditctl failed setting log file. + * Try again. + */ + saverrno = errno; + close(fd); + } else { + /* Success. */ + *newfile = fn; + close(fd); + if (error) + return (error); + if (saverrno) { + /* + * auditctl() failed but still + * successful. Return errno and "soft" + * error. + */ + errno = saverrno; + return (ADE_ACTL); + } + return (ADE_NOERR); + } + } + + /* + * Tell the administrator about lack of permissions for dir. + */ + if (warn_getacdir != NULL) + (*warn_getacdir)(dirent->dirname); + } + if (saverrno) { + errno = saverrno; + return (ADE_ACTLERR); + } else + return (ADE_SWAPERR); +} + +/* + * Mask calling process from being audited. Returns: + * ADE_NOERR on success, + * ADE_SETAUDIT if setaudit(2) fails. + */ +int +auditd_prevent_audit(void) +{ + auditinfo_t ai; + + /* + * To prevent event feedback cycles and avoid audit becoming stalled if + * auditing is suspended we mask this processes events from being + * audited. We allow the uid, tid, and mask fields to be implicitly + * set to zero, but do set the audit session ID to the PID. + * + * XXXRW: Is there more to it than this? + */ + bzero(&ai, sizeof(ai)); + ai.ai_asid = getpid(); + if (setaudit(&ai) != 0) + return (ADE_SETAUDIT); + return (ADE_NOERR); +} + +/* + * Generate and submit audit record for audit startup or shutdown. The event + * argument can be AUE_audit_recovery, AUE_audit_startup or + * AUE_audit_shutdown. The path argument will add a path token, if not NULL. + * Returns: + * AUE_NOERR on success, + * ADE_NOMEM if memory allocation fails, + * ADE_AU_OPEN if au_open(3) fails, + * ADE_AU_CLOSE if au_close(3) fails. + */ +int +auditd_gen_record(int event, char *path) +{ + int aufd; + uid_t uid; + pid_t pid; + char *autext = NULL; + token_t *tok; + struct auditinfo_addr aia; + + if (event == AUE_audit_startup) + asprintf(&autext, "%s::Audit startup", getprogname()); + else if (event == AUE_audit_shutdown) + asprintf(&autext, "%s::Audit shutdown", getprogname()); + else if (event == AUE_audit_recovery) + asprintf(&autext, "%s::Audit recovery", getprogname()); + else + return (ADE_INVAL); + if (autext == NULL) + return (ADE_NOMEM); + + if ((aufd = au_open()) == -1) { + free(autext); + return (ADE_AU_OPEN); + } + bzero(&aia, sizeof(aia)); + uid = getuid(); pid = getpid(); + if ((tok = au_to_subject32_ex(uid, geteuid(), getegid(), uid, getgid(), + pid, pid, &aia.ai_termid)) != NULL) + au_write(aufd, tok); + if ((tok = au_to_text(autext)) != NULL) + au_write(aufd, tok); + free(autext); + if (path != NULL && (tok = au_to_path(path)) != NULL) + au_write(aufd, tok); + if ((tok = au_to_return32(0, 0)) != NULL) + au_write(aufd, tok); + if (au_close(aufd, 1, event) == -1) + return (ADE_AU_CLOSE); + + return (ADE_NOERR); +} + +/* + * Check for a 'current' symlink and do crash recovery, if needed. Create a new + * 'current' symlink. The argument 'curfile' is the file the 'current' symlink + * should point to. Returns: + * ADE_NOERR on success, + * ADE_AU_OPEN if au_open(3) fails, + * ADE_AU_CLOSE if au_close(3) fails. + * ADE_RENAME if error renaming audit trail file, + * ADE_READLINK if error reading the 'current' link, + * ADE_SYMLINK if error creating 'current' link. + */ +int +auditd_new_curlink(char *curfile) +{ + int len, err; + char *ptr; + char *path = NULL; + struct stat sb; + char recoveredname[MAXPATHLEN]; + char newname[MAXPATHLEN]; + + /* + * Check to see if audit was shutdown properly. If not, clean up, + * recover previous audit trail file, and generate audit record. + */ + len = readlink(AUDIT_CURRENT_LINK, recoveredname, MAXPATHLEN - 1); + if (len > 0) { + /* 'current' exist but is it pointing at a valid file? */ + recoveredname[len++] = '\0'; + if (stat(recoveredname, &sb) == 0) { + /* Yes, rename it to a crash recovery file. */ + strlcpy(newname, recoveredname, MAXPATHLEN); + + if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) { + strlcpy(ptr, CRASH_RECOVERY, TIMESTAMP_LEN); + if (rename(recoveredname, newname) != 0) + return (ADE_RENAME); + } else + return (ADE_STRERR); + + path = newname; + } + + /* 'current' symlink is (now) invalid so remove it. */ + (void) unlink(AUDIT_CURRENT_LINK); + + /* Note the crash recovery in current audit trail */ + err = auditd_gen_record(AUE_audit_recovery, path); + if (err) + return (err); + } + + if (len < 0 && errno != ENOENT) + return (ADE_READLINK); + + if (symlink(curfile, AUDIT_CURRENT_LINK) != 0) + return (ADE_SYMLINK); + + return (0); +} + +/* + * Do just what we need to quickly start auditing. Assume no system logging or + * notify. Return: + * 0 on success, + * -1 on failure. + */ +int +audit_quick_start(void) +{ + int err; + char *newfile; + time_t tt; + char TS[TIMESTAMP_LEN]; + + /* + * Mask auditing of this process. + */ + if (auditd_prevent_audit() != 0) + return (-1); + + /* + * Read audit_control and get log directories. + */ + err = auditd_read_dirs(NULL, NULL); + if (err != ADE_NOERR && err != ADE_SOFTLIM) + return (-1); + + /* + * Create a new audit trail log. + */ + if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0) + return (-1); + err = auditd_swap_trail(TS, &newfile, getgid(), NULL); + if (err != ADE_NOERR && err != ADE_ACTL) + return (-1); + + /* + * Add the current symlink and recover from crash, if needed. + */ + if (auditd_new_curlink(newfile) != 0) + return(-1); + + /* + * At this point auditing has started so generate audit start-up record. + */ + if (auditd_gen_record(AUE_audit_startup, NULL) != 0) + return (-1); + + /* + * Configure the audit controls. + */ + (void) auditd_set_evcmap(); + (void) auditd_set_namask(); + (void) auditd_set_policy(); + (void) auditd_set_fsize(); + (void) auditd_set_minfree(); + (void) auditd_set_host(); + + return (0); +} + +/* + * Shut down auditing quickly. Assumes that is only called on system shutdown. + * Returns: + * 0 on success, + * -1 on failure. + */ +int +audit_quick_stop(void) +{ + int len; + long cond; + char *ptr; + time_t tt; + char oldname[MAXPATHLEN]; + char newname[MAXPATHLEN]; + char TS[TIMESTAMP_LEN]; + + /* + * Auditing already disabled? + */ + if (auditon(A_GETCOND, &cond, sizeof(cond)) < 0) + return (-1); + if (cond == AUC_DISABLED) + return (0); + + /* + * Generate audit shutdown record. + */ + (void) auditd_gen_record(AUE_audit_shutdown, NULL); + + /* + * Shutdown auditing in the kernel. + */ + cond = AUC_DISABLED; + if (auditon(A_SETCOND, &cond, sizeof(cond)) != 0) + return (-1); +#ifdef __BSM_INTERNAL_NOTIFY_KEY + notify_post(__BSM_INTERNAL_NOTIFY_KEY); +#endif + + /* + * Rename last audit trail and remove 'current' link. + */ + len = readlink(AUDIT_CURRENT_LINK, oldname, MAXPATHLEN - 1); + if (len < 0) + return (-1); + oldname[len++] = '\0'; + + if (getTSstr(tt, TS, TIMESTAMP_LEN) != 0) + return (-1); + + strlcpy(newname, oldname, len); + + if ((ptr = strstr(newname, NOT_TERMINATED)) != NULL) { + strlcpy(ptr, TS, TIMESTAMP_LEN); + if (rename(oldname, newname) != 0) + return (-1); + } else + return (-1); + + (void) unlink(AUDIT_CURRENT_LINK); + + return (0); +} diff --git a/libbsm/Makefile.am b/libbsm/Makefile.am index d4e31fea55b8..b2f1e5c62c78 100644 --- a/libbsm/Makefile.am +++ b/libbsm/Makefile.am @@ -1,5 +1,5 @@ # -# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.am#5 $ +# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.am#7 $ # if USE_NATIVE_INCLUDES @@ -14,6 +14,7 @@ libbsm_la_SOURCES = \ bsm_audit.c \ bsm_class.c \ bsm_control.c \ + bsm_errno.c \ bsm_event.c \ bsm_flags.c \ bsm_io.c \ @@ -30,6 +31,7 @@ endif man3_MANS = \ au_class.3 \ au_control.3 \ + au_errno.3 \ au_event.3 \ au_free_token.3 \ au_io.3 \ diff --git a/libbsm/Makefile.in b/libbsm/Makefile.in index dd09ce00d0cf..ffd354dfbb84 100644 --- a/libbsm/Makefile.in +++ b/libbsm/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.in#9 $ +# $P4: //depot/projects/trustedbsd/openbsm/libbsm/Makefile.in#12 $ # VPATH = @srcdir@ @@ -60,13 +60,13 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libbsm_la_LIBADD = am__libbsm_la_SOURCES_DIST = bsm_audit.c bsm_class.c bsm_control.c \ - bsm_event.c bsm_flags.c bsm_io.c bsm_mask.c bsm_token.c \ - bsm_user.c bsm_notify.c bsm_wrappers.c + bsm_errno.c bsm_event.c bsm_flags.c bsm_io.c bsm_mask.c \ + bsm_token.c bsm_user.c bsm_notify.c bsm_wrappers.c @HAVE_AUDIT_SYSCALLS_TRUE@am__objects_1 = bsm_notify.lo \ @HAVE_AUDIT_SYSCALLS_TRUE@ bsm_wrappers.lo am_libbsm_la_OBJECTS = bsm_audit.lo bsm_class.lo bsm_control.lo \ - bsm_event.lo bsm_flags.lo bsm_io.lo bsm_mask.lo bsm_token.lo \ - bsm_user.lo $(am__objects_1) + bsm_errno.lo bsm_event.lo bsm_flags.lo bsm_io.lo bsm_mask.lo \ + bsm_token.lo bsm_user.lo $(am__objects_1) libbsm_la_OBJECTS = $(am_libbsm_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(top_builddir)/config@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/config/depcomp @@ -199,12 +199,13 @@ 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) lib_LTLIBRARIES = libbsm.la -libbsm_la_SOURCES = bsm_audit.c bsm_class.c bsm_control.c bsm_event.c \ - bsm_flags.c bsm_io.c bsm_mask.c bsm_token.c bsm_user.c \ - $(am__append_1) +libbsm_la_SOURCES = bsm_audit.c bsm_class.c bsm_control.c bsm_errno.c \ + bsm_event.c bsm_flags.c bsm_io.c bsm_mask.c bsm_token.c \ + bsm_user.c $(am__append_1) man3_MANS = \ au_class.3 \ au_control.3 \ + au_errno.3 \ au_event.3 \ au_free_token.3 \ au_io.3 \ @@ -286,6 +287,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_audit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_class.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_control.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_errno.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_event.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_flags.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_io.Plo@am__quote@ diff --git a/libbsm/au_errno.3 b/libbsm/au_errno.3 new file mode 100644 index 000000000000..f7ff8a0c7a1f --- /dev/null +++ b/libbsm/au_errno.3 @@ -0,0 +1,111 @@ +.\"- +.\" Copyright (c) 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/libbsm/au_errno.3#3 $ +.\" +.Dd December 8, 2008 +.Dt AU_BSM_TO_ERRNO 3 +.Os +.Sh NAME +.Nm au_bsm_to_errno , +.Nm au_errno_to_bsm , +.Nm au_strerror +.Nd "convert between BSM and local error numbers" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_bsm_to_errno "u_char bsm_error" "int *errorp" +.Ft u_char +.Fn au_errno_to_bsm "int error" +.Ft const char * +.Fn au_strerror "int bsm_error" +.Sh DESCRIPTION +These interfaces may be used to convert between the local ( +.Xr errno 2 ) +and BSM error number spaces found in BSM return tokens. +.Pp +The +.Fn au_bsm_to_errno +function accepts a BSM error value, +.Fa bsm_error, +and converts it to an +.Xr errno 2 +that will be stored in the integer pointed to by +.Fa errorp +if successful. +This call will fail if the BSM error cannot be mapped into a local error +number, which may occur if the return token was generated on another +operating system. +.Pp +.Fn au_errno_to_bsm +function accepts a local +.Xr errno 2 +value, and returns the BSM error number for it. +This call cannot fail, and instead returns a BSM error number indicating to +a later decoder that the error could not be encoded. +.Pp +The +.Fn au_strerror +converts a BSM error value to a string, generally by converting first to a +local error number and using the local +.Xr strerror 3 +function, but will also work for errors that are not locally defined. +.Sh RETURN VALULES +On success, +.Fn au_bsm_to_errno +returns 0 and a converted error value; on failure, it returns -1 but does not +set +.Xr errno 2 . +.Pp +On success, +.Fn au_strerror +returns a pointer to an error string; on failure it will return +.Dv NULL . +.Sh SEE ALSO +.Xr au_to_return 3 , +.Xr au_to_return32 3 , +.Xr au_to_return64 3 , +.Xr libbsm 3 +.Sh HISTORY +.Fn au_bsm_to_errno +and +.Fn au_errno_to_bsm +were introduced in OpenBSM 1.1. +.Sh AUTHORS +These functions were implemented by +.An Robert Watson +under contract to Apple Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +.Nm au_strerror +is unable to provide localized strings for errors not available in the local +operating system. diff --git a/libbsm/au_token.3 b/libbsm/au_token.3 index cb8ef7064091..28d195e366ac 100644 --- a/libbsm/au_token.3 +++ b/libbsm/au_token.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_token.3#15 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/au_token.3#16 $ .\" .Dd April 19, 2005 .Dt AU_TOKEN 3 @@ -209,6 +209,15 @@ These interfaces support the allocation of BSM audit tokens, represented by .Vt token_t , for various data types. +.Pp +.Xr au_errno_to_bsm 3 +must be used to convert local +.Xr errno 2 +errors to BSM error numbers before they are passed to +.Fn au_to_return , +.Fn au_to_return32 , +and +.Fn au_to_return64 . .Sh RETURN VALUES On success, a pointer to a .Vt token_t @@ -221,6 +230,7 @@ On failure, will be returned, and an error condition returned via .Va errno . .Sh SEE ALSO +.Xr au_errno_to_bsm 3 , .Xr libbsm 3 .Sh HISTORY The OpenBSM implementation was created by McAfee Research, the security diff --git a/libbsm/audit_submit.3 b/libbsm/audit_submit.3 index 6a61d997e535..80a2578e3298 100644 --- a/libbsm/audit_submit.3 +++ b/libbsm/audit_submit.3 @@ -27,7 +27,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/libbsm/audit_submit.3#14 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/audit_submit.3#15 $ .\" .Dd January 18, 2008 .Dt audit_submit 3 @@ -58,7 +58,10 @@ The return token is dependent on the .Fa status and .Fa reterr -arguments. +arguments; unlike the argument to +.Xr au_to_return , +.Fa reterr +should be a local rather than BSM error number. Optionally, a text token will be created as a part of this record. .Pp Text token output is under the control of a diff --git a/libbsm/bsm_audit.c b/libbsm/bsm_audit.c index 2fd9466a5dad..3510639d9667 100644 --- a/libbsm/bsm_audit.c +++ b/libbsm/bsm_audit.c @@ -30,7 +30,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/libbsm/bsm_audit.c#31 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_audit.c#34 $ */ #include <sys/types.h> @@ -48,7 +48,9 @@ #include <netinet/in.h> #include <errno.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdlib.h> #include <string.h> @@ -65,7 +67,9 @@ static int audit_rec_count = 0; */ static LIST_HEAD(, au_record) audit_free_q; +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* * This call frees a token_t and its internal data. @@ -93,7 +97,9 @@ au_open(void) { au_record_t *rec = NULL; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (audit_rec_count == 0) LIST_INIT(&audit_free_q); @@ -108,7 +114,9 @@ au_open(void) LIST_REMOVE(rec, au_rec_q); } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif if (rec == NULL) { /* @@ -125,10 +133,14 @@ au_open(void) return (-1); } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (audit_rec_count == MAX_AUDIT_RECORDS) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif free(rec->data); free(rec); @@ -140,7 +152,9 @@ au_open(void) open_desc_table[audit_rec_count] = rec; audit_rec_count++; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } @@ -221,7 +235,7 @@ au_assemble(au_record_t *rec, short event) aia.ai_termid.at_type = AU_IPv4; aia.ai_termid.at_addr[0] = INADDR_ANY; if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) { - if (errno != ENOSYS) + if (errno != ENOSYS && errno != EPERM) return (-1); #endif /* HAVE_AUDIT_SYSCALLS */ tot_rec_size = rec->len + AUDIT_HEADER_SIZE + @@ -242,6 +256,8 @@ au_assemble(au_record_t *rec, short event) (IN6_IS_ADDR_UNSPECIFIED(aptr)) ? AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&aia); break; + default: + return (-1); } tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE; /* @@ -299,12 +315,16 @@ au_teardown(au_record_t *rec) rec->used = 0; rec->len = 0; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif /* Add the record to the freelist tail */ LIST_INSERT_HEAD(&audit_free_q, rec, au_rec_q); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } #ifdef HAVE_AUDIT_SYSCALLS diff --git a/libbsm/bsm_class.c b/libbsm/bsm_class.c index 0acfed484a5f..1978e442c650 100644 --- a/libbsm/bsm_class.c +++ b/libbsm/bsm_class.c @@ -27,7 +27,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/libbsm/bsm_class.c#14 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_class.c#15 $ */ #include <config/config.h> @@ -35,7 +35,9 @@ #include <bsm/libbsm.h> #include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdio.h> #include <stdlib.h> @@ -51,7 +53,9 @@ static FILE *fp = NULL; static char linestr[AU_LINE_MAX]; static const char *classdelim = ":"; +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* * Parse a single line from the audit_class file passed in str to the struct @@ -133,9 +137,13 @@ getauclassent_r(struct au_class_ent *c) { struct au_class_ent *cp; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif cp = getauclassent_r_locked(c); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (cp); } @@ -152,9 +160,13 @@ getauclassent(void) c.ac_name = class_ent_name; c.ac_desc = class_ent_desc; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif cp = getauclassent_r_locked(&c); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (cp); } @@ -175,9 +187,13 @@ void setauclass(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauclass_locked(); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -191,15 +207,21 @@ getauclassnam_r(struct au_class_ent *c, const char *name) if (name == NULL) return (NULL); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauclass_locked(); while ((cp = getauclassent_r_locked(c)) != NULL) { if (strcmp(name, cp->ac_name) == 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (cp); } } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (NULL); } @@ -230,13 +252,17 @@ getauclassnum_r(struct au_class_ent *c, au_class_t class_number) { struct au_class_ent *cp; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauclass_locked(); while ((cp = getauclassent_r_locked(c)) != NULL) { if (class_number == cp->ac_class) return (cp); } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (NULL); } @@ -263,10 +289,14 @@ void endauclass(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (fp != NULL) { fclose(fp); fp = NULL; } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } diff --git a/libbsm/bsm_control.c b/libbsm/bsm_control.c index 96cbc23106ec..4fed3ff1c2d4 100644 --- a/libbsm/bsm_control.c +++ b/libbsm/bsm_control.c @@ -27,7 +27,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/libbsm/bsm_control.c#23 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#24 $ */ #include <config/config.h> @@ -36,7 +36,9 @@ #include <errno.h> #include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdio.h> #include <stdlib.h> @@ -58,7 +60,9 @@ static char *delim = ":"; static char inacdir = 0; static char ptrmoved = 0; +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* * Returns the string value corresponding to the given label from the @@ -318,9 +322,13 @@ void setac(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -330,13 +338,17 @@ void endac(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif ptrmoved = 1; if (fp != NULL) { fclose(fp); fp = NULL; } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -352,7 +364,9 @@ getacdir(char *name, int len) * Check if another function was called between successive calls to * getacdir. */ +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (inacdir && ptrmoved) { ptrmoved = 0; if (fp != NULL) @@ -360,19 +374,27 @@ getacdir(char *name, int len) ret = 2; } if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (dir == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-1); } if (strlen(dir) >= (size_t)len) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-3); } strlcpy(name, dir, len); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (ret); } @@ -384,18 +406,26 @@ getacmin(int *min_val) { char *min; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (min == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (1); } *min_val = atoi(min); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } @@ -408,20 +438,28 @@ getacfilesz(size_t *filesz_val) char *filesz, *dummy; long long ll; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &filesz) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (filesz == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif errno = EINVAL; return (1); } ll = strtoll(filesz, &dummy, 10); if (*dummy != '\0') { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif errno = EINVAL; return (-1); } @@ -430,12 +468,16 @@ getacfilesz(size_t *filesz_val) * indicates no rotation size. */ if (ll < 0 || (ll > 0 && ll < MIN_AUDIT_FILE_SIZE)) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif errno = EINVAL; return (-1); } *filesz_val = ll; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } @@ -447,22 +489,32 @@ getacflg(char *auditstr, int len) { char *str; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (str == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (1); } if (strlen(str) >= (size_t)len) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-3); } strlcpy(auditstr, str, len); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } @@ -474,22 +526,32 @@ getacna(char *auditstr, int len) { char *str; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (str == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (1); } if (strlen(str) >= (size_t)len) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-3); } strlcpy(auditstr, str, len); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } @@ -501,22 +563,32 @@ getacpol(char *auditstr, size_t len) { char *str; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (str == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-1); } if (strlen(str) >= len) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-3); } strlcpy(auditstr, str, len); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } @@ -525,21 +597,31 @@ getachost(char *auditstr, size_t len) { char *str; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setac_locked(); if (getstrfromtype_locked(AUDIT_HOST_CONTROL_ENTRY, &str) < 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-2); } if (str == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (1); } if (strlen(str) >= len) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-3); } strcpy(auditstr, str); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (0); } diff --git a/libbsm/bsm_errno.c b/libbsm/bsm_errno.c new file mode 100644 index 000000000000..e6f41d3796c8 --- /dev/null +++ b/libbsm/bsm_errno.c @@ -0,0 +1,642 @@ +/*- + * Copyright (c) 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/libbsm/bsm_errno.c#12 $ + */ + +#include <sys/types.h> + +#include <config/config.h> + +#include <bsm/audit_errno.h> +#include <bsm/libbsm.h> + +#include <errno.h> +#include <string.h> + +/* + * Different operating systems use different numeric constants for different + * error numbers, and sometimes error numbers don't exist in more than one + * operating system. These routines convert between BSM and local error + * number spaces, subject to the above realities. BSM error numbers are + * stored in a single 8-bit character, so don't have a byte order. + */ + +struct bsm_errors { + int be_bsm_error; + int be_os_error; + const char *be_strerror; +}; + +#define ERRNO_NO_LOCAL_MAPPING -600 + +/* + * Mapping table -- please maintain in numeric sorted order with respect to + * the BSM constant. Today we do a linear lookup, but could switch to a + * binary search if it makes sense. We only ifdef errors that aren't + * generally available, but it does make the table a lot more ugly. + * + * XXXRW: It would be nice to have a similar ordered table mapping to BSM + * constant from local constant, but the order of local constants varies by + * OS. Really we need to build that table at compile-time but don't do that + * yet. + * + * XXXRW: We currently embed English-language error strings here, but should + * support catalogues; these are only used if the OS doesn't have an error + * string using strerror(3). + */ +static const struct bsm_errors bsm_errors[] = { + { BSM_ESUCCESS, 0, "Success" }, + { BSM_EPERM, EPERM, "Operation not permitted" }, + { BSM_ENOENT, ENOENT, "No such file or directory" }, + { BSM_ESRCH, ESRCH, "No such process" }, + { BSM_EINTR, EINTR, "Interrupted system call" }, + { BSM_EIO, EIO, "Input/output error" }, + { BSM_ENXIO, ENXIO, "Device not configured" }, + { BSM_E2BIG, E2BIG, "Argument list too long" }, + { BSM_ENOEXEC, ENOEXEC, "Exec format error" }, + { BSM_EBADF, EBADF, "BAd file descriptor" }, + { BSM_ECHILD, ECHILD, "No child processes" }, + { BSM_EAGAIN, EAGAIN, "Resource temporarily unavailable" }, + { BSM_ENOMEM, ENOMEM, "Cannot allocate memory" }, + { BSM_EACCES, EACCES, "Permission denied" }, + { BSM_EFAULT, EFAULT, "Bad address" }, + { BSM_ENOTBLK, ENOTBLK, "Block device required" }, + { BSM_EBUSY, EBUSY, "Device busy" }, + { BSM_EEXIST, EEXIST, "File exists" }, + { BSM_EXDEV, EXDEV, "Cross-device link" }, + { BSM_ENODEV, ENODEV, "Operation not supported by device" }, + { BSM_ENOTDIR, ENOTDIR, "Not a directory" }, + { BSM_EISDIR, EISDIR, "Is a directory" }, + { BSM_EINVAL, EINVAL, "Invalid argument" }, + { BSM_ENFILE, ENFILE, "Too many open files in system" }, + { BSM_EMFILE, EMFILE, "Too many open files" }, + { BSM_ENOTTY, ENOTTY, "Inappropriate ioctl for device" }, + { BSM_ETXTBSY, ETXTBSY, "Text file busy" }, + { BSM_EFBIG, EFBIG, "File too large" }, + { BSM_ENOSPC, ENOSPC, "No space left on device" }, + { BSM_ESPIPE, ESPIPE, "Illegal seek" }, + { BSM_EROFS, EROFS, "Read-only file system" }, + { BSM_EMLINK, EMLINK, "Too many links" }, + { BSM_EPIPE, EPIPE, "Broken pipe" }, + { BSM_EDOM, EDOM, "Numerical argument out of domain" }, + { BSM_ERANGE, ERANGE, "Result too large" }, + { BSM_ENOMSG, ENOMSG, "No message of desired type" }, + { BSM_EIDRM, EIDRM, "Identifier removed" }, + { BSM_ECHRNG, +#ifdef ECHRNG + ECHRNG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Channel number out of range" }, + { BSM_EL2NSYNC, +#ifdef EL2NSYNC + EL2NSYNC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Level 2 not synchronized" }, + { BSM_EL3HLT, +#ifdef EL3HLT + EL3HLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Level 3 halted" }, + { BSM_EL3RST, +#ifdef EL3RST + EL3RST, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Level 3 reset" }, + { BSM_ELNRNG, +#ifdef ELNRNG + ELNRNG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Link number out of range" }, + { BSM_EUNATCH, +#ifdef EUNATCH + EUNATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Protocol driver not attached" }, + { BSM_ENOCSI, +#ifdef ENOCSI + ENOCSI, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "No CSI structure available" }, + { BSM_EL2HLT, +#ifdef EL2HLT + EL2HLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Level 2 halted" }, + { BSM_EDEADLK, EDEADLK, "Resource deadlock avoided" }, + { BSM_ENOLCK, ENOLCK, "No locks available" }, + { BSM_ECANCELED, ECANCELED, "Operation canceled" }, + { BSM_ENOTSUP, ENOTSUP, "Operation not supported" }, + { BSM_EDQUOT, EDQUOT, "Disc quota exceeded" }, + { BSM_EBADE, +#ifdef EBADE + EBADE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Invalid exchange" }, + { BSM_EBADR, +#ifdef EBADR + EBADR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Invalid request descriptor" }, + { BSM_EXFULL, +#ifdef EXFULL + EXFULL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Exchange full" }, + { BSM_ENOANO, +#ifdef ENOANO + ENOANO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "No anode" }, + { BSM_EBADRQC, +#ifdef EBADRQC + EBADRQC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Invalid request descriptor" }, + { BSM_EBADSLT, +#ifdef EBADSLT + EBADSLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Invalid slot" }, + { BSM_EDEADLOCK, +#ifdef EDEADLOCK + EDEADLOCK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Resource deadlock avoided" }, + { BSM_EBFONT, +#ifdef EBFONT + EBFONT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Bad font file format" }, + { BSM_EOWNERDEAD, +#ifdef EOWNERDEAD + EOWNERDEAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Process died with the lock" }, + { BSM_ENOTRECOVERABLE, +#ifdef ENOTRECOVERABLE + ENOTRECOVERABLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Lock is not recoverable" }, + { BSM_ENOSTR, +#ifdef ENOSTR + ENOSTR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Device not a stream" }, + { BSM_ENONET, +#ifdef ENONET + ENONET, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Machine is not on the network" }, + { BSM_ENOPKG, +#ifdef ENOPKG + ENOPKG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Package not installed" }, + { BSM_EREMOTE, EREMOTE, "Too many levels of remote in path" }, + { BSM_ENOLINK, +#ifdef ENOLINK + ENOLINK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Link has been severed" }, + { BSM_EADV, +#ifdef EADV + EADV, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Advertise error" }, + { BSM_ESRMNT, +#ifdef ESRMNT + ESRMNT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "srmount error" }, + { BSM_ECOMM, +#ifdef ECOMM + ECOMM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Communication error on send" }, + { BSM_EPROTO, +#ifdef EPROTO + EPROTO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Protocol error" }, + { BSM_ELOCKUNMAPPED, +#ifdef ELOCKUNMAPPED + ELOCKUNMAPPED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Locked lock was unmapped" }, + { BSM_ENOTACTIVE, +#ifdef ENOTACTIVE + ENOTACTIVE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Facility is not active" }, + { BSM_EMULTIHOP, +#ifdef EMULTIHOP + EMULTIHOP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Multihop attempted" }, + { BSM_EBADMSG, +#ifdef EBADMSG + EBADMSG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Bad message" }, + { BSM_ENAMETOOLONG, ENAMETOOLONG, "File name too long" }, + { BSM_EOVERFLOW, EOVERFLOW, "Value too large to be stored in data type" }, + { BSM_ENOTUNIQ, +#ifdef ENOTUNIQ + ENOTUNIQ, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Given log name not unique" }, + { BSM_EBADFD, +#ifdef EBADFD + EBADFD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Given f.d. invalid for this operation" }, + { BSM_EREMCHG, +#ifdef EREMCHG + EREMCHG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Remote address changed" }, + { BSM_ELIBACC, +#ifdef ELIBACC + ELIBACC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Can't access a needed shared lib" }, + { BSM_ELIBBAD, +#ifdef ELIBBAD + ELIBBAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Accessing a corrupted shared lib" }, + { BSM_ELIBSCN, +#ifdef ELIBSCN + ELIBSCN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ".lib section in a.out corrupted" }, + { BSM_ELIBMAX, +#ifdef ELIBMAX + ELIBMAX, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Attempting to link in too many libs" }, + { BSM_ELIBEXEC, +#ifdef ELIBEXEC + ELIBEXEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Attempting to exec a shared library" }, + { BSM_EILSEQ, EILSEQ, "Illegal byte sequence" }, + { BSM_ENOSYS, ENOSYS, "Function not implemented" }, + { BSM_ELOOP, ELOOP, "Too many levels of symbolic links" }, + { BSM_ERESTART, +#ifdef ERESTART + ERESTART, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Restart syscall" }, + { BSM_ESTRPIPE, +#ifdef ESTRPIPE + ESTRPIPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "If pipe/FIFO, don't sleep in stream head" }, + { BSM_ENOTEMPTY, ENOTEMPTY, "Directory not empty" }, + { BSM_EUSERS, EUSERS, "Too many users" }, + { BSM_ENOTSOCK, ENOTSOCK, "Socket operation on non-socket" }, + { BSM_EDESTADDRREQ, EDESTADDRREQ, "Destination address required" }, + { BSM_EMSGSIZE, EMSGSIZE, "Message too long" }, + { BSM_EPROTOTYPE, EPROTOTYPE, "Protocol wrong type for socket" }, + { BSM_ENOPROTOOPT, ENOPROTOOPT, "Protocol not available" }, + { BSM_EPROTONOSUPPORT, EPROTONOSUPPORT, "Protocol not supported" }, + { BSM_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT, "Socket type not supported" }, + { BSM_EOPNOTSUPP, EOPNOTSUPP, "Operation not supported" }, + { BSM_EPFNOSUPPORT, EPFNOSUPPORT, "Protocol family not supported" }, + { BSM_EAFNOSUPPORT, EAFNOSUPPORT, "Address family not supported by protocol family" }, + { BSM_EADDRINUSE, EADDRINUSE, "Address already in use" }, + { BSM_EADDRNOTAVAIL, EADDRNOTAVAIL, "Can't assign requested address" }, + { BSM_ENETDOWN, ENETDOWN, "Network is down" }, + { BSM_ENETRESET, ENETRESET, "Network dropped connection on reset" }, + { BSM_ECONNABORTED, ECONNABORTED, "Software caused connection abort" }, + { BSM_ECONNRESET, ECONNRESET, "Connection reset by peer" }, + { BSM_ENOBUFS, ENOBUFS, "No buffer space available" }, + { BSM_EISCONN, EISCONN, "Socket is already connected" }, + { BSM_ENOTCONN, ENOTCONN, "Socket is not connected" }, + { BSM_ESHUTDOWN, ESHUTDOWN, "Can't send after socket shutdown" }, + { BSM_ETOOMANYREFS, ETOOMANYREFS, "Too many references: can't splice" }, + { BSM_ETIMEDOUT, ETIMEDOUT, "Operation timed out" }, + { BSM_ECONNREFUSED, ECONNREFUSED, "Connection refused" }, + { BSM_EHOSTDOWN, EHOSTDOWN, "Host is down" }, + { BSM_EHOSTUNREACH, EHOSTUNREACH, "No route to host" }, + { BSM_EALREADY, EALREADY, "Operation already in progress" }, + { BSM_EINPROGRESS, EINPROGRESS, "Operation now in progress" }, + { BSM_ESTALE, ESTALE, "Stale NFS file handle" }, + { BSM_EPWROFF, +#ifdef EPWROFF + EPWROFF, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Device power is off" }, + { BSM_EDEVERR, +#ifdef EDEVERR + EDEVERR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Device error" }, + { BSM_EBADEXEC, +#ifdef EBADEXEC + EBADEXEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Bad executable" }, + { BSM_EBADARCH, +#ifdef EBADARCH + EBADARCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Bad CPU type in executable" }, + { BSM_ESHLIBVERS, +#ifdef ESHLIBVERS + ESHLIBVERS, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Shared library version mismatch" }, + { BSM_EBADMACHO, +#ifdef EBADMACHO + EBADMACHO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Malfored Macho file" }, + { BSM_EPOLICY, +#ifdef EPOLICY + EPOLICY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Operation failed by policy" }, + { BSM_EDOTDOT, +#ifdef EDOTDOT + EDOTDOT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "RFS specific error" }, + { BSM_EUCLEAN, +#ifdef EUCLEAN + EUCLEAN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Structure needs cleaning" }, + { BSM_ENOTNAM, +#ifdef ENOTNAM + ENOTNAM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Not a XENIX named type file" }, + { BSM_ENAVAIL, +#ifdef ENAVAIL + ENAVAIL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "No XENIX semaphores available" }, + { BSM_EISNAM, +#ifdef EISNAM + EISNAM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Is a named type file" }, + { BSM_EREMOTEIO, +#ifdef EREMOTEIO + EREMOTEIO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Remote I/O error" }, + { BSM_ENOMEDIUM, +#ifdef ENOMEDIUM + ENOMEDIUM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "No medium found" }, + { BSM_EMEDIUMTYPE, +#ifdef EMEDIUMTYPE + EMEDIUMTYPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Wrong medium type" }, + { BSM_ENOKEY, +#ifdef ENOKEY + ENOKEY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Required key not available" }, + { BSM_EKEYEXPIRED, +#ifdef EKEEXPIRED + EKEYEXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Key has expired" }, + { BSM_EKEYREVOKED, +#ifdef EKEYREVOKED + EKEYREVOKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Key has been revoked" }, + { BSM_EKEYREJECTED, +#ifdef EKEREJECTED + EKEYREJECTED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + "Key was rejected by service" }, +}; +static const int bsm_errors_count = sizeof(bsm_errors) / sizeof(bsm_errors[0]); + +static const struct bsm_errors * +au_bsm_error_lookup_errno(int error) +{ + int i; + + if (error == ERRNO_NO_LOCAL_MAPPING) + return (NULL); + for (i = 0; i < bsm_errors_count; i++) { + if (bsm_errors[i].be_os_error == error) + return (&bsm_errors[i]); + } + return (NULL); +} + +static const struct bsm_errors * +au_bsm_error_lookup_bsm(u_char bsm_error) +{ + int i; + + for (i = 0; i < bsm_errors_count; i++) { + if (bsm_errors[i].be_bsm_error == bsm_error) + return (&bsm_errors[i]); + } + return (NULL); +} + +/* + * Converstion from a BSM error to a local error number may fail if either + * OpenBSM doesn't recognize the error on the wire, or because there is no + * appropriate local mapping. However, we don't allow conversion to BSM to + * fail, we just convert to BSM_UKNOWNERR. + */ +int +au_bsm_to_errno(u_char bsm_error, int *errorp) +{ + const struct bsm_errors *bsme; + + bsme = au_bsm_error_lookup_bsm(bsm_error); + if (bsme == NULL || bsme->be_os_error == ERRNO_NO_LOCAL_MAPPING) + return (-1); + *errorp = bsme->be_os_error; + return (0); +} + +u_char +au_errno_to_bsm(int error) +{ + const struct bsm_errors *bsme; + + /* + * We should never be passed this libbsm-internal constant, and + * because it is ambiguous we just return an error. + */ + if (error == ERRNO_NO_LOCAL_MAPPING) + return (BSM_UNKNOWNERR); + bsme = au_bsm_error_lookup_errno(error); + if (bsme == NULL) + return (BSM_UNKNOWNERR); + return (bsme->be_bsm_error); +} + +#if !defined(KERNEL) && !defined(_KERNEL) +const char * +au_strerror(u_char bsm_error) +{ + const struct bsm_errors *bsme; + + bsme = au_bsm_error_lookup_bsm(bsm_error); + if (bsme == NULL) + return ("Unrecognized BSM error"); + if (bsme->be_os_error != ERRNO_NO_LOCAL_MAPPING) + return (strerror(bsme->be_os_error)); + return (bsme->be_strerror); +} +#endif diff --git a/libbsm/bsm_event.c b/libbsm/bsm_event.c index 695e617c570b..f3c660168bf7 100644 --- a/libbsm/bsm_event.c +++ b/libbsm/bsm_event.c @@ -27,7 +27,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/libbsm/bsm_event.c#16 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#17 $ */ #include <config/config.h> @@ -35,7 +35,9 @@ #include <bsm/libbsm.h> #include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdio.h> #include <stdlib.h> @@ -52,7 +54,9 @@ static FILE *fp = NULL; static char linestr[AU_LINE_MAX]; static const char *eventdelim = ":"; +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* * Parse one line from the audit_event file into the au_event_ent structure. @@ -114,9 +118,13 @@ void setauevent(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauevent_locked(); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -126,12 +134,16 @@ void endauevent(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (fp != NULL) { fclose(fp); fp = NULL; } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -171,9 +183,13 @@ getauevent_r(struct au_event_ent *e) { struct au_event_ent *ep; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif ep = getauevent_r_locked(e); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (ep); } @@ -230,9 +246,13 @@ getauevnam_r(struct au_event_ent *e, const char *name) { struct au_event_ent *ep; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif ep = getauevnam_r_locked(e, name); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (ep); } @@ -284,9 +304,13 @@ getauevnum_r(struct au_event_ent *e, au_event_t event_number) { struct au_event_ent *ep; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif ep = getauevnum_r_locked(e, event_number); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (ep); } diff --git a/libbsm/bsm_io.c b/libbsm/bsm_io.c index 989fd8b82950..e593745bc84a 100644 --- a/libbsm/bsm_io.c +++ b/libbsm/bsm_io.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2004-2008 Apple Inc. * Copyright (c) 2005 SPARTA, Inc. * Copyright (c) 2006 Robert N. M. Watson * Copyright (c) 2006 Martin Voros @@ -32,15 +32,15 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#55 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#59 $ */ #include <sys/types.h> #include <config/config.h> -#ifdef HAVE_SYS_ENDIAN_H +#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC) #include <sys/endian.h> -#else /* !HAVE_SYS_ENDIAN_H */ +#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */ #ifdef HAVE_MACHINE_ENDIAN_H #include <machine/endian.h> #else /* !HAVE_MACHINE_ENDIAN_H */ @@ -51,7 +51,7 @@ #endif /* !HAVE_ENDIAN_H */ #endif /* !HAVE_MACHINE_ENDIAN_H */ #include <compat/endian.h> -#endif /* !HAVE_SYS_ENDIAN_H */ +#endif /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */ #ifdef HAVE_FULL_QUEUE_H #include <sys/queue.h> #else /* !HAVE_FULL_QUEUE_H */ @@ -771,13 +771,24 @@ print_ip_ex_address(FILE *fp, u_int32_t type, u_int32_t *ipaddr) static void print_retval(FILE *fp, u_char status, char raw) { + int error; + if (raw) fprintf(fp, "%u", status); else { - if (status == 0) - fprintf(fp, "success"); - else - fprintf(fp, "failure : %s", strerror(status)); + /* + * Convert to a local error number and print the OS's version + * of the error string if possible. We may want to provide + * an au_strerror(3) in the future so that we can print + * strings for non-local errors. + */ + if (au_bsm_to_errno(status, &error) == 0) { + if (error == 0) + fprintf(fp, "success"); + else + fprintf(fp, "failure : %s", strerror(error)); + } else + fprintf(fp, "failure: Unknown error: %d", status); } } @@ -3742,54 +3753,72 @@ print_text_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, } /* + * socket domain 2 bytes * socket type 2 bytes + * address type 2 bytes * local port 2 bytes - * address type/length 4 bytes - * local Internet address 4 bytes - * remote port 4 bytes - * address type/length 4 bytes - * remote Internet address 4 bytes + * local Internet address 4/16 bytes + * remote port 2 bytes + * remote Internet address 4/16 bytes */ static int fetch_socketex32_tok(tokenstr_t *tok, u_char *buf, int len) { int err = 0; - READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len, + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.domain, tok->len, err); if (err) return (-1); - READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port, - sizeof(uint16_t), tok->len, err); + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len, + err); if (err) return (-1); - READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.l_ad_type, tok->len, + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.atype, tok->len, err); if (err) return (-1); - READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr, - sizeof(tok->tt.socket_ex32.l_addr), tok->len, err); - if (err) + if (tok->tt.socket_ex32.atype != AU_IPv4 && + tok->tt.socket_ex32.atype != AU_IPv6) return (-1); - READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port, + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port, sizeof(uint16_t), tok->len, err); if (err) return (-1); - READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.r_ad_type, tok->len, - err); - if (err) - return (-1); + if (tok->tt.socket_ex32.atype == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr, + sizeof(tok->tt.socket_ex32.l_addr[0]), tok->len, err); + if (err) + return (-1); + } else { + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr, + sizeof(tok->tt.socket_ex32.l_addr), tok->len, err); + if (err) + return (-1); + } - READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr, - sizeof(tok->tt.socket_ex32.r_addr), tok->len, err); + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port, + sizeof(uint16_t), tok->len, err); if (err) return (-1); + if (tok->tt.socket_ex32.atype == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr, + sizeof(tok->tt.socket_ex32.r_addr[0]), tok->len, err); + if (err) + return (-1); + } else { + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr, + sizeof(tok->tt.socket_ex32.r_addr), tok->len, err); + if (err) + return (-1); + } + return (0); } @@ -3800,6 +3829,9 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, print_tok_type(fp, tok->id, "socket", raw, xml); if (xml) { + open_attr(fp, "sock_dom"); + print_2_bytes(fp, tok->tt.socket_ex32.domain, "%#x"); + close_attr(fp); open_attr(fp, "sock_type"); print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x"); close_attr(fp); @@ -3807,10 +3839,12 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x"); close_attr(fp); open_attr(fp, "laddr"); - print_ip_address(fp, tok->tt.socket_ex32.l_addr); + print_ip_ex_address(fp, tok->tt.socket_ex32.atype, + tok->tt.socket_ex32.l_addr); close_attr(fp); open_attr(fp, "faddr"); - print_ip_address(fp, tok->tt.socket_ex32.r_addr); + print_ip_ex_address(fp, tok->tt.socket_ex32.atype, + tok->tt.socket_ex32.r_addr); close_attr(fp); open_attr(fp, "fport"); print_2_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x"); @@ -3818,15 +3852,19 @@ print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, close_tag(fp, tok->id); } else { print_delim(fp, del); + print_2_bytes(fp, tok->tt.socket_ex32.domain, "%#x"); + print_delim(fp, del); print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x"); print_delim(fp, del); print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x"); print_delim(fp, del); - print_ip_address(fp, tok->tt.socket_ex32.l_addr); + print_ip_ex_address(fp, tok->tt.socket_ex32.atype, + tok->tt.socket_ex32.l_addr); print_delim(fp, del); print_4_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x"); print_delim(fp, del); - print_ip_address(fp, tok->tt.socket_ex32.r_addr); + print_ip_ex_address(fp, tok->tt.socket_ex32.atype, + tok->tt.socket_ex32.r_addr); } } diff --git a/libbsm/bsm_mask.c b/libbsm/bsm_mask.c index 07d3da3f83a5..afbed5e3f7b2 100644 --- a/libbsm/bsm_mask.c +++ b/libbsm/bsm_mask.c @@ -27,7 +27,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/libbsm/bsm_mask.c#14 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_mask.c#15 $ */ #include <sys/types.h> @@ -41,12 +41,16 @@ #include <bsm/libbsm.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdlib.h> #include <string.h> /* MT-Safe */ +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif static int firsttime = 1; /* @@ -162,11 +166,15 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag) return (-1); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (firsttime) { firsttime = 0; if ( -1 == load_event_table()) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-1); } } @@ -174,7 +182,9 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag) case AU_PRS_REREAD: flush_cache(); if (load_event_table() == -1) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-1); } ev = read_from_cache(event); @@ -186,14 +196,18 @@ au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag) ev = NULL; } if (ev == NULL) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (-1); } if (sorf & AU_PRS_SUCCESS) effmask |= (mask_p->am_success & ev->ae_class); if (sorf & AU_PRS_FAILURE) effmask |= (mask_p->am_failure & ev->ae_class); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif if (effmask != 0) return (1); return (0); diff --git a/libbsm/bsm_token.c b/libbsm/bsm_token.c index f9692d1d0101..c9aa1a92fce7 100644 --- a/libbsm/bsm_token.c +++ b/libbsm/bsm_token.c @@ -30,15 +30,15 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#72 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#85 $ */ #include <sys/types.h> #include <config/config.h> -#ifdef HAVE_SYS_ENDIAN_H +#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC) #include <sys/endian.h> -#else /* !HAVE_SYS_ENDIAN_H */ +#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */ #ifdef HAVE_MACHINE_ENDIAN_H #include <machine/endian.h> #else /* !HAVE_MACHINE_ENDIAN_H */ @@ -49,7 +49,7 @@ #endif /* !HAVE_ENDIAN_H */ #endif /* !HAVE_MACHINE_ENDIAN_H */ #include <compat/endian.h> -#endif /* !HAVE_SYS_ENDIAN_H */ +#endif /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */ #ifdef HAVE_FULL_QUEUE_H #include <sys/queue.h> #else /* !HAVE_FULL_QUEUE_H */ @@ -178,8 +178,12 @@ au_to_attr32(struct vnode_au_info *vni) ADD_U_CHAR(dptr, AUT_ATTR32); /* - * Darwin defines the size for the file mode as 2 bytes; BSM defines - * 4 so pad with 0. + * BSD defines the size for the file mode as 2 bytes; BSM defines 4 + * so pad with 0. + * + * XXXRW: Possibly should be conditionally compiled. + * + * XXXRW: Should any conversions take place on the mode? */ ADD_U_INT16(dptr, pad0_16); ADD_U_INT16(dptr, vni->vn_mode); @@ -223,8 +227,12 @@ au_to_attr64(struct vnode_au_info *vni) ADD_U_CHAR(dptr, AUT_ATTR64); /* - * Darwin defines the size for the file mode as 2 bytes; BSM defines - * 4 so pad with 0. + * BSD defines the size for the file mode as 2 bytes; BSM defines 4 + * so pad with 0. + * + * XXXRW: Possibly should be conditionally compiled. + * + * XXXRW: Should any conversions take place on the mode? */ ADD_U_INT16(dptr, pad0_16); ADD_U_INT16(dptr, vni->vn_mode); @@ -305,6 +313,10 @@ au_to_data(char unit_print, char unit_type, char unit_count, const char *p) if (t == NULL) return (NULL); + /* + * XXXRW: We should be byte-swapping each data item for multi-byte + * types. + */ ADD_U_CHAR(dptr, AUT_DATA); ADD_U_CHAR(dptr, unit_print); ADD_U_CHAR(dptr, unit_type); @@ -401,7 +413,7 @@ au_to_in_addr_ex(struct in6_addr *internet_addr) { token_t *t; u_char *dptr = NULL; - u_int32_t type = AF_INET6; + u_int32_t type = AU_IPv6; GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); if (t == NULL) @@ -482,20 +494,30 @@ au_to_ipc_perm(struct ipc_perm *perm) ADD_U_CHAR(dptr, AUT_IPC_PERM); /* - * Darwin defines the sizes for ipc_perm members as 2 bytes; BSM - * defines 4 so pad with 0. + * Systems vary significantly in what types they use in struct + * ipc_perm; at least a few still use 16-bit uid's and gid's, so + * allow for that, as BSM define 32-bit values here. + * Some systems define the sizes for ipc_perm members as 2 bytes; + * BSM defines 4 so pad with 0. + * + * XXXRW: Possibly shoulid be conditionally compiled, and more cases + * need to be handled. */ - ADD_U_INT16(dptr, pad0); - ADD_U_INT16(dptr, perm->uid); - - ADD_U_INT16(dptr, pad0); - ADD_U_INT16(dptr, perm->gid); - - ADD_U_INT16(dptr, pad0); - ADD_U_INT16(dptr, perm->cuid); - - ADD_U_INT16(dptr, pad0); - ADD_U_INT16(dptr, perm->cgid); + if (sizeof(perm->uid) != sizeof(u_int32_t)) { + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->uid); + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->gid); + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->cuid); + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->cgid); + } else { + ADD_U_INT32(dptr, perm->uid); + ADD_U_INT32(dptr, perm->gid); + ADD_U_INT32(dptr, perm->cuid); + ADD_U_INT32(dptr, perm->cgid); + } ADD_U_INT16(dptr, pad0); ADD_U_INT16(dptr, perm->mode); @@ -616,6 +638,8 @@ au_to_text(const char *text) textlen = strlen(text); textlen += 1; + /* XXXRW: Should validate length against token size limit. */ + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); if (t == NULL) return (NULL); @@ -686,6 +710,13 @@ au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, ADD_U_INT32(dptr, pid); ADD_U_INT32(dptr, sid); ADD_U_INT32(dptr, tid->port); + + /* + * Note: Solaris will write out IPv6 addresses here as a 32-bit + * address type and 16 bytes of address, but for IPv4 addresses it + * simply writes the 4-byte address directly. We support only IPv4 + * addresses for process32 tokens. + */ ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); return (t); @@ -712,6 +743,13 @@ au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, ADD_U_INT32(dptr, pid); ADD_U_INT32(dptr, sid); ADD_U_INT64(dptr, tid->port); + + /* + * Note: Solaris will write out IPv6 addresses here as a 32-bit + * address type and 16 bytes of address, but for IPv4 addresses it + * simply writes the 4-byte address directly. We support only IPv4 + * addresses for process64 tokens. + */ ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); return (t); @@ -899,6 +937,60 @@ au_to_seq(long audit_count) /* * token ID 1 byte + * socket domain 2 bytes + * socket type 2 bytes + * address type 2 byte + * local port 2 bytes + * local address 4 bytes/16 bytes (IPv4/IPv6 address) + * remote port 2 bytes + * remote address 4 bytes/16 bytes (IPv4/IPv6 address) + */ +token_t * +au_to_socket_ex(u_short so_domain, u_short so_type, + struct sockaddr *sa_local, struct sockaddr *sa_remote) +{ + token_t *t; + u_char *dptr = NULL; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + if (so_domain == AF_INET) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); + else if (so_domain == AF_INET6) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 5 * sizeof(u_int16_t) + 16 * sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + + ADD_U_CHAR(dptr, AUT_SOCKET_EX); + ADD_U_INT16(dptr, so_domain); /* XXXRW: explicitly convert? */ + ADD_U_INT16(dptr, so_type); /* XXXRW: explicitly convert? */ + if (so_domain == AF_INET) { + ADD_U_INT16(dptr, AU_IPv4); + sin = (struct sockaddr_in *)sa_local; + ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t)); + ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t)); + sin = (struct sockaddr_in *)sa_remote; + ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t)); + ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t)); + } else { + ADD_U_INT16(dptr, AU_IPv6); + sin6 = (struct sockaddr_in6 *)sa_local; + ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t)); + ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t)); + sin6 = (struct sockaddr_in6 *)sa_remote; + ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t)); + ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t)); + } + + return (t); +} + +/* + * token ID 1 byte * socket family 2 bytes * path 104 bytes */ @@ -971,8 +1063,9 @@ au_to_sock_inet128(struct sockaddr_in6 *so) ADD_U_CHAR(dptr, AUT_SOCKINET128); /* - * In Darwin, sin6_family is one octet, but BSM defines the token - * to store two. So we copy in a 0 first. + * In BSD, sin6_family is one octet, but BSM defines the token to + * store two. So we copy in a 0 first. XXXRW: Possibly should be + * conditionally compiled. */ ADD_U_CHAR(dptr, 0); ADD_U_CHAR(dptr, so->sin6_family); @@ -1207,7 +1300,6 @@ au_to_exec_args(char **argv) nextarg = *(argv + count); } - totlen += count * sizeof(char); /* nul terminations. */ GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); if (t == NULL) return (NULL); @@ -1224,27 +1316,6 @@ au_to_exec_args(char **argv) } /* - * token ID 1 byte - * zonename length 2 bytes - * zonename N bytes + 1 terminating NULL byte - */ -token_t * -au_to_zonename(const char *zonename) -{ - u_char *dptr = NULL; - u_int16_t textlen; - token_t *t; - - textlen = strlen(zonename); - textlen += 1; - GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); - ADD_U_CHAR(dptr, AUT_ZONENAME); - ADD_U_INT16(dptr, textlen); - ADD_STRING(dptr, zonename, textlen); - return (t); -} - -/* * token ID 1 byte * count 4 bytes * text count null-terminated strings @@ -1269,7 +1340,6 @@ au_to_exec_env(char **envp) nextenv = *(envp + count); } - totlen += sizeof(char) * count; GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); if (t == NULL) return (NULL); @@ -1287,6 +1357,29 @@ au_to_exec_env(char **envp) /* * token ID 1 byte + * zonename length 2 bytes + * zonename N bytes + 1 terminating NULL byte + */ +token_t * +au_to_zonename(const char *zonename) +{ + u_char *dptr = NULL; + u_int16_t textlen; + token_t *t; + + textlen = strlen(zonename) + 1; + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ZONENAME); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, zonename, textlen); + return (t); +} + +/* + * token ID 1 byte * record byte count 4 bytes * version # 1 byte [2] * event type 2 bytes @@ -1338,9 +1431,10 @@ au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, { token_t *t; u_char *dptr = NULL; - u_int32_t timems, hostid; - au_tid_addr_t *tid = &aia->ai_termid; + u_int32_t timems; + au_tid_addr_t *tid; + tid = &aia->ai_termid; if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6) return (NULL); GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + @@ -1462,7 +1556,7 @@ au_to_trailer(int rec_size) { token_t *t; u_char *dptr = NULL; - u_int16_t magic = TRAILER_PAD_MAGIC; + u_int16_t magic = AUT_TRAILER_MAGIC; GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + sizeof(u_int32_t)); diff --git a/libbsm/bsm_user.c b/libbsm/bsm_user.c index 5266fdf2eebc..005698be9a98 100644 --- a/libbsm/bsm_user.c +++ b/libbsm/bsm_user.c @@ -27,7 +27,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/libbsm/bsm_user.c#18 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_user.c#19 $ */ #include <config/config.h> @@ -35,7 +35,9 @@ #include <bsm/libbsm.h> #include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK #include <pthread.h> +#endif #include <stdio.h> #include <stdlib.h> @@ -51,7 +53,9 @@ static FILE *fp = NULL; static char linestr[AU_LINE_MAX]; static const char *user_delim = ":"; +#ifdef HAVE_PTHREAD_MUTEX_LOCK static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif /* * Parse one line from the audit_user file into the au_user_ent structure. @@ -97,9 +101,13 @@ void setauuser(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauuser_locked(); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -109,12 +117,16 @@ void endauuser(void) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif if (fp != NULL) { fclose(fp); fp = NULL; } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif } /* @@ -154,9 +166,13 @@ getauuserent_r(struct au_user_ent *u) { struct au_user_ent *up; +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif up = getauuserent_r_locked(u); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (up); } @@ -184,17 +200,23 @@ getauusernam_r(struct au_user_ent *u, const char *name) if (name == NULL) return (NULL); +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_lock(&mutex); +#endif setauuser_locked(); while ((up = getauuserent_r_locked(u)) != NULL) { if (strcmp(name, u->au_name) == 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (u); } } +#ifdef HAVE_PTHREAD_MUTEX_LOCK pthread_mutex_unlock(&mutex); +#endif return (NULL); } diff --git a/libbsm/bsm_wrappers.c b/libbsm/bsm_wrappers.c index f818f1de2e91..5bcf57c847cd 100644 --- a/libbsm/bsm_wrappers.c +++ b/libbsm/bsm_wrappers.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/libbsm/bsm_wrappers.c#26 $ + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_wrappers.c#28 $ */ #ifdef __APPLE__ @@ -69,6 +69,7 @@ audit_submit(short au_event, au_id_t auid, char status, int error, afd, subj_ex; struct auditinfo ai; struct auditinfo_addr aia; + au_tid_t atid; if (auditon(A_GETCOND, &acond, sizeof(acond)) < 0) { /* @@ -85,7 +86,6 @@ audit_submit(short au_event, au_id_t auid, char status, } if (acond == AUC_NOAUDIT) return (0); - /* XXXCSJP we should be doing a pre-select here */ afd = au_open(); if (afd < 0) { error = errno; @@ -95,30 +95,51 @@ audit_submit(short au_event, au_id_t auid, char status, return (-1); } /* - * Some operating systems do not have getaudit_addr(2) implemented - * yet. So we try to use getaudit(2) first, if the subject is - * using IPv6, then we will have to try getaudit_addr(2). Failing - * this, we return error. + * Try to use getaudit_addr(2) first. If this kernel does not support + * it, then fall back on to getaudit(2). */ subj_ex = 0; - error = getaudit(&ai); - if (error < 0 && errno == E2BIG) { - error = getaudit_addr(&aia, sizeof(aia)); - if (error == 0) - subj_ex = 1; - } - if (error < 0) { + error = getaudit_addr(&aia, sizeof(aia)); + if (error < 0 && errno == ENOSYS) { + error = getaudit(&ai); + if (error < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s", + strerror(errno)); + errno = error; + return (-1); + } + /* + * Convert this auditinfo_t to an auditinfo_addr_t to make the + * following code less complicated wrt to preselection and + * subject token generation. + */ + aia.ai_auid = ai.ai_auid; + aia.ai_mask = ai.ai_mask; + aia.ai_asid = ai.ai_asid; + aia.ai_termid.at_type = AU_IPv4; + aia.ai_termid.at_addr[0] = ai.ai_termid.machine; + aia.ai_termid.at_port = ai.ai_termid.port; + } else if (error < 0) { error = errno; - syslog(LOG_AUTH | LOG_ERR, "audit: getaudit failed: %s", + syslog(LOG_AUTH | LOG_ERR, "audit: getaudit_addr failed: %s", strerror(errno)); errno = error; return (-1); } + /* + * NB: We should be performing pre-selection here now that we have the + * masks for this process. + */ + if (aia.ai_termid.at_type == AU_IPv6) + subj_ex = 1; pid = getpid(); - if (subj_ex == 0) + if (subj_ex == 0) { + atid.port = aia.ai_termid.at_port; + atid.machine = aia.ai_termid.at_addr[0]; token = au_to_subject32(auid, geteuid(), getegid(), - getuid(), getgid(), pid, pid, &ai.ai_termid); - else + getuid(), getgid(), pid, pid, &atid); + } else token = au_to_subject_ex(auid, geteuid(), getegid(), getuid(), getgid(), pid, pid, &aia.ai_termid); if (token == NULL) { @@ -157,7 +178,7 @@ audit_submit(short au_event, au_id_t auid, char status, return (-1); } } - token = au_to_return32(status, reterr); + token = au_to_return32(status, au_errno_to_bsm(reterr)); if (token == NULL) { syslog(LOG_AUTH | LOG_ERR, "audit: enable to build return token"); diff --git a/libbsm/libbsm.3 b/libbsm/libbsm.3 index e84ea943d684..9a8ebda1dbe0 100644 --- a/libbsm/libbsm.3 +++ b/libbsm/libbsm.3 @@ -23,9 +23,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/libbsm.3#13 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/libbsm/libbsm.3#14 $ .\" -.Dd April 19, 2005 +.Dd November 12, 2008 .Dt LIBBSM 3 .Os .Sh NAME @@ -201,6 +201,12 @@ database: .Xr au_user 3 , .Xr audit_class 5 , .Xr audit_control 5 +.Ss Audit Error Interfaces +These functions convert between BSM and local +.Xr errno 2 +error numbers, and must be used to interpret and generate BSM return tokens: +.Xr au_bsm_to_errno 3 , +.Xr au_errno_to_bsm 3 . .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/man/Makefile.in b/man/Makefile.in index a24804a5d040..2f229f5bb4c4 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/man/Makefile.in#7 $ +# $P4: //depot/projects/trustedbsd/openbsm/man/Makefile.in#8 $ # VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/man/audit.log.5 b/man/audit.log.5 index dac0067cfef8..143936c389eb 100644 --- a/man/audit.log.5 +++ b/man/audit.log.5 @@ -1,5 +1,6 @@ .\"- .\" Copyright (c) 2005-2006 Robert N. M. Watson +.\" Copyright (c) 2008 Apple Inc. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -23,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit.log.5#19 $ +.\" $P4: //depot/projects/trustedbsd/openbsm/man/audit.log.5#23 $ .\" .Dd November 5, 2006 .Dt AUDIT.LOG 5 @@ -139,7 +140,7 @@ token can be created using The .Dq trailer terminates a BSM audit record, and contains a magic number, -.Dv TRAILER_PAD_MAGIC +.Dv AUT_TRAILER_MAGIC and length that can be used to validate that the record was read properly. A .Dq trailer @@ -515,7 +516,7 @@ An exec_args token may be created using .It Sy "Field Bytes Description" .It "Token ID 1 byte Token ID" .It Li "Count" Ta "4 bytes" Ta "Number of arguments" -.It Li "Text" Ta "* bytes" Ta "Count null-terminated strings" +.It Li "Text" Ta "* bytes" Ta "Count nul-terminated strings" .El .Ss exec_env Token The @@ -560,25 +561,24 @@ or .It Li "Local port" Ta "2 bytes" Ta "Local port" .It Li "Socket address" Ta "4 bytes" Ta "Socket address" .El -.Bl -column -offset 3n ".No Terminal Address Type/Length" ".No N bytes + 1 NUL" -.It Sy "Field Bytes Description" -.It "Token ID 1 byte Token ID" -.It Li "Socket domain" Ta "4 bytes" Ta "Socket domain" -.It Li "Socket family" Ta "2 bytes" Ta "Socket family" -.It Li "Address type" Ta "1 byte" Ta "Address type (IPv4/IPv6)" -.It Li "Local port" Ta "2 bytes" Ta "Local port" -.It Li "Local IP address" Ta "4/16 bytes" Ta "Local IP address" -.It Li "Remote port" Ta "2 bytes" Ta "Remote port" -.It Li "Remote IP address" Ta "4/16 bytes" Ta "Remote IP address" -.El .Ss Expanded Socket Token The .Dq expanded socket token contains information about IPv4 and IPv6 sockets. +A +.Dq expanded socket +token can be created using +.Xr au_to_socket_ex 3 . .Bl -column -offset 3n ".No Terminal Address Type/Length" ".No N bytes + 1 NUL" .It Sy "Field Bytes Description" -.It "Token ID 1 byte Token ID" -.It XXXXX +.It Li "Token ID" Ta "1 byte" Ta "Token ID" +.It Li "Socket domain" Ta "2 bytes" Ta "Socket domain" +.It Li "Socket type" Ta "2 bytes" Ta "Socket type" +.It Li "Address type" Ta "2 byte" Ta "Address type (IPv4/IPv6)" +.It Li "Local port" Ta "2 bytes" Ta "Local port" +.It Li "Local IP address" Ta "4/16 bytes" Ta "Local IP address" +.It Li "Remote port" Ta "2 bytes" Ta "Remote port" +.It Li "Remote IP address" Ta "4/16 bytes" Ta "Remote IP address" .El .Ss Seq Token The diff --git a/modules/Makefile.in b/modules/Makefile.in index 39b942af6621..135dcae0468d 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/modules/Makefile.in#5 $ +# $P4: //depot/projects/trustedbsd/openbsm/modules/Makefile.in#6 $ # VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/modules/auditfilter_noop/Makefile.in b/modules/auditfilter_noop/Makefile.in index 6d39c48eff41..8c764e416a05 100644 --- a/modules/auditfilter_noop/Makefile.in +++ b/modules/auditfilter_noop/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/modules/auditfilter_noop/Makefile.in#6 $ +# $P4: //depot/projects/trustedbsd/openbsm/modules/auditfilter_noop/Makefile.in#7 $ # VPATH = @srcdir@ diff --git a/sys/Makefile.in b/sys/Makefile.in index 7c090bdf04d6..b61e9fc3674f 100644 --- a/sys/Makefile.in +++ b/sys/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/sys/Makefile.in#2 $ +# $P4: //depot/projects/trustedbsd/openbsm/sys/Makefile.in#3 $ # VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/sys/bsm/Makefile.am b/sys/bsm/Makefile.am index b3c7805bca8e..2fd60bc9a889 100644 --- a/sys/bsm/Makefile.am +++ b/sys/bsm/Makefile.am @@ -1,5 +1,5 @@ # -# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.am#1 $ +# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.am#2 $ # @@ -8,6 +8,7 @@ openbsmdir = $(includedir)/bsm openbsm_HEADERS = \ audit.h \ + audit_errno.h \ audit_internal.h \ audit_kevents.h \ audit_record.h diff --git a/sys/bsm/Makefile.in b/sys/bsm/Makefile.in index 34cb9e6a0790..d0e57935b850 100644 --- a/sys/bsm/Makefile.in +++ b/sys/bsm/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.in#2 $ +# $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/Makefile.in#4 $ # VPATH = @srcdir@ @@ -48,8 +48,8 @@ CONFIG_HEADER = $(top_builddir)/config/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = -am__openbsm_HEADERS_DIST = audit.h audit_internal.h audit_kevents.h \ - audit_record.h +am__openbsm_HEADERS_DIST = audit.h audit_errno.h audit_internal.h \ + audit_kevents.h audit_record.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -173,6 +173,7 @@ top_srcdir = @top_srcdir@ @USE_NATIVE_INCLUDES_FALSE@openbsmdir = $(includedir)/bsm @USE_NATIVE_INCLUDES_FALSE@openbsm_HEADERS = \ @USE_NATIVE_INCLUDES_FALSE@ audit.h \ +@USE_NATIVE_INCLUDES_FALSE@ audit_errno.h \ @USE_NATIVE_INCLUDES_FALSE@ audit_internal.h \ @USE_NATIVE_INCLUDES_FALSE@ audit_kevents.h \ @USE_NATIVE_INCLUDES_FALSE@ audit_record.h diff --git a/sys/bsm/audit.h b/sys/bsm/audit.h index ebb84da19861..c730caccd8d4 100644 --- a/sys/bsm/audit.h +++ b/sys/bsm/audit.h @@ -26,12 +26,21 @@ * (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/sys/bsm/audit.h#1 $ + * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit.h#2 $ */ #ifndef _BSM_AUDIT_H #define _BSM_AUDIT_H +#ifdef __APPLE__ +/* Temporary until rdar://problem/6133383 is resolved. */ +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/cdefs.h> +#include <sys/queue.h> +#endif /* __APPLE__ */ + #define AUDIT_RECORD_MAGIC 0x828a0f1b #define MAX_AUDIT_RECORDS 20 #define MAXAUDITDATA (0x8000 - 1) @@ -39,6 +48,14 @@ #define MIN_AUDIT_FILE_SIZE (512 * 1024) /* + * Minimum noumber of free blocks on the filesystem containing the audit + * log necessary to avoid a hard log rotation. DO NOT SET THIS VALUE TO 0 + * as the kernel does an unsigned compare, plus we want to leave a few blocks + * free so userspace can terminate the log, etc. + */ +#define AUDIT_HARD_LIMIT_FREE_BLOCKS 4 + +/* * Triggers for the audit daemon. */ #define AUDIT_TRIGGER_MIN 1 @@ -47,8 +64,9 @@ #define AUDIT_TRIGGER_READ_FILE 3 /* Re-read config file. */ #define AUDIT_TRIGGER_CLOSE_AND_DIE 4 /* Terminate audit. */ #define AUDIT_TRIGGER_NO_SPACE 5 /* Below min free space. */ -#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests roate. */ -#define AUDIT_TRIGGER_MAX 6 +#define AUDIT_TRIGGER_ROTATE_USER 6 /* User requests rotate. */ +#define AUDIT_TRIGGER_INITIALIZE 7 /* Initialize audit. */ +#define AUDIT_TRIGGER_MAX 7 /* * The special device filename (FreeBSD). @@ -59,7 +77,9 @@ /* * Pre-defined audit IDs */ -#define AU_DEFAUDITID -1 +#define AU_DEFAUDITID (uid_t)(-1) +#define AU_DEFAUDITSID 0 +#define AU_ASSIGN_ASID -1 /* * IPC types. @@ -103,6 +123,7 @@ #define A_GETKAUDIT 29 #define A_SETKAUDIT 30 #define A_SENDTRIGGER 31 +#define A_GETSINFO_ADDR 32 /* * Audit policy controls. @@ -183,6 +204,7 @@ struct auditinfo_addr { au_mask_t ai_mask; /* Audit masks. */ au_tid_addr_t ai_termid; /* Terminal ID. */ au_asid_t ai_asid; /* Audit session ID. */ + u_int64_t ai_flags; /* Audit session flags. */ }; typedef struct auditinfo_addr auditinfo_addr_t; @@ -192,6 +214,7 @@ struct auditpinfo { au_mask_t ap_mask; /* Audit masks. */ au_tid_t ap_termid; /* Terminal ID. */ au_asid_t ap_asid; /* Audit session ID. */ + u_int64_t ap_flags; /* Audit session flags. */ }; typedef struct auditpinfo auditpinfo_t; @@ -204,6 +227,16 @@ struct auditpinfo_addr { }; typedef struct auditpinfo_addr auditpinfo_addr_t; +struct au_session { + auditinfo_addr_t *as_aia_p; /* Ptr to full audit info. */ +#define as_asid as_aia_p->ai_asid +#define as_auid as_aia_p->ai_auid +#define as_termid as_aia_p->ai_termid + + au_mask_t as_mask; /* Process Audit Masks. */ +}; +typedef struct au_session au_session_t; + /* * Contents of token_t are opaque outside of libbsm. */ diff --git a/sys/bsm/audit_errno.h b/sys/bsm/audit_errno.h new file mode 100644 index 000000000000..667813c8863d --- /dev/null +++ b/sys/bsm/audit_errno.h @@ -0,0 +1,214 @@ +/*- + * Copyright (c) 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/sys/bsm/audit_errno.h#4 $ + */ + +#ifndef _BSM_AUDIT_ERRNO_H_ +#define _BSM_AUDIT_ERRNO_H_ + +/* + * For the purposes of portable encoding, we convert between local error + * numbers and Solaris error numbers (as well as some extensions for error + * numbers that don't exist in Solaris). Although the first 35 or so + * constants are the same across all OS's, we don't handle that in any + * special way. + * + * When adding constants here, also add them to bsm_errno.c. + */ +#define BSM_ESUCCESS 0 +#define BSM_EPERM 1 +#define BSM_ENOENT 2 +#define BSM_ESRCH 3 +#define BSM_EINTR 4 +#define BSM_EIO 5 +#define BSM_ENXIO 6 +#define BSM_E2BIG 7 +#define BSM_ENOEXEC 8 +#define BSM_EBADF 9 +#define BSM_ECHILD 10 +#define BSM_EAGAIN 11 +#define BSM_ENOMEM 12 +#define BSM_EACCES 13 +#define BSM_EFAULT 14 +#define BSM_ENOTBLK 15 +#define BSM_EBUSY 16 +#define BSM_EEXIST 17 +#define BSM_EXDEV 18 +#define BSM_ENODEV 19 +#define BSM_ENOTDIR 20 +#define BSM_EISDIR 21 +#define BSM_EINVAL 22 +#define BSM_ENFILE 23 +#define BSM_EMFILE 24 +#define BSM_ENOTTY 25 +#define BSM_ETXTBSY 26 +#define BSM_EFBIG 27 +#define BSM_ENOSPC 28 +#define BSM_ESPIPE 29 +#define BSM_EROFS 30 +#define BSM_EMLINK 31 +#define BSM_EPIPE 32 +#define BSM_EDOM 33 +#define BSM_ERANGE 34 +#define BSM_ENOMSG 35 +#define BSM_EIDRM 36 +#define BSM_ECHRNG 37 /* Solaris/Linux-specific. */ +#define BSM_EL2NSYNC 38 /* Solaris/Linux-specific. */ +#define BSM_EL3HLT 39 /* Solaris/Linux-specific. */ +#define BSM_EL3RST 40 /* Solaris/Linux-specific. */ +#define BSM_ELNRNG 41 /* Solaris/Linux-specific. */ +#define BSM_EUNATCH 42 /* Solaris/Linux-specific. */ +#define BSM_ENOCSI 43 /* Solaris/Linux-specific. */ +#define BSM_EL2HLT 44 /* Solaris/Linux-specific. */ +#define BSM_EDEADLK 45 +#define BSM_ENOLCK 46 +#define BSM_ECANCELED 47 +#define BSM_ENOTSUP 48 +#define BSM_EDQUOT 49 +#define BSM_EBADE 50 /* Solaris/Linux-specific. */ +#define BSM_EBADR 51 /* Solaris/Linux-specific. */ +#define BSM_EXFULL 52 /* Solaris/Linux-specific. */ +#define BSM_ENOANO 53 /* Solaris/Linux-specific. */ +#define BSM_EBADRQC 54 /* Solaris/Linux-specific. */ +#define BSM_EBADSLT 55 /* Solaris/Linux-specific. */ +#define BSM_EDEADLOCK 56 /* Solaris-specific. */ +#define BSM_EBFONT 57 /* Solaris/Linux-specific. */ +#define BSM_EOWNERDEAD 58 /* Solaris/Linux-specific. */ +#define BSM_ENOTRECOVERABLE 59 /* Solaris/Linux-specific. */ +#define BSM_ENOSTR 60 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ENODATA 61 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ETIME 62 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ENOSR 63 /* Solaris/Darwin/Linux-specific. */ +#define BSM_ENONET 64 /* Solaris/Linux-specific. */ +#define BSM_ENOPKG 65 /* Solaris/Linux-specific. */ +#define BSM_EREMOTE 66 +#define BSM_ENOLINK 67 +#define BSM_EADV 68 /* Solaris/Linux-specific. */ +#define BSM_ESRMNT 69 /* Solaris/Linux-specific. */ +#define BSM_ECOMM 70 /* Solaris/Linux-specific. */ +#define BSM_EPROTO 71 +#define BSM_ELOCKUNMAPPED 72 /* Solaris-specific. */ +#define BSM_ENOTACTIVE 73 /* Solaris-specific. */ +#define BSM_EMULTIHOP 74 +#define BSM_EBADMSG 77 +#define BSM_ENAMETOOLONG 78 +#define BSM_EOVERFLOW 79 +#define BSM_ENOTUNIQ 80 /* Solaris/Linux-specific. */ +#define BSM_EBADFD 81 /* Solaris/Linux-specific. */ +#define BSM_EREMCHG 82 /* Solaris/Linux-specific. */ +#define BSM_ELIBACC 83 /* Solaris/Linux-specific. */ +#define BSM_ELIBBAD 84 /* Solaris/Linux-specific. */ +#define BSM_ELIBSCN 85 /* Solaris/Linux-specific. */ +#define BSM_ELIBMAX 86 /* Solaris/Linux-specific. */ +#define BSM_ELIBEXEC 87 /* Solaris/Linux-specific. */ +#define BSM_EILSEQ 88 +#define BSM_ENOSYS 89 +#define BSM_ELOOP 90 +#define BSM_ERESTART 91 +#define BSM_ESTRPIPE 92 /* Solaris/Linux-specific. */ +#define BSM_ENOTEMPTY 93 +#define BSM_EUSERS 94 +#define BSM_ENOTSOCK 95 +#define BSM_EDESTADDRREQ 96 +#define BSM_EMSGSIZE 97 +#define BSM_EPROTOTYPE 98 +#define BSM_ENOPROTOOPT 99 +#define BSM_EPROTONOSUPPORT 120 +#define BSM_ESOCKTNOSUPPORT 121 +#define BSM_EOPNOTSUPP 122 +#define BSM_EPFNOSUPPORT 123 +#define BSM_EAFNOSUPPORT 124 +#define BSM_EADDRINUSE 125 +#define BSM_EADDRNOTAVAIL 126 +#define BSM_ENETDOWN 127 +#define BSM_ENETUNREACH 128 +#define BSM_ENETRESET 129 +#define BSM_ECONNABORTED 130 +#define BSM_ECONNRESET 131 +#define BSM_ENOBUFS 132 +#define BSM_EISCONN 133 +#define BSM_ENOTCONN 134 +#define BSM_ESHUTDOWN 143 +#define BSM_ETOOMANYREFS 144 +#define BSM_ETIMEDOUT 145 +#define BSM_ECONNREFUSED 146 +#define BSM_EHOSTDOWN 147 +#define BSM_EHOSTUNREACH 148 +#define BSM_EALREADY 149 +#define BSM_EINPROGRESS 150 +#define BSM_ESTALE 151 + +/* + * OpenBSM constants for error numbers not defined in Solaris. In the event + * that these errors are added to Solaris, we will deprecate the OpenBSM + * numbers in the same way we do for audit event constants. + * + * ELAST doesn't get a constant in the BSM space. + */ +#define BSM_EPROCLIM 190 /* FreeBSD/Darwin-specific. */ +#define BSM_EBADRPC 191 /* FreeBSD/Darwin-specific. */ +#define BSM_ERPCMISMATCH 192 /* FreeBSD/Darwin-specific. */ +#define BSM_EPROGUNAVAIL 193 /* FreeBSD/Darwin-specific. */ +#define BSM_EPROGMISMATCH 194 /* FreeBSD/Darwin-specific. */ +#define BSM_EPROCUNAVAIL 195 /* FreeBSD/Darwin-specific. */ +#define BSM_EFTYPE 196 /* FreeBSD/Darwin-specific. */ +#define BSM_EAUTH 197 /* FreeBSD/Darwin-specific. */ +#define BSM_ENEEDAUTH 198 /* FreeBSD/Darwin-specific. */ +#define BSM_ENOATTR 199 /* FreeBSD/Darwin-specific. */ +#define BSM_EDOOFUS 200 /* FreeBSD-specific. */ +#define BSM_EJUSTRETURN 201 /* FreeBSD-specific. */ +#define BSM_ENOIOCTL 202 /* FreeBSD-specific. */ +#define BSM_EDIRIOCTL 203 /* FreeBSD-specific. */ +#define BSM_EPWROFF 204 /* Darwin-specific. */ +#define BSM_EDEVERR 205 /* Darwin-specific. */ +#define BSM_EBADEXEC 206 /* Darwin-specific. */ +#define BSM_EBADARCH 207 /* Darwin-specific. */ +#define BSM_ESHLIBVERS 208 /* Darwin-specific. */ +#define BSM_EBADMACHO 209 /* Darwin-specific. */ +#define BSM_EPOLICY 210 /* Darwin-specific. */ +#define BSM_EDOTDOT 211 /* Linux-specific. */ +#define BSM_EUCLEAN 212 /* Linux-specific. */ +#define BSM_ENOTNAM 213 /* Linux(Xenix?)-specific. */ +#define BSM_ENAVAIL 214 /* Linux(Xenix?)-specific. */ +#define BSM_EISNAM 215 /* Linux(Xenix?)-specific. */ +#define BSM_EREMOTEIO 216 /* Linux-specific. */ +#define BSM_ENOMEDIUM 217 /* Linux-specific. */ +#define BSM_EMEDIUMTYPE 218 /* Linux-specific. */ +#define BSM_ENOKEY 219 /* Linux-specific. */ +#define BSM_EKEYEXPIRED 220 /* Linux-specific. */ +#define BSM_EKEYREVOKED 221 /* Linux-specific. */ +#define BSM_EKEYREJECTED 222 /* Linux-specific. */ + +/* + * In the event that OpenBSM doesn't have a file representation of a local + * error number, use this. + */ +#define BSM_UNKNOWNERR 250 /* OpenBSM-specific. */ + +#endif /* !_BSM_AUDIT_ERRNO_H_ */ diff --git a/sys/bsm/audit_internal.h b/sys/bsm/audit_internal.h index d3482b3d7478..71a51307ab98 100644 --- a/sys/bsm/audit_internal.h +++ b/sys/bsm/audit_internal.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005 Apple Inc. + * Copyright (c) 2005-2008 Apple Inc. * Copyright (c) 2005 SPARTA, Inc. * All rights reserved. * @@ -30,7 +30,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/sys/bsm/audit_internal.h#2 $ + * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_internal.h#5 $ */ #ifndef _AUDIT_INTERNAL_H diff --git a/sys/bsm/audit_kevents.h b/sys/bsm/audit_kevents.h index 34cf545270ab..57351b5ea7b9 100644 --- a/sys/bsm/audit_kevents.h +++ b/sys/bsm/audit_kevents.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/sys/bsm/audit_kevents.h#3 $ + * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_kevents.h#4 $ */ #ifndef _BSM_AUDIT_KEVENTS_H_ @@ -58,7 +58,6 @@ #define AUE_UMOUNT 12 #define AUE_JUNK 13 /* Solaris-specific. */ #define AUE_ACCESS 14 -#define AUE_CHECKUSERACCESS AUE_ACCESS /* Darwin-specific. */ #define AUE_KILL 15 #define AUE_STAT 16 #define AUE_LSTAT 17 @@ -560,7 +559,7 @@ #define AUE_ACCESS_EXTENDED 43162 /* Darwin. */ #define AUE_CHMOD_EXTENDED 43163 /* Darwin. */ #define AUE_FCHMOD_EXTENDED 43164 /* Darwin. */ -#define AUE_FSTAT_EXTENDED 43165 /* Dariwn. */ +#define AUE_FSTAT_EXTENDED 43165 /* Darwin. */ #define AUE_LSTAT_EXTENDED 43166 /* Darwin. */ #define AUE_MKDIR_EXTENDED 43167 /* Darwin. */ #define AUE_MKFIFO_EXTENDED 43168 /* Darwin. */ @@ -585,6 +584,8 @@ #define AUE_CAP_GETRIGHTS 43187 /* TrustedBSD. */ #define AUE_CAP_ENTER 43188 /* TrustedBSD. */ #define AUE_CAP_GETMODE 43189 /* TrustedBSD. */ +#define AUE_POSIX_SPAWN 43190 /* Darwin. */ +#define AUE_FSGETPATH 43191 /* Darwin. */ /* * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the @@ -656,13 +657,42 @@ /* * Possible desired future values based on review of BSD/Darwin system calls. */ +#define AUE_ACCESSEXTENDED AUE_NULL +#define AUE_ATGETMSG AUE_NULL +#define AUE_ATPUTMSG AUE_NULL +#define AUE_ATSOCKET AUE_NULL +#define AUE_ATPGETREQ AUE_NULL +#define AUE_ATPGETRSP AUE_NULL +#define AUE_ATPSNDREQ AUE_NULL +#define AUE_ATPSNDRSP AUE_NULL +#define AUE_BSDTHREADCREATE AUE_NULL +#define AUE_BSDTHREADTERMINATE AUE_NULL +#define AUE_BSDTHREADREGISTER AUE_NULL +#define AUE_CHMODEXTENDED AUE_NULL +#define AUE_CHUD AUE_NULL +#define AUE_CSOPS AUE_NULL #define AUE_DUP AUE_NULL +#define AUE_FCHMODEXTENDED AUE_NULL +#define AUE_FDATASYNC AUE_NULL +#define AUE_FFSCTL AUE_NULL +#define AUE_FGETATTRLIST AUE_NULL +#define AUE_FGETXATTR AUE_NULL +#define AUE_FLISTXATTR AUE_NULL +#define AUE_FREMOVEXATTR AUE_NULL #define AUE_FSCTL AUE_NULL +#define AUE_FSETATTRLIST AUE_NULL +#define AUE_FSETXATTR AUE_NULL +#define AUE_FSTATEXTENDED AUE_NULL +#define AUE_FSTATFS64 AUE_NULL #define AUE_FSTATV AUE_NULL +#define AUE_FSTAT64 AUE_NULL +#define AUE_FSTAT64EXTENDED AUE_NULL #define AUE_GCCONTROL AUE_NULL +#define AUE_GETDIRENTRIES64 AUE_NULL #define AUE_GETDTABLESIZE AUE_NULL #define AUE_GETEGID AUE_NULL #define AUE_GETEUID AUE_NULL +#define AUE_GETFSSTAT64 AUE_NULL #define AUE_GETGID AUE_NULL #define AUE_GETGROUPS AUE_NULL #define AUE_GETITIMER AUE_NULL @@ -675,24 +705,53 @@ #define AUE_GETPRIORITY AUE_NULL #define AUE_GETRLIMIT AUE_NULL #define AUE_GETRUSAGE AUE_NULL +#define AUE_GETSGROUPS AUE_NULL #define AUE_GETSID AUE_NULL #define AUE_GETSOCKNAME AUE_NULL #define AUE_GETTIMEOFDAY AUE_NULL +#define AUE_GETTID AUE_NULL #define AUE_GETUID AUE_NULL #define AUE_GETSOCKOPT AUE_NULL -#define AUE_GTSOCKOPT AUE_GETSOCKOPT /* XXX: Typo in Darwin. */ +#define AUE_GETWGROUPS AUE_NULL +#define AUE_GETXATTR AUE_NULL +#define AUE_IDENTITYSVC AUE_NULL +#define AUE_INITGROUPS AUE_NULL +#define AUE_IOPOLICYSYS AUE_NULL #define AUE_ISSETUGID AUE_NULL +#define AUE_LIOLISTIO AUE_NULL +#define AUE_LISTXATTR AUE_NULL +#define AUE_LSTATEXTENDED AUE_NULL #define AUE_LSTATV AUE_NULL +#define AUE_LSTAT64 AUE_NULL +#define AUE_LSTAT64EXTENDED AUE_NULL #define AUE_MADVISE AUE_NULL #define AUE_MINCORE AUE_NULL #define AUE_MKCOMPLEX AUE_NULL +#define AUE_MKDIREXTENDED AUE_NULL +#define AUE_MKFIFOEXTENDED AUE_NULL #define AUE_MODWATCH AUE_NULL #define AUE_MSGCL AUE_NULL #define AUE_MSYNC AUE_NULL +#define AUE_OPENEXTENDED AUE_NULL #define AUE_PREAD AUE_NULL #define AUE_PWRITE AUE_NULL #define AUE_PREADV AUE_NULL +#define AUE_PROCINFO AUE_NULL +#define AUE_PTHREADCANCELED AUE_NULL +#define AUE_PTHREADCHDIR AUE_NULL +#define AUE_PTHREADCONDBROADCAST AUE_NULL +#define AUE_PTHREADCONDDESTORY AUE_NULL +#define AUE_PTHREADCONDINIT AUE_NULL +#define AUE_PTHREADCONDSIGNAL AUE_NULL +#define AUE_PTHREADCONDWAIT AUE_NULL +#define AUE_PTHREADFCHDIR AUE_NULL +#define AUE_PTHREADMARK AUE_NULL +#define AUE_PTHREADMUTEXDESTROY AUE_NULL +#define AUE_PTHREADMUTEXINIT AUE_NULL +#define AUE_PTHREADMUTEXTRYLOCK AUE_NULL +#define AUE_PTHREADMUTEXUNLOCK AUE_NULL #define AUE_PWRITEV AUE_NULL +#define AUE_REMOVEXATTR AUE_NULL #define AUE_SBRK AUE_NULL #define AUE_SELECT AUE_NULL #define AUE_SEMDESTROY AUE_NULL @@ -701,7 +760,15 @@ #define AUE_SEMPOST AUE_NULL #define AUE_SEMTRYWAIT AUE_NULL #define AUE_SEMWAIT AUE_NULL +#define AUE_SEMWAITSIGNAL AUE_NULL #define AUE_SETITIMER AUE_NULL +#define AUE_SETSGROUPS AUE_NULL +#define AUE_SETTID AUE_NULL +#define AUE_SETTIDWITHPID AUE_NULL +#define AUE_SETWGROUPS AUE_NULL +#define AUE_SETXATTR AUE_NULL +#define AUE_SHAREDREGIONCHECK AUE_NULL +#define AUE_SHAREDREGIONMAP AUE_NULL #define AUE_SIGACTION AUE_NULL #define AUE_SIGALTSTACK AUE_NULL #define AUE_SIGPENDING AUE_NULL @@ -710,11 +777,21 @@ #define AUE_SIGSUSPEND AUE_NULL #define AUE_SIGWAIT AUE_NULL #define AUE_SSTK AUE_NULL +#define AUE_STACKSNAPSHOT AUE_NULL +#define AUE_STATEXTENDED AUE_NULL +#define AUE_STATFS64 AUE_NULL #define AUE_STATV AUE_NULL +#define AUE_STAT64 AUE_NULL +#define AUE_STAT64EXTENDED AUE_NULL #define AUE_SYNC AUE_NULL #define AUE_SYSCALL AUE_NULL #define AUE_TABLE AUE_NULL +#define AUE_UMASKEXTENDED AUE_NULL +#define AUE_VMPRESSUREMONITOR AUE_NULL #define AUE_WAITEVENT AUE_NULL +#define AUE_WAITID AUE_NULL #define AUE_WATCHEVENT AUE_NULL +#define AUE_WORKQOPEN AUE_NULL +#define AUE_WORKQOPS AUE_NULL #endif /* !_BSM_AUDIT_KEVENTS_H_ */ diff --git a/sys/bsm/audit_record.h b/sys/bsm/audit_record.h index ccca15b646d1..7295bc4ac5b1 100644 --- a/sys/bsm/audit_record.h +++ b/sys/bsm/audit_record.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/sys/bsm/audit_record.h#3 $ + * $P4: //depot/projects/trustedbsd/openbsm/sys/bsm/audit_record.h#8 $ */ #ifndef _BSM_AUDIT_RECORD_H_ @@ -164,14 +164,11 @@ #define AUDIT_HEADER_VERSION_SOLARIS 2 #define AUDIT_HEADER_VERSION_TSOL25 3 #define AUDIT_HEADER_VERSION_TSOL 4 -#define AUDIT_HEADER_VERSION_OPENBSM 10 +#define AUDIT_HEADER_VERSION_OPENBSM10 10 +#define AUDIT_HEADER_VERSION_OPENBSM11 11 +#define AUDIT_HEADER_VERSION_OPENBSM AUDIT_HEADER_VERSION_OPENBSM11 -/* - * BSM define is AUT_TRAILER_MAGIC; Apple BSM define is TRAILER_PAD_MAGIC; we - * split the difference, will remove the Apple define for the next release. - */ #define AUT_TRAILER_MAGIC 0xb105 -#define TRAILER_PAD_MAGIC AUT_TRAILER_MAGIC /* BSM library calls */ @@ -182,6 +179,7 @@ struct in6_addr; struct ip; struct ipc_perm; struct kevent; +struct sockaddr; struct sockaddr_in; struct sockaddr_in6; struct sockaddr_un; @@ -208,6 +206,7 @@ token_t *au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod); token_t *au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod); token_t *au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod); token_t *au_to_header64(int rec_size, au_event_t e_type, au_emod_t e_mod); +token_t *au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod); #endif token_t *au_to_me(void); @@ -251,15 +250,8 @@ token_t *au_to_return(char status, uint32_t ret); token_t *au_to_return32(char status, uint32_t ret); token_t *au_to_return64(char status, uint64_t ret); token_t *au_to_seq(long audit_count); - -#if defined(_KERNEL) || defined(KERNEL) -token_t *au_to_socket(struct socket *so); -token_t *au_to_socket_ex_32(uint16_t lp, uint16_t rp, struct sockaddr *la, - struct sockaddr *ta); -token_t *au_to_socket_ex_128(uint16_t lp, uint16_t rp, struct sockaddr *la, - struct sockaddr *ta); -#endif - +token_t *au_to_socket_ex(u_short so_domain, u_short so_type, + struct sockaddr *sa_local, struct sockaddr *sa_remote); token_t *au_to_sock_inet(struct sockaddr_in *so); token_t *au_to_sock_inet32(struct sockaddr_in *so); token_t *au_to_sock_inet128(struct sockaddr_in6 *so); @@ -277,8 +269,8 @@ token_t *au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, token_t *au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid); #if defined(_KERNEL) || defined(KERNEL) -token_t *au_to_exec_args(const char *args, int argc); -token_t *au_to_exec_env(const char *envs, int envc); +token_t *au_to_exec_args(char *args, int argc); +token_t *au_to_exec_env(char *envs, int envc); #else token_t *au_to_exec_args(char **argv); token_t *au_to_exec_env(char **envp); @@ -288,6 +280,12 @@ token_t *au_to_kevent(struct kevent *kev); token_t *au_to_trailer(int rec_size); token_t *au_to_zonename(const char *zonename); +/* + * BSM library routines for manipulating errno values. + */ +int au_bsm_to_errno(u_char bsm_error, int *errorp); +u_char au_errno_to_bsm(int error); + __END_DECLS #endif /* ! _BSM_AUDIT_RECORD_H_ */ diff --git a/test/Makefile.in b/test/Makefile.in index 9eb97fac459c..737f3b1ea22e 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/test/Makefile.in#6 $ +# $P4: //depot/projects/trustedbsd/openbsm/test/Makefile.in#7 $ # VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/test/bsm/Makefile.in b/test/bsm/Makefile.in index 128b03dac9fd..aa06a80d8be9 100644 --- a/test/bsm/Makefile.in +++ b/test/bsm/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/test/bsm/Makefile.in#6 $ +# $P4: //depot/projects/trustedbsd/openbsm/test/bsm/Makefile.in#7 $ # VPATH = @srcdir@ diff --git a/test/bsm/generate.c b/test/bsm/generate.c index d066246b161c..249e8858d034 100644 --- a/test/bsm/generate.c +++ b/test/bsm/generate.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2006-2007 Robert N. M. Watson + * Copyright (c) 2008 Apple Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $P4: //depot/projects/trustedbsd/openbsm/test/bsm/generate.c#9 $ + * $P4: //depot/projects/trustedbsd/openbsm/test/bsm/generate.c#12 $ */ /* @@ -553,7 +554,7 @@ generate_process64ex_record(const char *directory, const char *record_filename, free(buf); } -static char return32_status = 0xd7; +static char return32_status = EINVAL; static uint32_t return32_ret = 0x12345678; static void @@ -561,7 +562,8 @@ generate_return32_token(const char *directory, const char *token_filename) { token_t *return32_token; - return32_token = au_to_return32(return32_status, return32_ret); + return32_token = au_to_return32(au_errno_to_bsm(return32_status), + return32_ret); if (return32_token == NULL) err(EX_UNAVAILABLE, "au_to_return32"); write_token(directory, token_filename, return32_token); @@ -572,7 +574,8 @@ generate_return32_record(const char *directory, const char *record_filename) { token_t *return32_token; - return32_token = au_to_return32(return32_status, return32_ret); + return32_token = au_to_return32(au_errno_to_bsm(return32_status), + return32_ret); if (return32_token == NULL) err(EX_UNAVAILABLE, "au_to_return32"); write_record(directory, record_filename, return32_token, AUE_NULL); @@ -913,6 +916,124 @@ generate_zonename_record(const char *directory, const char *record_filename) write_record(directory, record_filename, zonename_token, AUE_NULL); } +static u_short socketex_domain = AF_INET; +static u_short socketex_type = SOCK_STREAM; +static struct sockaddr_in socketex_laddr, socketex_raddr; + +static void +generate_socketex_token(const char *directory, const char *token_filename) +{ + token_t *socketex_token; + + bzero(&socketex_laddr, sizeof(socketex_laddr)); + socketex_laddr.sin_family = AF_INET; + socketex_laddr.sin_len = sizeof(socketex_laddr); + socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + bzero(&socketex_raddr, sizeof(socketex_raddr)); + socketex_raddr.sin_family = AF_INET; + socketex_raddr.sin_len = sizeof(socketex_raddr); + socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + socketex_token = au_to_socket_ex(socketex_domain, socketex_type, + (struct sockaddr *)&socketex_laddr, + (struct sockaddr *)&socketex_raddr); + if (socketex_token == NULL) + err(EX_UNAVAILABLE, "au_to_socket_ex"); + write_token(directory, token_filename, socketex_token); +} + +static void +generate_socketex_record(const char *directory, const char *record_filename) +{ + token_t *socketex_token; + + bzero(&socketex_laddr, sizeof(socketex_laddr)); + socketex_laddr.sin_family = AF_INET; + socketex_laddr.sin_len = sizeof(socketex_laddr); + socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + bzero(&socketex_raddr, sizeof(socketex_raddr)); + socketex_raddr.sin_family = AF_INET; + socketex_raddr.sin_len = sizeof(socketex_raddr); + socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + socketex_token = au_to_socket_ex(socketex_domain, socketex_type, + (struct sockaddr *)&socketex_laddr, + (struct sockaddr *)&socketex_raddr); + if (socketex_token == NULL) + err(EX_UNAVAILABLE, "au_to_socket_ex"); + write_record(directory, record_filename, socketex_token, AUE_NULL); +} + +/* + * Generate a series of error-number specific return tokens in records. + */ +static void +generate_error_record(const char *directory, const char *filename, int error) +{ + char pathname[PATH_MAX]; + token_t *return32_token; + + return32_token = au_to_return32(au_errno_to_bsm(error), -1); + if (return32_token == NULL) + err(EX_UNAVAILABLE, "au_to_return32"); + (void)snprintf(pathname, PATH_MAX, "%s_record", filename); + write_record(directory, pathname, return32_token, AUE_NULL); +} + +/* + * Not all the error numbers, just a few present on all platforms for now. + */ +const struct { + int error_number; + const char *error_name; +} error_list[] = { + { EPERM, "EPERM" }, + { ENOENT, "ENOENT" }, + { ESRCH, "ESRCH" }, + { EINTR, "EINTR" }, + { EIO, "EIO" }, + { ENXIO, "ENXIO" }, + { E2BIG, "E2BIG" }, + { ENOEXEC, "ENOEXEC" }, + { EBADF, "EBADF" }, + { ECHILD, "ECHILD" }, + { EDEADLK, "EDEADLK" }, + { ENOMEM, "ENOMEM" }, + { EACCES, "EACCES" }, + { EFAULT, "EFAULT" }, + { ENOTBLK, "ENOTBLK" }, + { EBUSY, "EBUSY" }, + { EEXIST, "EEXIST" }, + { EXDEV, "EXDEV" }, + { ENODEV, "ENODEV" }, + { ENOTDIR, "ENOTDIR" }, + { EISDIR, "EISDIR" }, + { EINVAL, "EINVAL" }, + { ENFILE, "ENFILE" }, + { EMFILE, "EMFILE" }, + { ENOTTY, "ENOTTY" }, + { ETXTBSY, "ETXTBSY" }, + { EFBIG, "EFBIG" }, + { ENOSPC, "ENOSPC" }, + { ESPIPE, "ESPIPE" }, + { EROFS, "EROFS" }, + { EMLINK, "EMLINK" }, + { EPIPE, "EPIPE" } +}; +const int error_list_count = sizeof(error_list)/sizeof(error_list[0]); + +static void +do_error_records(const char *directory) +{ + int i; + + for (i = 0; i < error_list_count; i++) + generate_error_record(directory, error_list[i].error_name, + error_list[i].error_number); +} + int main(int argc, char *argv[]) { @@ -980,6 +1101,7 @@ main(int argc, char *argv[]) generate_groups_token(directory, "groups_token"); generate_attr32_token(directory, "attr32_token"); generate_zonename_token(directory, "zonename_token"); + generate_socketex_token(directory, "socketex_token"); } if (do_records) { @@ -1015,6 +1137,8 @@ main(int argc, char *argv[]) generate_groups_record(directory, "groups_record"); generate_attr32_record(directory, "attr32_record"); generate_zonename_record(directory, "zonename_record"); + generate_socketex_record(directory, "socketex_record"); + do_error_records(directory); } return (0); diff --git a/test/reference/E2BIG_record b/test/reference/E2BIG_record Binary files differnew file mode 100644 index 000000000000..d95b8559abdf --- /dev/null +++ b/test/reference/E2BIG_record diff --git a/test/reference/EACCES_record b/test/reference/EACCES_record Binary files differnew file mode 100644 index 000000000000..6eecd6edaecc --- /dev/null +++ b/test/reference/EACCES_record diff --git a/test/reference/EBADF_record b/test/reference/EBADF_record Binary files differnew file mode 100644 index 000000000000..d169ad2b55c1 --- /dev/null +++ b/test/reference/EBADF_record diff --git a/test/reference/EBUSY_record b/test/reference/EBUSY_record Binary files differnew file mode 100644 index 000000000000..6d3e89607729 --- /dev/null +++ b/test/reference/EBUSY_record diff --git a/test/reference/ECHILD_record b/test/reference/ECHILD_record Binary files differnew file mode 100644 index 000000000000..3beca2a8244b --- /dev/null +++ b/test/reference/ECHILD_record diff --git a/test/reference/EDEADLK_record b/test/reference/EDEADLK_record Binary files differnew file mode 100644 index 000000000000..9d6a25b27739 --- /dev/null +++ b/test/reference/EDEADLK_record diff --git a/test/reference/EEXIST_record b/test/reference/EEXIST_record Binary files differnew file mode 100644 index 000000000000..04dbf35bbc84 --- /dev/null +++ b/test/reference/EEXIST_record diff --git a/test/reference/EFAULT_record b/test/reference/EFAULT_record Binary files differnew file mode 100644 index 000000000000..1ed507832045 --- /dev/null +++ b/test/reference/EFAULT_record diff --git a/test/reference/EFBIG_record b/test/reference/EFBIG_record Binary files differnew file mode 100644 index 000000000000..d0716ff9eaf3 --- /dev/null +++ b/test/reference/EFBIG_record diff --git a/test/reference/EINTR_record b/test/reference/EINTR_record Binary files differnew file mode 100644 index 000000000000..ab9da8ee1566 --- /dev/null +++ b/test/reference/EINTR_record diff --git a/test/reference/EINVAL_record b/test/reference/EINVAL_record Binary files differnew file mode 100644 index 000000000000..a658c62915d0 --- /dev/null +++ b/test/reference/EINVAL_record diff --git a/test/reference/EIO_record b/test/reference/EIO_record Binary files differnew file mode 100644 index 000000000000..6752b71ad893 --- /dev/null +++ b/test/reference/EIO_record diff --git a/test/reference/EISDIR_record b/test/reference/EISDIR_record Binary files differnew file mode 100644 index 000000000000..8cec4e10fbcb --- /dev/null +++ b/test/reference/EISDIR_record diff --git a/test/reference/EMFILE_record b/test/reference/EMFILE_record Binary files differnew file mode 100644 index 000000000000..8bc30d829541 --- /dev/null +++ b/test/reference/EMFILE_record diff --git a/test/reference/EMLINK_record b/test/reference/EMLINK_record Binary files differnew file mode 100644 index 000000000000..a84cf482a47d --- /dev/null +++ b/test/reference/EMLINK_record diff --git a/test/reference/ENFILE_record b/test/reference/ENFILE_record Binary files differnew file mode 100644 index 000000000000..5dc5f597bd4d --- /dev/null +++ b/test/reference/ENFILE_record diff --git a/test/reference/ENODEV_record b/test/reference/ENODEV_record Binary files differnew file mode 100644 index 000000000000..c2e642b52fd4 --- /dev/null +++ b/test/reference/ENODEV_record diff --git a/test/reference/ENOENT_record b/test/reference/ENOENT_record Binary files differnew file mode 100644 index 000000000000..10d855ad54cc --- /dev/null +++ b/test/reference/ENOENT_record diff --git a/test/reference/ENOEXEC_record b/test/reference/ENOEXEC_record Binary files differnew file mode 100644 index 000000000000..180ee3aae2c1 --- /dev/null +++ b/test/reference/ENOEXEC_record diff --git a/test/reference/ENOMEM_record b/test/reference/ENOMEM_record Binary files differnew file mode 100644 index 000000000000..cc7f1c159241 --- /dev/null +++ b/test/reference/ENOMEM_record diff --git a/test/reference/ENOSPC_record b/test/reference/ENOSPC_record Binary files differnew file mode 100644 index 000000000000..a2795ce574dc --- /dev/null +++ b/test/reference/ENOSPC_record diff --git a/test/reference/ENOTBLK_record b/test/reference/ENOTBLK_record Binary files differnew file mode 100644 index 000000000000..b2021628f1bd --- /dev/null +++ b/test/reference/ENOTBLK_record diff --git a/test/reference/ENOTDIR_record b/test/reference/ENOTDIR_record Binary files differnew file mode 100644 index 000000000000..33f7427a4973 --- /dev/null +++ b/test/reference/ENOTDIR_record diff --git a/test/reference/ENOTTY_record b/test/reference/ENOTTY_record Binary files differnew file mode 100644 index 000000000000..c9c8f36165f3 --- /dev/null +++ b/test/reference/ENOTTY_record diff --git a/test/reference/ENXIO_record b/test/reference/ENXIO_record Binary files differnew file mode 100644 index 000000000000..83894dba3cde --- /dev/null +++ b/test/reference/ENXIO_record diff --git a/test/reference/EPERM_record b/test/reference/EPERM_record Binary files differnew file mode 100644 index 000000000000..41f20ba540b1 --- /dev/null +++ b/test/reference/EPERM_record diff --git a/test/reference/EPIPE_record b/test/reference/EPIPE_record Binary files differnew file mode 100644 index 000000000000..795c9f716cd2 --- /dev/null +++ b/test/reference/EPIPE_record diff --git a/test/reference/EROFS_record b/test/reference/EROFS_record Binary files differnew file mode 100644 index 000000000000..bd0a91baac9e --- /dev/null +++ b/test/reference/EROFS_record diff --git a/test/reference/ESPIPE_record b/test/reference/ESPIPE_record Binary files differnew file mode 100644 index 000000000000..7c1bed3613f5 --- /dev/null +++ b/test/reference/ESPIPE_record diff --git a/test/reference/ESRCH_record b/test/reference/ESRCH_record Binary files differnew file mode 100644 index 000000000000..43a04e12931d --- /dev/null +++ b/test/reference/ESRCH_record diff --git a/test/reference/ETXTBSY_record b/test/reference/ETXTBSY_record Binary files differnew file mode 100644 index 000000000000..b69309f1379b --- /dev/null +++ b/test/reference/ETXTBSY_record diff --git a/test/reference/EXDEV_record b/test/reference/EXDEV_record Binary files differnew file mode 100644 index 000000000000..c60cc26d7696 --- /dev/null +++ b/test/reference/EXDEV_record diff --git a/test/reference/arg32_record b/test/reference/arg32_record Binary files differindex 2222ed03c2c6..cb2379aa0430 100644 --- a/test/reference/arg32_record +++ b/test/reference/arg32_record diff --git a/test/reference/data_record b/test/reference/data_record Binary files differindex 8088f4eb37d7..7876b223ebd3 100644 --- a/test/reference/data_record +++ b/test/reference/data_record diff --git a/test/reference/file_record b/test/reference/file_record Binary files differindex b56d5cccbb45..a80b8ed23337 100644 --- a/test/reference/file_record +++ b/test/reference/file_record diff --git a/test/reference/header32_token b/test/reference/header32_token Binary files differindex dd72c1cf61a3..3386b86789ec 100644 --- a/test/reference/header32_token +++ b/test/reference/header32_token diff --git a/test/reference/in_addr_record b/test/reference/in_addr_record Binary files differindex 4f308e068526..2b12d8064991 100644 --- a/test/reference/in_addr_record +++ b/test/reference/in_addr_record diff --git a/test/reference/ip_record b/test/reference/ip_record Binary files differindex aee40a71153f..ebe66d91a5a8 100644 --- a/test/reference/ip_record +++ b/test/reference/ip_record diff --git a/test/reference/ipc_record b/test/reference/ipc_record Binary files differindex 4510f8819dca..9e7defc7d5a3 100644 --- a/test/reference/ipc_record +++ b/test/reference/ipc_record diff --git a/test/reference/iport_record b/test/reference/iport_record Binary files differindex 1375efbf483d..1f1adddc4cbd 100644 --- a/test/reference/iport_record +++ b/test/reference/iport_record diff --git a/test/reference/opaque_record b/test/reference/opaque_record Binary files differindex 247d6f2733da..c34ac5025538 100644 --- a/test/reference/opaque_record +++ b/test/reference/opaque_record diff --git a/test/reference/path_record b/test/reference/path_record Binary files differindex 0d32b86832a7..b809d7147553 100644 --- a/test/reference/path_record +++ b/test/reference/path_record diff --git a/test/reference/process32_record b/test/reference/process32_record Binary files differindex 9a3f7d9de206..0fc103f6fff4 100644 --- a/test/reference/process32_record +++ b/test/reference/process32_record diff --git a/test/reference/process32ex_record-IPv4 b/test/reference/process32ex_record-IPv4 Binary files differindex 6250b9c57ba9..7a1514c76fa7 100644 --- a/test/reference/process32ex_record-IPv4 +++ b/test/reference/process32ex_record-IPv4 diff --git a/test/reference/process32ex_record-IPv6 b/test/reference/process32ex_record-IPv6 Binary files differindex 22a3249258a8..44183fcf8125 100644 --- a/test/reference/process32ex_record-IPv6 +++ b/test/reference/process32ex_record-IPv6 diff --git a/test/reference/process64_record b/test/reference/process64_record Binary files differindex d8fca8eb4e6a..cf318bbbc827 100644 --- a/test/reference/process64_record +++ b/test/reference/process64_record diff --git a/test/reference/process64ex_record-IPv4 b/test/reference/process64ex_record-IPv4 Binary files differindex 3b7a728e7250..16969f8a3d3a 100644 --- a/test/reference/process64ex_record-IPv4 +++ b/test/reference/process64ex_record-IPv4 diff --git a/test/reference/process64ex_record-IPv6 b/test/reference/process64ex_record-IPv6 Binary files differindex 6563e25be6cd..bf8fc14e9ea2 100644 --- a/test/reference/process64ex_record-IPv6 +++ b/test/reference/process64ex_record-IPv6 diff --git a/test/reference/return32_record b/test/reference/return32_record Binary files differindex e57d26c0c74d..f0b8610afa43 100644 --- a/test/reference/return32_record +++ b/test/reference/return32_record diff --git a/test/reference/return32_token b/test/reference/return32_token index e7a209862e6b..4c6dc0c6a944 100644 --- a/test/reference/return32_token +++ b/test/reference/return32_token @@ -1 +1 @@ -'×4Vx
\ No newline at end of file +'4Vx
\ No newline at end of file diff --git a/test/reference/seq_record b/test/reference/seq_record Binary files differindex 75cea179e2ed..34674b85e308 100644 --- a/test/reference/seq_record +++ b/test/reference/seq_record diff --git a/test/reference/socketex_record b/test/reference/socketex_record Binary files differnew file mode 100644 index 000000000000..b41c5f9471cd --- /dev/null +++ b/test/reference/socketex_record diff --git a/test/reference/socketex_token b/test/reference/socketex_token Binary files differnew file mode 100644 index 000000000000..47a9e199a451 --- /dev/null +++ b/test/reference/socketex_token diff --git a/test/reference/subject32_record b/test/reference/subject32_record Binary files differindex f96d84c5e984..a806651cf71e 100644 --- a/test/reference/subject32_record +++ b/test/reference/subject32_record diff --git a/test/reference/subject32ex_record b/test/reference/subject32ex_record Binary files differindex 1d949a6e9184..1debf62609e5 100644 --- a/test/reference/subject32ex_record +++ b/test/reference/subject32ex_record diff --git a/test/reference/text_record b/test/reference/text_record Binary files differindex 2f3fce2bc9ab..b7d25db2301e 100644 --- a/test/reference/text_record +++ b/test/reference/text_record diff --git a/test/reference/zonename_record b/test/reference/zonename_record Binary files differindex cfb9e264d6d4..618285933cae 100644 --- a/test/reference/zonename_record +++ b/test/reference/zonename_record diff --git a/tools/Makefile.in b/tools/Makefile.in index d689761d39a6..0931a48f09bc 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # -# $P4: //depot/projects/trustedbsd/openbsm/tools/Makefile.in#9 $ +# $P4: //depot/projects/trustedbsd/openbsm/tools/Makefile.in#10 $ # VPATH = @srcdir@ |