diff options
Diffstat (limited to 'contrib/openbsm/libbsm')
33 files changed, 14788 insertions, 0 deletions
diff --git a/contrib/openbsm/libbsm/Makefile.am b/contrib/openbsm/libbsm/Makefile.am new file mode 100644 index 0000000..278f228 --- /dev/null +++ b/contrib/openbsm/libbsm/Makefile.am @@ -0,0 +1,157 @@ +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 = libbsm.la + +libbsm_la_SOURCES = \ + bsm_audit.c \ + bsm_class.c \ + bsm_control.c \ + bsm_domain.c \ + bsm_errno.c \ + bsm_event.c \ + bsm_fcntl.c \ + bsm_flags.c \ + bsm_io.c \ + bsm_mask.c \ + bsm_socket_type.c \ + bsm_token.c \ + bsm_user.c + +if HAVE_AUDIT_SYSCALLS +libbsm_la_SOURCES += \ + bsm_notify.c \ + bsm_wrappers.c +endif + +man3_MANS = \ + au_class.3 \ + au_control.3 \ + au_domain.3 \ + au_errno.3 \ + au_event.3 \ + au_fcntl_cmd.3 \ + au_free_token.3 \ + au_io.3 \ + au_mask.3 \ + au_notify.3 \ + au_open.3 \ + au_socket_type.3 \ + au_token.3 \ + au_user.3 \ + libbsm.3 + +install-exec-hook: + cd $(DESTDIR)$(mandir) && \ + $(LN_S) -f au_class.3 getauclassent.3 && \ + $(LN_S) -f au_class.3 getauclassent_r.3 && \ + $(LN_S) -f au_class.3 getauclassnam.3 && \ + $(LN_S) -f au_class.3 getauclassnam_r.3 && \ + $(LN_S) -f au_class.3 setauclass.3 && \ + $(LN_S) -f au_class.3 endauclass.3 && \ + $(LN_S) -f au_control.3 setac.3 && \ + $(LN_S) -f au_control.3 endac.3 && \ + $(LN_S) -f au_control.3 getacdir.3 && \ + $(LN_S) -f au_control.3 getacdist.3 && \ + $(LN_S) -f au_control.3 getacexpire.3 && \ + $(LN_S) -f au_control.3 getacfilesz.3 && \ + $(LN_S) -f au_control.3 getacflg.3 && \ + $(LN_S) -f au_control.3 getachost.3 && \ + $(LN_S) -f au_control.3 getacmin.3 && \ + $(LN_S) -f au_control.3 getacna.3 && \ + $(LN_S) -f au_control.3 getacpol.3 && \ + $(LN_S) -f au_control.3 au_poltostr.3 && \ + $(LN_S) -f au_control.3 ac_strtopol.3 && \ + $(LN_S) -f au_domain.3 au_bsm_to_domain.3 && \ + $(LN_S) -f au_domain.3 au_domain_to_bsm.3 && \ + $(LN_S) -f au_errno.3 au_bsm_to_errno.3 && \ + $(LN_S) -f au_errno.3 au_errno_to_bsm.3 && \ + $(LN_S) -f au_errno.3 au_strerror.3 && \ + $(LN_S) -f au_event.3 setauevent.3 && \ + $(LN_S) -f au_event.3 endauevent.3 && \ + $(LN_S) -f au_event.3 getauevent.3 && \ + $(LN_S) -f au_event.3 getauevent_r.3 && \ + $(LN_S) -f au_event.3 getauevnam.3 && \ + $(LN_S) -f au_event.3 getauevnam_r.3 && \ + $(LN_S) -f au_event.3 getauevnum.3 && \ + $(LN_S) -f au_event.3 getauevnum_r.3 && \ + $(LN_S) -f au_event.3 getauevnonam.3 && \ + $(LN_S) -f au_event.3 getauevnonam_r.3 && \ + $(LN_S) -f au_fcntl.3 au_bsm_to_fcntl_cmd.3 && \ + $(LN_S) -f au_fcntl.3 au_fcntl_cmd_to_bsm.3 && \ + $(LN_S) -f au_io.3 au_fetch_tok.3 && \ + $(LN_S) -f au_io.3 au_print_tok.3 && \ + $(LN_S) -f au_io.3 au_print_flags_tok.3 && \ + $(LN_S) -f au_io.3 au_read_rec.3 && \ + $(LN_S) -f au_mask.3 au_preselect.3 && \ + $(LN_S) -f au_mask.3 getauditflagsbin.3 && \ + $(LN_S) -f au_mask.3 getauditflagschar.3 && \ + $(LN_S) -f au_notify.3 au_get_state.3 && \ + $(LN_S) -f au_notify.3 au_notify_initialize.3 && \ + $(LN_S) -f au_notify.3 au_notify_terminate.3 && \ + $(LN_S) -f au_open.3 au_open.3 && \ + $(LN_S) -f au_open.3 au_write.3 && \ + $(LN_S) -f au_open.3 au_close.3 && \ + $(LN_S) -f au_open.3 au_close_buffer.3 && \ + $(LN_S) -f au_open.3 au_close_token.3 && \ + $(LN_S) -f au_socket_type.3 au_bsm_to_socket_type.3 && \ + $(LN_S) -f au_socket_type.3 au_socket_type_to_bsm.3 && \ + $(LN_S) -f au_token.3 au_to_arg32.3 && \ + $(LN_S) -f au_token.3 au_to_arg64.3 && \ + $(LN_S) -f au_token.3 au_to_arg.3 && \ + $(LN_S) -f au_token.3 au_to_attr64.3 && \ + $(LN_S) -f au_token.3 au_to_data.3 && \ + $(LN_S) -f au_token.3 au_to_exit.3 && \ + $(LN_S) -f au_token.3 au_to_groups.3 && \ + $(LN_S) -f au_token.3 au_to_newgroups.3 && \ + $(LN_S) -f au_token.3 au_to_in_addr.3 && \ + $(LN_S) -f au_token.3 au_to_in_addr_ex.3 && \ + $(LN_S) -f au_token.3 au_to_ip.3 && \ + $(LN_S) -f au_token.3 au_to_ipc.3 && \ + $(LN_S) -f au_token.3 au_to_ipc_perm.3 && \ + $(LN_S) -f au_token.3 au_to_iport.3 && \ + $(LN_S) -f au_token.3 au_to_opaque.3 && \ + $(LN_S) -f au_token.3 au_to_file.3 && \ + $(LN_S) -f au_token.3 au_to_text.3 && \ + $(LN_S) -f au_token.3 au_to_path.3 && \ + $(LN_S) -f au_token.3 au_to_process32.3 && \ + $(LN_S) -f au_token.3 au_to_process64.3 && \ + $(LN_S) -f au_token.3 au_to_process.3 && \ + $(LN_S) -f au_token.3 au_to_process32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_process64_ex.3 && \ + $(LN_S) -f au_token.3 au_to_process_ex.3 && \ + $(LN_S) -f au_token.3 au_to_return32.3 && \ + $(LN_S) -f au_token.3 au_to_return64.3 && \ + $(LN_S) -f au_token.3 au_to_return.3 && \ + $(LN_S) -f au_token.3 au_to_seq.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet32.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet128.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet.3 && \ + $(LN_S) -f au_token.3 au_to_socket_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject32.3 && \ + $(LN_S) -f au_token.3 au_to_subject64.3 && \ + $(LN_S) -f au_token.3 au_to_subject.3 && \ + $(LN_S) -f au_token.3 au_to_subject32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject64_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject_ex.3 && \ + $(LN_S) -f au_token.3 au_to_me.3 && \ + $(LN_S) -f au_token.3 au_to_exec_args.3 && \ + $(LN_S) -f au_token.3 au_to_exec_env.3 && \ + $(LN_S) -f au_token.3 au_to_header.3 && \ + $(LN_S) -f au_token.3 au_to_header32.3 && \ + $(LN_S) -f au_token.3 au_to_header64.3 && \ + $(LN_S) -f au_token.3 au_to_header_ex.3 && \ + $(LN_S) -f au_token.3 au_to_header32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_trailer.3 && \ + $(LN_S) -f au_token.3 au_to_zonename.3 && \ + $(LN_S) -f au_user.3 setauuser.3 && \ + $(LN_S) -f au_user.3 endauuser.3 && \ + $(LN_S) -f au_user.3 getauuserent.3 && \ + $(LN_S) -f au_user.3 getauuserent_r.3 && \ + $(LN_S) -f au_user.3 getauusernam.3 && \ + $(LN_S) -f au_user.3 getauusernam_r.3 && \ + $(LN_S) -f au_user.3 au_user_mask.3 && \ + $(LN_S) -f au_user.3 getfauditflags.3 diff --git a/contrib/openbsm/libbsm/Makefile.in b/contrib/openbsm/libbsm/Makefile.in new file mode 100644 index 0000000..0549153 --- /dev/null +++ b/contrib/openbsm/libbsm/Makefile.in @@ -0,0 +1,792 @@ +# Makefile.in generated by automake 1.12.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2012 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@ + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@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@ +@HAVE_AUDIT_SYSCALLS_TRUE@am__append_1 = \ +@HAVE_AUDIT_SYSCALLS_TRUE@ bsm_notify.c \ +@HAVE_AUDIT_SYSCALLS_TRUE@ bsm_wrappers.c + +subdir = libbsm +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(top_srcdir)/config/depcomp +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 = +CONFIG_CLEAN_VPATH_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 = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libbsm_la_LIBADD = +am__libbsm_la_SOURCES_DIST = bsm_audit.c bsm_class.c bsm_control.c \ + bsm_domain.c bsm_errno.c bsm_event.c bsm_fcntl.c bsm_flags.c \ + bsm_io.c bsm_mask.c bsm_socket_type.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_domain.lo bsm_errno.lo bsm_event.lo bsm_fcntl.lo \ + bsm_flags.lo bsm_io.lo bsm_mask.lo bsm_socket_type.lo \ + bsm_token.lo bsm_user.lo $(am__objects_1) +libbsm_la_OBJECTS = $(am_libbsm_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +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 = $(libbsm_la_SOURCES) +DIST_SOURCES = $(am__libbsm_la_SOURCES_DIST) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(man3_MANS) +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@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MIG = @MIG@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +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_build_prefix = @top_build_prefix@ +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 = libbsm.la +libbsm_la_SOURCES = bsm_audit.c bsm_class.c bsm_control.c bsm_domain.c \ + bsm_errno.c bsm_event.c bsm_fcntl.c bsm_flags.c bsm_io.c \ + bsm_mask.c bsm_socket_type.c bsm_token.c bsm_user.c \ + $(am__append_1) +man3_MANS = \ + au_class.3 \ + au_control.3 \ + au_domain.3 \ + au_errno.3 \ + au_event.3 \ + au_fcntl_cmd.3 \ + au_free_token.3 \ + au_io.3 \ + au_mask.3 \ + au_notify.3 \ + au_open.3 \ + au_socket_type.3 \ + au_token.3 \ + au_user.3 \ + libbsm.3 + +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 ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign libbsm/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libbsm/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 +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +libbsm.la: $(libbsm_la_OBJECTS) $(libbsm_la_DEPENDENCIES) $(EXTRA_libbsm_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libbsm_la_OBJECTS) $(libbsm_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@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_domain.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_fcntl.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@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_mask.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_notify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_socket_type.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_token.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_user.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsm_wrappers.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(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@ $(am__mv) $(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@ $(am__mv) $(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 +install-man3: $(man3_MANS) + @$(NORMAL_INSTALL) + @list1='$(man3_MANS)'; \ + list2=''; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) + +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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + 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; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +cscopelist: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically 'make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + @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 "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$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) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)"; 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: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_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 + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man3 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +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 uninstall-man + +uninstall-man: uninstall-man3 + +.MAKE: install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist 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-exec-hook \ + install-html install-html-am install-info install-info-am \ + install-libLTLIBRARIES install-man install-man3 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 \ + uninstall-man uninstall-man3 + + +install-exec-hook: + cd $(DESTDIR)$(mandir) && \ + $(LN_S) -f au_class.3 getauclassent.3 && \ + $(LN_S) -f au_class.3 getauclassent_r.3 && \ + $(LN_S) -f au_class.3 getauclassnam.3 && \ + $(LN_S) -f au_class.3 getauclassnam_r.3 && \ + $(LN_S) -f au_class.3 setauclass.3 && \ + $(LN_S) -f au_class.3 endauclass.3 && \ + $(LN_S) -f au_control.3 setac.3 && \ + $(LN_S) -f au_control.3 endac.3 && \ + $(LN_S) -f au_control.3 getacdir.3 && \ + $(LN_S) -f au_control.3 getacdist.3 && \ + $(LN_S) -f au_control.3 getacexpire.3 && \ + $(LN_S) -f au_control.3 getacfilesz.3 && \ + $(LN_S) -f au_control.3 getacflg.3 && \ + $(LN_S) -f au_control.3 getachost.3 && \ + $(LN_S) -f au_control.3 getacmin.3 && \ + $(LN_S) -f au_control.3 getacna.3 && \ + $(LN_S) -f au_control.3 getacpol.3 && \ + $(LN_S) -f au_control.3 au_poltostr.3 && \ + $(LN_S) -f au_control.3 ac_strtopol.3 && \ + $(LN_S) -f au_domain.3 au_bsm_to_domain.3 && \ + $(LN_S) -f au_domain.3 au_domain_to_bsm.3 && \ + $(LN_S) -f au_errno.3 au_bsm_to_errno.3 && \ + $(LN_S) -f au_errno.3 au_errno_to_bsm.3 && \ + $(LN_S) -f au_errno.3 au_strerror.3 && \ + $(LN_S) -f au_event.3 setauevent.3 && \ + $(LN_S) -f au_event.3 endauevent.3 && \ + $(LN_S) -f au_event.3 getauevent.3 && \ + $(LN_S) -f au_event.3 getauevent_r.3 && \ + $(LN_S) -f au_event.3 getauevnam.3 && \ + $(LN_S) -f au_event.3 getauevnam_r.3 && \ + $(LN_S) -f au_event.3 getauevnum.3 && \ + $(LN_S) -f au_event.3 getauevnum_r.3 && \ + $(LN_S) -f au_event.3 getauevnonam.3 && \ + $(LN_S) -f au_event.3 getauevnonam_r.3 && \ + $(LN_S) -f au_fcntl.3 au_bsm_to_fcntl_cmd.3 && \ + $(LN_S) -f au_fcntl.3 au_fcntl_cmd_to_bsm.3 && \ + $(LN_S) -f au_io.3 au_fetch_tok.3 && \ + $(LN_S) -f au_io.3 au_print_tok.3 && \ + $(LN_S) -f au_io.3 au_print_flags_tok.3 && \ + $(LN_S) -f au_io.3 au_read_rec.3 && \ + $(LN_S) -f au_mask.3 au_preselect.3 && \ + $(LN_S) -f au_mask.3 getauditflagsbin.3 && \ + $(LN_S) -f au_mask.3 getauditflagschar.3 && \ + $(LN_S) -f au_notify.3 au_get_state.3 && \ + $(LN_S) -f au_notify.3 au_notify_initialize.3 && \ + $(LN_S) -f au_notify.3 au_notify_terminate.3 && \ + $(LN_S) -f au_open.3 au_open.3 && \ + $(LN_S) -f au_open.3 au_write.3 && \ + $(LN_S) -f au_open.3 au_close.3 && \ + $(LN_S) -f au_open.3 au_close_buffer.3 && \ + $(LN_S) -f au_open.3 au_close_token.3 && \ + $(LN_S) -f au_socket_type.3 au_bsm_to_socket_type.3 && \ + $(LN_S) -f au_socket_type.3 au_socket_type_to_bsm.3 && \ + $(LN_S) -f au_token.3 au_to_arg32.3 && \ + $(LN_S) -f au_token.3 au_to_arg64.3 && \ + $(LN_S) -f au_token.3 au_to_arg.3 && \ + $(LN_S) -f au_token.3 au_to_attr64.3 && \ + $(LN_S) -f au_token.3 au_to_data.3 && \ + $(LN_S) -f au_token.3 au_to_exit.3 && \ + $(LN_S) -f au_token.3 au_to_groups.3 && \ + $(LN_S) -f au_token.3 au_to_newgroups.3 && \ + $(LN_S) -f au_token.3 au_to_in_addr.3 && \ + $(LN_S) -f au_token.3 au_to_in_addr_ex.3 && \ + $(LN_S) -f au_token.3 au_to_ip.3 && \ + $(LN_S) -f au_token.3 au_to_ipc.3 && \ + $(LN_S) -f au_token.3 au_to_ipc_perm.3 && \ + $(LN_S) -f au_token.3 au_to_iport.3 && \ + $(LN_S) -f au_token.3 au_to_opaque.3 && \ + $(LN_S) -f au_token.3 au_to_file.3 && \ + $(LN_S) -f au_token.3 au_to_text.3 && \ + $(LN_S) -f au_token.3 au_to_path.3 && \ + $(LN_S) -f au_token.3 au_to_process32.3 && \ + $(LN_S) -f au_token.3 au_to_process64.3 && \ + $(LN_S) -f au_token.3 au_to_process.3 && \ + $(LN_S) -f au_token.3 au_to_process32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_process64_ex.3 && \ + $(LN_S) -f au_token.3 au_to_process_ex.3 && \ + $(LN_S) -f au_token.3 au_to_return32.3 && \ + $(LN_S) -f au_token.3 au_to_return64.3 && \ + $(LN_S) -f au_token.3 au_to_return.3 && \ + $(LN_S) -f au_token.3 au_to_seq.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet32.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet128.3 && \ + $(LN_S) -f au_token.3 au_to_sock_inet.3 && \ + $(LN_S) -f au_token.3 au_to_socket_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject32.3 && \ + $(LN_S) -f au_token.3 au_to_subject64.3 && \ + $(LN_S) -f au_token.3 au_to_subject.3 && \ + $(LN_S) -f au_token.3 au_to_subject32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject64_ex.3 && \ + $(LN_S) -f au_token.3 au_to_subject_ex.3 && \ + $(LN_S) -f au_token.3 au_to_me.3 && \ + $(LN_S) -f au_token.3 au_to_exec_args.3 && \ + $(LN_S) -f au_token.3 au_to_exec_env.3 && \ + $(LN_S) -f au_token.3 au_to_header.3 && \ + $(LN_S) -f au_token.3 au_to_header32.3 && \ + $(LN_S) -f au_token.3 au_to_header64.3 && \ + $(LN_S) -f au_token.3 au_to_header_ex.3 && \ + $(LN_S) -f au_token.3 au_to_header32_ex.3 && \ + $(LN_S) -f au_token.3 au_to_trailer.3 && \ + $(LN_S) -f au_token.3 au_to_zonename.3 && \ + $(LN_S) -f au_user.3 setauuser.3 && \ + $(LN_S) -f au_user.3 endauuser.3 && \ + $(LN_S) -f au_user.3 getauuserent.3 && \ + $(LN_S) -f au_user.3 getauuserent_r.3 && \ + $(LN_S) -f au_user.3 getauusernam.3 && \ + $(LN_S) -f au_user.3 getauusernam_r.3 && \ + $(LN_S) -f au_user.3 au_user_mask.3 && \ + $(LN_S) -f au_user.3 getfauditflags.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/contrib/openbsm/libbsm/au_class.3 b/contrib/openbsm/libbsm/au_class.3 new file mode 100644 index 0000000..acdac62 --- /dev/null +++ b/contrib/openbsm/libbsm/au_class.3 @@ -0,0 +1,118 @@ +.\"- +.\" Copyright (c) 2005-2006 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_CLASS 3 +.Os +.Sh NAME +.Nm getauclassent , +.Nm getauclassent_r , +.Nm getauclassnam , +.Nm getauclassnam_r , +.Nm setauclass , +.Nm endauclass +.Nd "look up information from the audit_class database" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft "struct au_class_ent *" +.Fn getauclassent void +.Ft "struct au_class_ent *" +.Fn getauclassent_r "struct au_class_ent *e" +.Ft "struct au_class_ent *" +.Fn getauclassnam "const char *name" +.Ft "struct au_class_ent *" +.Fn getauclassnam_r "struct au_class_ent *e" "const char *name" +.Ft void +.Fn setauclass void +.Ft void +.Fn endauclass void +.Sh DESCRIPTION +These interfaces may be used to look up information from the +.Xr audit_class 5 +database, which describes audit event classes. +Audit event classes are described by +.Vt "struct au_class_ent" . +.Pp +The +.Fn getauclassent +function +will return the next class found in the +.Xr audit_class 5 +database, or the first if the function has not yet been called. +.Dv NULL +will be returned if no further records are available. +.Pp +The +.Fn getauclassnam +function +looks up a class by name. +.Dv NULL +will be returned if no matching class can be found. +.Pp +The +.Fn setauclass +function +resets the iterator through the +.Xr audit_class 5 +database, causing the next call to +.Fn getauclassent +to start again from the beginning of the file. +.Pp +The +.Fn endauclass +function +closes the +.Xr audit_class 5 +database, if open. +.Sh SEE ALSO +.Xr libbsm 3 , +.Xr audit_class 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +These routines cannot currently distinguish between an entry not being found +and an error accessing the database. +The implementation should be changed to return an error via +.Va errno +when +.Dv NULL +is returned. diff --git a/contrib/openbsm/libbsm/au_control.3 b/contrib/openbsm/libbsm/au_control.3 new file mode 100644 index 0000000..d4d4450 --- /dev/null +++ b/contrib/openbsm/libbsm/au_control.3 @@ -0,0 +1,258 @@ +.\"- +.\" Copyright (c) 2005-2006 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_CONTROL 3 +.Os +.Sh NAME +.Nm setac , +.Nm endac , +.Nm getacdir , +.Nm getacdist , +.Nm getacexpire , +.Nm getacfilesz , +.Nm getacflg , +.Nm getachost , +.Nm getacmin , +.Nm getacna , +.Nm getacpol , +.Nm au_poltostr , +.Nm au_strtopol +.Nd "look up information from the audit_control database" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft void +.Fn setac void +.Ft void +.Fn endac void +.Ft int +.Fn getacdir "char *name" "int len" +.Ft int +.Fn getacdist "void" +.Ft int +.Fn getacexpire "int *andflg" "time_t *age" "size_t *size" +.Ft int +.Fn getacfilesz "size_t *size_val" +.Ft int +.Fn getacflg "char *auditstr" "int len" +.Ft int +.Fn getachost "char *auditstr" "int len" +.Ft int +.Fn getacmin "int *min_val" +.Ft int +.Fn getacna "char *auditstr" "int len" +.Ft int +.Fn getacpol "char *auditstr" "size_t len" +.Ft ssize_t +.Fn au_poltostr "int policy" "size_t maxsize" "char *buf" +.Ft int +.Fn au_strtopol "const char *polstr" "int *policy" +.Sh DESCRIPTION +These interfaces may be used to look up information from the +.Xr audit_control 5 +database, which contains various audit-related administrative parameters. +.Pp +The +.Fn setac +function +resets the database iterator to the beginning of the database; see the +.Sx BUGS +section for more information. +.Pp +The +.Fn endac +function +closes the +.Xr audit_control 5 +database. +.Pp +The +.Fn getacdir +function +returns the name of the directory where log data is stored via the passed +character buffer +.Fa name +of length +.Fa len . +.Pp +The +.Fn getacdist +function returns a value that allows to decide if trail files distribution is +turned on or off. +.Pp +The +.Fn getacexpire +function +returns the audit trail file expiration parameters in the passed +.Vt int +buffer +.Fa andflg , +.Vt time_t +buffer +.Fa age +and +.Vt size_t +buffer +.Fa size . +If the parameter is not specified in the +.Xr audit_control 5 +file it is set to zero. +.Pp +The +.Fn getacfilesz +function +returns the audit trail rotation size in the passed +.Vt size_t +buffer +.Fa size_val . +.Pp +The +.Fn getacflg +function +returns the audit system flags via the the passed character buffer +.Fa auditstr +of length +.Fa len . +.Pp +The +.Fn getachost +function +returns the local systems's audit host information via the the passed character +buffer +.Fa auditstr +of length +.Fa len . +.Pp +The +.Fn getacmin +function +returns the minimum free disk space for the audit log target file system via +the passed +.Fa min_val +variable. +.Pp +The +.Fn getacna +function +returns the non-attributable flags via the passed character buffer +.Fa auditstr +of length +.Fa len . +.Pp +The +.Fn getacpol +function +returns the audit policy flags via the passed character buffer +.Fa auditstr +of length +.Fa len . +.Pp +The +.Fn au_poltostr +function +converts a numeric audit policy mask, +.Fa policy , +to a string in the passed character buffer +.Fa buf +of lenth +.Fa maxsize . +.Pp +The +.Fn au_strtopol +function +converts an audit policy flags string, +.Fa polstr , +to a numeric audit policy mask returned via +.Fa policy . +.Sh RETURN VALULES +The +.Fn getacfilesz , +.Fn getacdir , +.Fn getacexpire , +.Fn getacflg , +.Fn getachost , +.Fn getacmin , +.Fn getacna , +.Fn getacpol , +and +.Fn au_strtopol +functions +return 0 on success, or a negative value on failure, along with error +information in +.Va errno . +.Pp +The +.Fn au_poltostr +function +returns a string length of 0 or more on success, or a negative value on +if there is a failure. +.Pp +The +.Fn getacdist +function returns 1 if trail files distribution is turned on, 0 if it is turned +off or negative value on failure. +.Pp +Functions that return a string value will return a failure if there is +insufficient room in the passed character buffer for the full string. +.Sh SEE ALSO +.Xr libbsm 3 , +.Xr audit_control 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +These routines cannot currently distinguish between an entry not being found +and an error accessing the database. +The implementation should be changed to return an error via +.Va errno +when +.Dv NULL +is returned. +.Pp +There is no reason for the +.Fn setac +interface to be exposed as part of the public API, as it is called implicitly +by other access functions and iteration is not supported. +.Pp +These interfaces inconsistently return various negative values depending on +the failure mode, and do not always set +.Va errno +on failure. diff --git a/contrib/openbsm/libbsm/au_domain.3 b/contrib/openbsm/libbsm/au_domain.3 new file mode 100644 index 0000000..2f16b38 --- /dev/null +++ b/contrib/openbsm/libbsm/au_domain.3 @@ -0,0 +1,86 @@ +.\"- +.\" 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. +.\" +.Dd December 28, 2008 +.Dt AU_BSM_TO_DOMAIN 3 +.Os +.Sh NAME +.Nm au_bsm_to_domain , +.Nm au_domain_to_bsm +.Nd "convert between BSM and local protocol domains" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_bsm_to_domain "u_short bsm_domain" "int *local_domainp" +.Ft u_short +.Fn au_domain_to_bsm "int local_domain" +.Sh DESCRIPTION +These interfaces may be used to convert between the local and BSM protocol +domains. +The +.Fn au_bsm_to_domain +function accepts a BSM domain, +.Fa bsm_domain , +and converts it to a local domain, such as those passed to +.Xr socket 2 , +that will be stored in the integer pointed to by +.Fa local_domainp +if successful. +This call will fail if the BSM domain cannot be mapped into a local domain, +which may occur if the socket token was generated on another operating +system. +.Pp +The +.Fn au_domain_to_bsm +function accepts a local domain, and returns the BSM domain for it. +This call cannot fail, and instead returns a BSM domain indicating to a later +decoder that the domain could not be encoded. +.Sh RETURN VALULES +On success, +.Fn au_bsm_to_domain +returns 0 and a converted domain; on failure, it returns -1 but does not set +.Xr errno 2 . +.Sh SEE ALSO +.Xr au_bsm_to_socket_type 3 , +.Xr au_socket_type_to_bsm 3 , +.Xr au_to_socket_ex 3 , +.Xr libbsm 3 +.Sh HISTORY +.Fn au_bsm_to_domain +and +.Fn au_domain_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. diff --git a/contrib/openbsm/libbsm/au_errno.3 b/contrib/openbsm/libbsm/au_errno.3 new file mode 100644 index 0000000..93873ce --- /dev/null +++ b/contrib/openbsm/libbsm/au_errno.3 @@ -0,0 +1,110 @@ +.\"- +.\" 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. +.\" +.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 +The +.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 +function 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/contrib/openbsm/libbsm/au_event.3 b/contrib/openbsm/libbsm/au_event.3 new file mode 100644 index 0000000..781ba1b --- /dev/null +++ b/contrib/openbsm/libbsm/au_event.3 @@ -0,0 +1,169 @@ +.\"- +.\" Copyright (c) 2005-2006 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_EVENT 3 +.Os +.Sh NAME +.Nm free_au_event_ent , +.Nm setauevent , +.Nm endauevent , +.Nm getauevent , +.Nm getauevent_r , +.Nm getauevnam , +.Nm getauevnam_r , +.Nm getauevnum , +.Nm getauevnum_r , +.Nm getauevnonam , +.Nm getauevnonam_r +.Nd "look up information from the audit_event database" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft void +.Fn setauevent void +.Ft void +.Fn endauevent void +.Ft "struct au_event_ent *" +.Fn getauevent void +.Ft "struct au_event_ent *" +.Fn getauevent_r "struct au_event_ent *e" +.Ft "struct au_event_ent *" +.Fn getauevnam "const char *name" +.Ft "struct au_event_ent *" +.Fn getauevnam_r "struct au_event_ent *e" "const char *name" +.Ft "struct au_event_ent *" +.Fn getauevnum "au_event_t event_number" +.Ft "struct au_event_ent *" +.Fn getauevnum_r "struct au_event_ent *e" "au_event_t event_number" +.Ft "au_event_t *" +.Fn getauevnonam "const char *event_name" +.Ft "au_event_t *" +.Fn getauevnonam_r "au_event_t *ev" "const char *event_name" +.Sh DESCRIPTION +These interfaces may be used to look up information from the +.Xr audit_event 5 +database, which describes audit events. +Entries in the database are described by +.Vt "struct au_event_ent" +entries, which are returned by calls to +.Fn getauevent , +.Fn getauevnam , +or +.Fn getauevnum . +It is also possible to look up an event number via a call to +.Fn getauevnonam . +.Pp +The +.Fn setauevent +function +resets the database access session for +.Xr audit_event 5 , +so that the next call to +.Fn getauevent +will start with the first entry in the database. +.Pp +The +.Fn endauevent +function +closes the +.Xr audit_event 5 +database session. +.Pp +The +.Fn getauevent +function +returns a reference to the next entry in the +.Xr audit_event 5 +database. +.Pp +The +.Fn getauevnam +function +returns a reference to the entry in the +.Xr audit_event 5 +database with a name of +.Fa name . +.Pp +.Fn getauevnum +returns a reference to the entry in the +.Xr audit_event 5 +database with an event number of +.Fa event_number . +.Pp +The +.Fn getauevnonam +function +returns a reference to an audit event number using the +.Xr audit_event 5 +database. +.Sh RETURN VALUES +Functions +.Fn getauevent , +.Fn getauevent_r , +.Fn getauevnam , +.Fn getauevnam_r , +.Fn getauevnum , +.Fn getauevnum_r , +and +.Fn getauevnonam +will return a reference to a +.Vt "struct au_event_ent" +or +.Vt au_event_t +on success, or +.Dv NULL +on failure, with +.Va errno +set to provide further error information. +.Sh SEE ALSO +.Xr libbsm 3 , +.Xr audit_event 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +The +.Va errno +variable +is not always properly set following a failure. +.Pp +These routines are thread-safe, but not re-entrant, so simultaneous or +interleaved use of these functions will affect the iterator. diff --git a/contrib/openbsm/libbsm/au_fcntl_cmd.3 b/contrib/openbsm/libbsm/au_fcntl_cmd.3 new file mode 100644 index 0000000..a87c3ec --- /dev/null +++ b/contrib/openbsm/libbsm/au_fcntl_cmd.3 @@ -0,0 +1,95 @@ +.\"- +.\" Copyright (c) 2009 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. +.\" +.Dd March 5, 2009 +.Dt AU_BSM_TO_FCNTL_CMD 3 +.Os +.Sh NAME +.Nm au_bsm_to_fcntl_cmd , +.Nm au_fcntl_cmd_to_bsm +.Nd "convert between BSM and local fcntl(2) command values" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_bsm_to_fcntl_cmd "u_short bsm_fcntl_cmd" "int *local_fcntl_cmdp" +.Ft u_short +.Fn au_fcntl_cmd_to_bsm "int local_fcntl_cmd" +.Sh DESCRIPTION +These interfaces may be used to convert between the local and BSM +.Xr fcntl 2 +command values. +The +.Fn au_bsm_to_fcntl_cmd +function accepts a BSM command value, +.Fa bsm_fcntl_cmd , +and converts it to a local command value passed to +.Xr fcntl 2 , +that will be stored in the integer pointed to by +.Fa local_fcntl_cmdp +if successful. +This call will fail if the BSM command value cannot be mapped into a local +.Xr fcntl 2 +command value which may occur if the command token was generated on another +operating system. +.Pp +The +.Fn au_fcntl_cmd_to_bsm +function accepts a local +.Xr fcntl 2 +command value, and returns the BSM +.Xr fcntl 2 +command value for it. This call cannot fail, and instead returns a BSM +command value indicating to a later decoder that the command value could +not be encoded. +.Sh RETURN VALUES +On success, +.Fn au_bsm_to_fcntl_cmd +returns 0 and a converted command value; on failure, it returns -1 but does +not set +.Xr errno 2 . +.Sh SEE ALSO +.Xr fcntl 2 , +.Xr au_bsm_to_domain 3 , +.Xr au_bsm_to_socket_type 3 , +.Xr au_domain_to_bsm 3 , +.Xr au_socket_type_to_bsm 3 , +.Xr libbsm 3 +.Sh HISTORY +.Fn au_bsm_to_domain +and +.Fn au_domain_to_bsm +were introduced in OpenBSM 1.1. +.Sh AUTHORS +These functions were implemented by +.An Stacey Son +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. diff --git a/contrib/openbsm/libbsm/au_free_token.3 b/contrib/openbsm/libbsm/au_free_token.3 new file mode 100644 index 0000000..8820645 --- /dev/null +++ b/contrib/openbsm/libbsm/au_free_token.3 @@ -0,0 +1,95 @@ +.\"- +.\" Copyright (c) 2004 Apple Inc. +.\" Copyright (c) 2005 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 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, +.\" STRING 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. +.\" +.Dd April 19, 2005 +.Dt AU_FREE_TOKEN 3 +.Os +.Sh NAME +.Nm au_free_token +.Nd "deallocate a token_t created by any of the au_to_*() BSM API functions" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft void +.Fn au_free_token "token_t *tok" +.Sh DESCRIPTION +The BSM API generally manages deallocation of +.Vt token_t +objects. +However, if +.Xr au_write 3 +is passed a bad audit descriptor, the +.Vt "token_t *" +parameter will be left untouched. +In that case, the caller can deallocate the +.Vt token_t +using +.Fn au_free_token +if desired. +.Pp +The +.Fa tok +argument is a +.Vt "token_t *" +generated by one of the +.Fn au_to_* +BSM API calls. +For convenience, +.Fa tok +may be +.Dv NULL , +in which case +.Fn au_free_token +returns immediately. +.Sh IMPLEMENTATION NOTES +This is, in fact, what +.Xr audit_write 3 +does, in keeping with the existing memory management model of the BSM API. +.Sh SEE ALSO +.Xr au_write 3 , +.Xr audit_write 3 , +.Xr libbsm 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. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. diff --git a/contrib/openbsm/libbsm/au_io.3 b/contrib/openbsm/libbsm/au_io.3 new file mode 100644 index 0000000..bfea1a8 --- /dev/null +++ b/contrib/openbsm/libbsm/au_io.3 @@ -0,0 +1,173 @@ +.\"- +.\" Copyright (c) 2009 Apple, Inc. +.\" Copyright (c) 2005 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd August 4, 2009 +.Dt AU_IO 3 +.Os +.Sh NAME +.Nm au_fetch_tok , +.Nm au_print_tok , +.Nm au_print_flags_tok , +.Nm au_read_rec +.Nd "perform I/O involving an audit record" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_fetch_tok "tokenstr_t *tok" "u_char *buf" "int len" +.Ft void +.Fo au_print_tok +.Fa "FILE *outfp" "tokenstr_t *tok" "char *del" "char raw" "char sfrm" +.Fc +.Ft void +.Fo au_print_flags_tok +.Fa "FILE *outfp" "tokenstr_t *tok" "char *del" "int oflags" +.Fc +.Ft int +.Fn au_read_rec "FILE *fp" "u_char **buf" +.Sh DESCRIPTION +These interfaces support input and output (I/O) involving audit records, +internalizing an audit record from a byte stream, converting a token to +either a raw or default string, and reading a single record from a file. +.Pp +The +.Fn au_fetch_tok +function +reads a token from the passed buffer +.Fa buf +of length +.Fa len +bytes, and returns a pointer to the token via +.Fa tok . +.Pp +The +.Fn au_print_tok +function +prints a string form of the token +.Fa tok +to the file output stream +.Fa outfp , +either in default mode, or raw mode if +.Fa raw +is set non-zero. +The delimiter +.Fa del +is used when printing. +The +.Fn au_print_flags_tok +function is a replacement for +.Fn au_print_tok . +The +.Fa oflags +controls how the output should be formatted and is specified by +or'ing the following flags: +.Pp +.Bl -tag -width AU_OFLAG_NORESOLVE -compact -offset indent +.It Li AU_OFLAG_NONE +Use the default form. +.It Li AU_OFLAG_NORESOLVE +Leave user and group IDs in their numeric form. +.It Li AU_OFLAG_RAW +Use the raw, numeric form. +.It Li AU_OFLAG_SHORT +Use the short form. +.It Li AU_OFLAG_XML +Use the XML form. +.El +.Pp +The flags options AU_OFLAG_SHORT and AU_OFLAG_RAW are exclusive and +should not be used together. +.Pp +The +.Fn au_read_rec +function +reads an audit record from the file stream +.Fa fp , +and returns an allocated memory buffer containing the record via +.Fa *buf , +which must be freed by the caller using +.Xr free 3 . +.Pp +A typical use of these routines might open a file with +.Xr fopen 3 , +then read records from the file sequentially by calling +.Fn au_read_rec . +Each record would be broken down into components tokens through sequential +calls to +.Fn au_fetch_tok +on the buffer, and then invoking +.Fn au_print_flags_tok +to print each token to an output stream such as +.Dv stdout . +On completion of the processing of each record, a call to +.Xr free 3 +would be used to free the record buffer. +Finally, the source stream would be closed by a call to +.Xr fclose 3 . +.Sh RETURN VALUES +The +.Fn au_fetch_tok +and +.Fn au_read_rec +functions +return 0 on success, or \-1 on failure along with additional error information +returned via +.Va errno . +.Sh SEE ALSO +.Xr free 3 , +.Xr libbsm 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. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Pp +The +.Fn au_print_flags_tok +function was added by Stacey Son as a replacement for the +.Fn au_print_tok +so new output formatting flags can be easily added without changing the API. +The +.Fn au_print_tok +is obsolete but remains in the API to support legacy code. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +The +.Va errno +variable +may not always be properly set in the event of an error. diff --git a/contrib/openbsm/libbsm/au_mask.3 b/contrib/openbsm/libbsm/au_mask.3 new file mode 100644 index 0000000..c2099ea --- /dev/null +++ b/contrib/openbsm/libbsm/au_mask.3 @@ -0,0 +1,154 @@ +.\"- +.\" Copyright (c) 2005 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_MASK 3 +.Os +.Sh NAME +.Nm au_preselect , +.Nm getauditflagsbin , +.Nm getauditflagschar +.Nd "convert between string and numeric values of audit masks" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_preselect "au_event_t event" "au_mask_t *mask_p" "int sorf" "int flag" +.Ft int +.Fn getauditflagsbin "char *auditstr" "au_mask_t *masks" +.Ft int +.Fn getauditflagschar "char *auditstr" "au_mask_t *masks" "int verbose" +.Sh DESCRIPTION +These interfaces support processing of an audit mask represented by type +.Vt au_mask_t , +including conversion between numeric and text formats, and computing whether +or not an event is matched by a mask. +.Pp +The +.Fn au_preselect +function +calculates whether or not the audit event passed via +.Fa event +is matched by the audit mask passed via +.Fa mask_p . +The +.Fa sorf +argument indicates whether or not to consider the event as a success, +if the +.Dv AU_PRS_SUCCESS +flag is set, or failure, if the +.Dv AU_PRS_FAILURE +flag is set. +The +.Fa flag +argument accepts additional arguments influencing the behavior of +.Fn au_preselect , +including +.Dv AU_PRS_REREAD , +which causes the event to be re-looked up rather than read from the cache, +or +.Dv AU_PRS_USECACHE +which forces use of the cache. +.Pp +The +.Fn getauditflagsbin +function +converts a string representation of an audit mask passed via a character +string pointed to by +.Fa auditstr , +returning the resulting mask, if valid, via +.Fa *masks . +.Pp +The +.Fn getauditflagschar +function +converts the audit event mask passed via +.Fa *masks +and converts it to a character string in a buffer pointed to by +.Fa auditstr . +See the +.Sx BUGS +section for more information on how to provide a buffer of +sufficient size. +If the +.Fa verbose +flag is set, the class description string retrieved from +.Xr audit_class 5 +will be used; otherwise, the two-character class name. +.Sh IMPLEMENTATION NOTES +The +.Fn au_preselect +function +makes implicit use of various audit database routines, and may influence +the behavior of simultaneous or interleaved processing of those databases by +other code. +.Sh RETURN VALUES +The +.Fn au_preselect +function +returns 0 on success, or returns \-1 if there is a failure looking up the +event type or other database access, in which case +.Va errno +will be set to indicate the error. +It returns 1 if the event is matched; 0 if not. +.Pp +.Rv -std getauditflagsbin getauditflagschar +.Sh SEE ALSO +.Xr libbsm 3 , +.Xr audit_class 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +The +.Va errno +variable +may not always be properly set in the event of an error. +.Pp +The +.Fn getauditflagschar +function +does not provide a way to indicate how long the character buffer is, in order +to detect overflow. +As a result, the caller must always provide a buffer of sufficient length for +any possible mask, which may be calculated as three times the number of +non-zero bits in the mask argument in the event non-verbose class names are +used, and is not trivially predictable for verbose class names. +This API should be replaced with a more robust one. diff --git a/contrib/openbsm/libbsm/au_notify.3 b/contrib/openbsm/libbsm/au_notify.3 new file mode 100644 index 0000000..06e63bf --- /dev/null +++ b/contrib/openbsm/libbsm/au_notify.3 @@ -0,0 +1,118 @@ +.\"- +.\" Copyright (c) 2004-2009 Apple Inc. +.\" Copyright (c) 2015 Christian Brueffer +.\" 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 the author 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 THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd July 29, 2015 +.Dt AU_NOTIFY 3 +.Os +.Sh NAME +.Nm au_get_state , +.Nm au_notify_initialize , +.Nm au_notify_terminate +.Nd "audit event notification" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_get_state "void" +.Ft uint32_t +.Fn au_notify_initialize "void" +.Ft int +.Fn au_notify_terminate "void" +.Sh DESCRIPTION +The +.Nm au_notify +audit notification API tracks audit state in a form permitting efficient +update, avoiding frequent system calls to check the kernel audit state. +It is implemented only for Darwin/Mac OS X. +.Pp +The +.Fn au_get_state +function provides a lightweight way to check whether or not auditing is +enabled. +If a client wants to use this function to determine whether an entire +series of audit calls should be made -- as in the common case of a caller +building a set of tokens, then writing them -- it should cache the audit +status in a local variable. +This function always returns the current state of auditing. +If audit notification has not already been initialized by calling +.Fn au_notify_initialize +it will be automatically initialized on the first call of +this function. +.Pp +The +.Fn au_notify_initialize +function initializes audit notification. +.Pp +The +.Fn au_notify_terminate +function cancels audit notification and frees the resources associated with it. +Responsible code that no longer needs to use +.Fn au_get_state +should call this function. +.Sh RETURN VALUES +If no error occurred the +.Fn au_get_state +function returns +.Dv AUC_NOAUDIT +if auditing is disabled or suspended, and +.Dv AUC_AUDITING +if auditing is enabled and active. +Otherwise, the function can return any of the errno values defined for +.Xr setaudit 2 , +or +.Dv AU_UNIMPL +if audit does not appear to be supported by the system. +.Pp +The +.Fn au_notify_initialize +function returns 0 on success, +.Dv AU_UNIMPL +if audit does not appear to be supported by the system, +or one of the status codes defined in +.In notify.h +on Mac OS X to indicate the error. +.Pp +The +.Fn au_notify_terminate +function returns 0 on success, or \-1 on failure. +.Sh SEE ALSO +.Xr libbsm 3 , +.Xr notify 3 (Mac OS X) +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +This software was created by +.An Apple Computer, Inc . +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. diff --git a/contrib/openbsm/libbsm/au_open.3 b/contrib/openbsm/libbsm/au_open.3 new file mode 100644 index 0000000..522354f --- /dev/null +++ b/contrib/openbsm/libbsm/au_open.3 @@ -0,0 +1,156 @@ +.\"- +.\" Copyright (c) 2006 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd March 4, 2006 +.Dt AU_OPEN 3 +.Os +.Sh NAME +.Nm au_close , +.Nm au_close_buffer , +.Nm au_close_token , +.Nm au_open , +.Nm au_write +.Nd "create and commit audit records" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_open void +.Ft int +.Fn au_write "int d" "token_t *tok" +.Ft int +.Fn au_close "int d" "int keep" "short event" +.Ft int +.Fn au_close_buffer "int d" "short event" "u_char *buffer" "size_t *buflen" +.Ft int +.Fn au_close_token "token_t *tok" "u_char *buffer" "size_t *buflen" +.Sh DESCRIPTION +These interfaces allow applications to allocate audit records, construct a +record using a series of tokens, and commit the audit record to the system +event log. +An extension API is also provided to commit the record to an in-memory +buffer rather than the system audit log. +.Pp +The +.Fn au_open +interface allocates a new audit record descriptor. +.Pp +The +.Fn au_write +interface adds a token to an allocated audit descriptor. +When a token has been successfully added to a record, the caller no longer +owns the token memory, and does not need to free it directly via a call to +.Xr au_free_token 3 . +.Pp +The +.Fn au_close +function is used to commit an audit record to the system audit log, or +abandon the record. +In either cases, all resources associated with the record will be released. +The +.Fa keep +argument determines the behavior: a value of +.Dv AU_TO_WRITE +causes the record to be committed; a value of +.Dv AU_TO_NO_WRITE +causes it to be abandoned. +When the audit record is committed, a BSM header will be inserted before +tokens added to the record, using the event identifier passed via +.Fa event , +and a trailer added to the end. +Committing a record to the system audit log requires privilege. +.Pp +The +.Fn au_close_buffer +function writes the resulting record to an in-memory buffer of size +.Fa *buflen ; +it will write back the filled buffer length into the same variable. +The argument +.Fa event +is the event identifier to use in the record header. +.Pp +The +.Fn au_close_token +function generates the BSM stream output for a single token, +.Fa tok , +in the passed buffer +.Fa buffer . +The initial buffer size and resulting data size are passed via +.Fa *buflen . +The +.Fn au_close_token +function +will free the token before returning. +.Sh RETURN VALUES +The function +.Fn au_open +returns a non-negative audit record descriptor number on success, or a +negative value on failure, along with error information in +.Va errno . +.Pp +The functions +.Fn au_write , +.Fn au_close , +.Fn au_close_buffer , +and +.Fn au_close_token +return 0 on success, or a negative value on failure, along with error +information in +.Va errno . +.Sh SEE ALSO +.Xr audit_submit 3 , +.Xr libbsm 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. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +Currently, +.Fn au_open +does not reserve kernel resources necessary to commit the record to the +trail; on systems supporting +.Fn au_close , +the call will block until resources are available to commit the record. +However, this leads to the possibility of an action being permitted without +the record being guaranteed to go to disk. +Ideally, +.Fn au_open +would reserve resources necessary to commit any submitted record, releasing +them on +.Fn au_close . diff --git a/contrib/openbsm/libbsm/au_socket_type.3 b/contrib/openbsm/libbsm/au_socket_type.3 new file mode 100644 index 0000000..5668569 --- /dev/null +++ b/contrib/openbsm/libbsm/au_socket_type.3 @@ -0,0 +1,91 @@ +.\"- +.\" 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. +.\" +.Dd December 28, 2008 +.Dt AU_BSM_TO_SOCKET_TYPE 3 +.Os +.Sh NAME +.Nm au_bsm_to_socket_type , +.Nm au_socket_type_to_bsm +.Nd "convert between BSM and local socket types" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fn au_bsm_to_socket_type "u_short bsm_socket_type" "int *local_socket_typep" +.Ft u_short +.Fn au_socket_type_to_bsm "int local_socket_type" +.Sh DESCRIPTION +These interfaces may be used to convert between the local and BSM socket +types. +The +.Fn au_bsm_to_socket_type +function accepts a BSM socket type, +.Fa bsm_socket_type , +and converts it to a local socket type, such as those passed to +.Xr socket 2 , +that will be stored in the integer pointed to by +.Fa local_socket_typep +if successful. +This call will fail if the BSM socket type cannot be mapped into a local +socket type, which may occur if the socket token was generated on another +operating system. +.Pp +.Fn au_socket_type_to_bsm +function accepts a local socket type, and returns the BSM socket type for it. +This call cannot fail, and instead returns a BSM socket type indicating to a +later decoder that the socket type could not be encoded. +.Sh RETURN VALULES +On success, +.Fn au_bsm_to_socket_type +returns 0 and a converted socket type; 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_bsm_to_domain 3 , +.Xr au_domain_to_bsm 3 , +.Xr au_to_socket_ex 3 , +.Xr libbsm 3 +.Sh HISTORY +.Fn au_bsm_to_socket_type +and +.Fn au_socket_type_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. diff --git a/contrib/openbsm/libbsm/au_token.3 b/contrib/openbsm/libbsm/au_token.3 new file mode 100644 index 0000000..0459242 --- /dev/null +++ b/contrib/openbsm/libbsm/au_token.3 @@ -0,0 +1,252 @@ +.\"- +.\" Copyright (c) 2005-2007 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_TOKEN 3 +.Os +.Sh NAME +.Nm au_to_arg32 , +.Nm au_to_arg64 , +.Nm au_to_arg , +.Nm au_to_attr64 , +.Nm au_to_data , +.Nm au_to_exit , +.Nm au_to_groups , +.Nm au_to_newgroups , +.Nm au_to_in_addr , +.Nm au_to_in_addr_ex , +.Nm au_to_ip , +.Nm au_to_ipc , +.Nm au_to_ipc_perm , +.Nm au_to_iport , +.Nm au_to_opaque , +.Nm au_to_file , +.Nm au_to_text , +.Nm au_to_path , +.Nm au_to_process32 , +.Nm au_to_process64 , +.Nm au_to_process , +.Nm au_to_process32_ex , +.Nm au_to_process64_ex , +.Nm au_to_process_ex , +.Nm au_to_return32 , +.Nm au_to_return64 , +.Nm au_to_return , +.Nm au_to_seq , +.Nm au_to_sock_inet32 , +.Nm au_to_sock_inet128 , +.Nm au_to_sock_inet , +.Nm au_to_socket_ex , +.Nm au_to_subject32 , +.Nm au_to_subject64 , +.Nm au_to_subject , +.Nm au_to_subject32_ex , +.Nm au_to_subject64_ex , +.Nm au_to_subject_ex , +.Nm au_to_me , +.Nm au_to_exec_args , +.Nm au_to_exec_env , +.Nm au_to_header , +.Nm au_to_header32 , +.Nm au_to_header64 , +.Nm au_to_header_ex , +.Nm au_to_header32_ex , +.Nm au_to_trailer , +.Nm au_to_zonename +.Nd "routines for generating BSM audit tokens" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft "token_t *" +.Fn au_to_arg32 "char n" "const char *text" "u_int32_t v" +.Ft "token_t *" +.Fn au_to_arg64 "char n" "const char *text" "u_int64_t v" +.Ft "token_t *" +.Fn au_to_arg "char n" "const char *text" "u_int32_t v" +.Ft "token_t *" +.Fn au_to_attr32 "struct vattr *attr" +.Ft "token_t *" +.Fn au_to_attr64 "struct vattr *attr" +.Ft "token_t *" +.Fn au_to_attr "struct vattr *attr" +.Ft "token_t *" +.Fn au_to_data "char unit_print" "char unit_type" "char unit_count" "const char *p" +.Ft "token_t *" +.Fn au_to_exit "int retval" "int err" +.Ft "token_t *" +.Fn au_to_groups "int *groups" +.Ft "token_t *" +.Fn au_to_newgroups "u_int16_t n" "gid_t *groups" +.Ft "token_t *" +.Fn au_to_in_addr "struct in_addr *internet_addr" +.Ft "token_t *" +.Fn au_to_in_addr_ex "struct in6_addr *internet_addr" +.Ft "token_t *" +.Fn au_to_ip "struct ip *ip" +.Ft "token_t *" +.Fn au_to_ipc "char type" "int id" +.Ft "token_t *" +.Fn au_to_ipc_perm "struct ipc_perm *perm" +.Ft "token_t *" +.Fn au_to_iport "u_int16_t iport" +.Ft "token_t *" +.Fn au_to_opaque "const char *data" "u_int16_t bytes" +.Ft "token_t *" +.Fn au_to_file "const char *file" "struct timeval tm" +.Ft "token_t *" +.Fn au_to_text "const char *text" +.Ft "token_t *" +.Fn au_to_path "const char *text" +.Ft "token_t *" +.Fo au_to_process32 +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_process64 +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_process32_ex +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_addr_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_process64_ex +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_addr_t *tid" +.Fc +.Ft "token_t *" +.Fn au_to_return32 "char status" "u_int32_t ret" +.Ft "token_t *" +.Fn au_to_return64 "char status" "u_int64_t ret" +.Ft "token_t *" +.Fn au_to_return "char status" "u_int32_t ret" +.Ft "token_t *" +.Fn au_to_seq "long audit_count" +.Ft "token_t *" +.Fn au_to_sock_inet32 "struct sockaddr_in *so" +.Ft "token_t *" +.Fn au_to_sock_inet128 "struct sockaddr_in6 *so" +.Ft "token_t *" +.Fn au_to_sock_int "struct sockaddr_in *so" +.Ft "token_t *" +.Fn au_to_socket_ex "u_short so_domain" "u_short so_type" "struct sockaddr *sa_local" "struct sockaddr *sa_remote" +.Ft "token_t *" +.Fo au_to_subject32 +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_subject64 +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_subject +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_subject32_ex +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_addr_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_subject64_ex +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_addr_t *tid" +.Fc +.Ft "token_t *" +.Fo au_to_subject_ex +.Fa "au_id_t auid" "uid_t euid" "gid_t egid" "uid_t ruid" +.Fa "gid_t rgid" "pid_t pid" "au_asid_t sid" "au_tid_addr_t *tid" +.Fc +.Ft "token_t *" +.Fn au_to_me void +.Ft "token_t *" +.Fn au_to_exec_args "char **argv" +.Ft "token_t *" +.Fn au_to_exec_env "char **envp" +.Ft "token_t *" +.Fn au_to_header "int rec_size" "au_event_t e_type" "au_emod_t emod" +.Ft "token_t *" +.Fn au_to_header32 "int rec_size" "au_event_t e_type" "au_emod_t emod" +.Ft "token_t *" +.Fn au_to_header64 "int rec_size" "au_event_t e_type" "au_emod_t e_mod" +.Ft "token_t *" +.Fn au_to_header_ex "int rec_size" "au_event_t e_type" "au_emod_t e_mod" +.Ft "token_t *" +.Fn au_to_header32_ex "int rec_size" "au_event_t e_type" "au_emod_t e_mod" +.Ft "token_t *" +.Fn au_to_trailer "int rec_size" +.Ft "token_t *" +.Fn au_to_zonename "const char *zonename" +.Sh DESCRIPTION +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 +will be returned; the allocated +.Vt token_t +can be freed via a call to +.Xr au_free_token 3 . +On failure, +.Dv NULL +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 +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. diff --git a/contrib/openbsm/libbsm/au_user.3 b/contrib/openbsm/libbsm/au_user.3 new file mode 100644 index 0000000..d2a4fa1 --- /dev/null +++ b/contrib/openbsm/libbsm/au_user.3 @@ -0,0 +1,154 @@ +.\"- +.\" Copyright (c) 2005-2006 Robert N. M. Watson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd April 19, 2005 +.Dt AU_USER 3 +.Os +.Sh NAME +.Nm setauuser , +.Nm endauuser , +.Nm getauuserent , +.Nm getauuserent_r , +.Nm getauusernam , +.Nm getauusernam_r , +.Nm au_user_mask , +.Nm getfauditflags +.Nd "look up information from the audit_user database" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft void +.Fn setauuser void +.Ft void +.Fn endauuser void +.Ft "struct au_user_ent *" +.Fn getauuserent void +.Ft "struct au_user_ent *" +.Fn getauuserent_r "struct au_user_ent *u" +.Ft "struct au_user_ent *" +.Fn getauusernam "const char *name" +.Ft "struct au_user_ent *" +.Fn getauusernam_r "struct au_user_ent *u" "const char *name" +.Ft int +.Fn au_user_mask "char *username" "au_mask_t *mask_p" +.Ft int +.Fo getfauditflags +.Fa "au_mask_t *usremask" "au_mask_t *usrdmask" "au_mask_t *lastmask" +.Fc +.Sh DESCRIPTION +These interfaces may be used to look up information from the +.Xr audit_user 5 +database, which describes per-user audit configuration. +Audit user entries are described by a +.Vt au_user_ent , +which stores the user's name in +.Va au_name , +events to always audit in +.Va au_always , +and events never to audit +.Va au_never . +.Pp +The +.Fn getauuserent +function +returns the next user found in the +.Xr audit_user 5 +database, or the first if the function has not yet been called. +.Dv NULL +will be returned if no further records are available. +.Pp +The +.Fn getauusernam +function +looks up a user by name. +.Dv NULL +will be returned if no matching class can be found. +.Pp +The +.Fn setauuser +function +resets the iterator through the +.Xr audit_user 5 +database, causing the next call to +.Fn getauuserent +to start again from the beginning of the file. +.Pp +The +.Fn endauuser +function +closes the +.Xr audit_user 5 +database, if open. +.Pp +The +.Fn au_user_mask +function +calculates a new session audit mask to be returned via +.Fa mask_p +for the user identified by +.Fa username . +If the user audit configuration is not found, the default system audit +properties returned by +.Xr getacflg 3 +are used. +The resulting mask may be set via a call to +.Xr setaudit 2 +or related variants. +.Pp +The +.Fn getfauditflags +function generates a new process audit state by combining the audit masks +passed as parameters with the system audit masks. +.Sh SEE ALSO +.Xr setaudit 2 , +.Xr getacflg 3 , +.Xr libbsm 3 , +.Xr audit_user 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +These routines cannot currently distinguish between an entry not being found +and an error accessing the database. +The implementation should be changed to return an error via +.Va errno +when +.Dv NULL +is returned. diff --git a/contrib/openbsm/libbsm/audit_submit.3 b/contrib/openbsm/libbsm/audit_submit.3 new file mode 100644 index 0000000..c3be666 --- /dev/null +++ b/contrib/openbsm/libbsm/audit_submit.3 @@ -0,0 +1,151 @@ +.\" +.\" Copyright (c) 2006 Christian S.J. Peron +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY 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. +.\" +.Dd January 18, 2008 +.Dt AUDIT_SUBMIT 3 +.Os +.Sh NAME +.Nm audit_submit +.Nd "general purpose audit record submission" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Ft int +.Fo audit_submit +.Fa "short au_event" "au_id_t auid" "char status" +.Fa "int reterr" "const char * restrict format" ... +.Fc +.Sh DESCRIPTION +The +.Fn audit_submit +function provides a generic programming interface for audit record submission. +This audit record will contain a header, subject token, an optional text token, +return token, and a trailer. +The header will contain the event class specified by +.Fa au_event . +The subject token will be generated based on +.Fa auid . +The return token is dependent on the +.Fa status +and +.Fa reterr +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 +.Fa format +string that specifies how subsequent arguments (or arguments accessed via the +variable-length argument facilities of +.Xr stdarg 3 ) +are converted for output. +If +.Fa format +is +.Dv NULL , +then no text token is created in the audit record. +.Pp +It should be noted that +.Fn audit_submit +assumes that +.Xr setaudit 2 , +or +.Xr setaudit_addr 2 +has already been called. +As a direct result, the terminal ID for the +subject will be retrieved from the kernel via +.Xr getaudit 2 , +or +.Xr getaudit_addr 2 . +.Sh RETURN VALUES +If successful, +.Nm +will return zero. +Otherwise a -1 is returned and the global variable +.Va errno +is set to indicate the error. +.Sh EXAMPLES +.Bd -literal -offset indent +#include <bsm/audit.h> +#include <bsm/libbsm.h> +#include <bsm/audit_uevents.h> + +#include <stdio.h> +#include <stdarg.h> +#include <errno.h> + +void +audit_bad_su(char *from_login, char *to_login) +{ + struct auditinfo_addr aia; + struct auditinfo ai; + au_id_t aid; + int error; + + error = getaudit_addr(&aia, sizeof(aia)); + if (error < 0 && errno == ENOSYS) { + error = getaudit(&ai); + if (error < 0) + err(1, "getaudit"); + aid = ai.ai_auid; + } else if (error < 0) + err(1, "getaudit_addr"); + else + aid = aia.ai_auid; + error = audit_submit(AUE_su, aid, EPERM, 1, + "bad su from %s to %s", from_login, to_login); + if (error != 0) + err(1, "audit_submit"); +} +.Ed +.Pp +Will generate the following audit record: +.Bd -literal -offset indent +header,94,1,su(1),0,Mon Apr 17 23:23:59 2006, + 271 msec +subject,root,root,wheel,root,wheel,652,652,0,0.0.0.0 +text,bad su from from csjp to root +return,failure : Operation not permitted,1 +trailer,94 +.Ed +.Sh SEE ALSO +.Xr auditon 2 , +.Xr getaudit 2 , +.Xr libbsm 3 , +.Xr stdarg 3 +.Sh HISTORY +The +.Fn audit_submit +function first appeared in OpenBSM version 1.0. +OpenBSM 1.0 was introduced in +.Fx 7.0 . +.Sh AUTHORS +The +.Fn audit_submit +function was written by +.An Christian S.J. Peron Aq csjp@FreeBSD.org . diff --git a/contrib/openbsm/libbsm/bsm_audit.c b/contrib/openbsm/libbsm/bsm_audit.c new file mode 100644 index 0000000..f7a00c6 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_audit.c @@ -0,0 +1,449 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2005 SPARTA, Inc. + * All rights reserved. + * + * This code was developed in part by Robert N. M. Watson, Senior Principal + * Scientist, SPARTA, Inc. + * + * 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. + */ + +#include <sys/types.h> + +#include <config/config.h> +#ifdef HAVE_FULL_QUEUE_H +#include <sys/queue.h> +#else +#include <compat/queue.h> +#endif + +#include <bsm/audit_internal.h> +#include <bsm/libbsm.h> + +#include <netinet/in.h> + +#include <errno.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK +#include <pthread.h> +#endif +#include <stdlib.h> +#include <string.h> + +/* array of used descriptors */ +static au_record_t *open_desc_table[MAX_AUDIT_RECORDS]; + +/* The current number of active record descriptors */ +static int audit_rec_count = 0; + +/* + * Records that can be recycled are maintained in the list given below. The + * maximum number of elements that can be present in this list is bounded by + * MAX_AUDIT_RECORDS. Memory allocated for these records are never freed. + */ +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. + */ +void +au_free_token(token_t *tok) +{ + + if (tok != NULL) { + if (tok->t_data) + free(tok->t_data); + free(tok); + } +} + +/* + * This call reserves memory for the audit record. Memory must be guaranteed + * before any auditable event can be generated. The au_record_t structure + * maintains a reference to the memory allocated above and also the list of + * tokens associated with this record. Descriptors are recyled once the + * records are added to the audit trail following au_close(). + */ +int +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); + + /* + * Find an unused descriptor, remove it from the free list, mark as + * used. + */ + if (!LIST_EMPTY(&audit_free_q)) { + rec = LIST_FIRST(&audit_free_q); + rec->used = 1; + LIST_REMOVE(rec, au_rec_q); + } + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + + if (rec == NULL) { + /* + * Create a new au_record_t if no descriptors are available. + */ + rec = malloc (sizeof(au_record_t)); + if (rec == NULL) + return (-1); + + rec->data = malloc (MAX_AUDIT_RECORD_SIZE * sizeof(u_char)); + if (rec->data == NULL) { + free(rec); + errno = ENOMEM; + 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); + + /* XXX We need to increase size of MAX_AUDIT_RECORDS */ + errno = ENOMEM; + return (-1); + } + rec->desc = audit_rec_count; + open_desc_table[audit_rec_count] = rec; + audit_rec_count++; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + + } + + memset(rec->data, 0, MAX_AUDIT_RECORD_SIZE); + + TAILQ_INIT(&rec->token_q); + rec->len = 0; + rec->used = 1; + + return (rec->desc); +} + +/* + * Store the token with the record descriptor. + * + * Don't permit writing more to the buffer than would let the trailer be + * appended later. + */ +int +au_write(int d, token_t *tok) +{ + au_record_t *rec; + + if (tok == NULL) { + errno = EINVAL; + return (-1); /* Invalid Token */ + } + + /* Write the token to the record descriptor */ + rec = open_desc_table[d]; + if ((rec == NULL) || (rec->used == 0)) { + errno = EINVAL; + return (-1); /* Invalid descriptor */ + } + + if (rec->len + tok->len + AUDIT_TRAILER_SIZE > MAX_AUDIT_RECORD_SIZE) { + errno = ENOMEM; + return (-1); + } + + /* Add the token to the tail */ + /* + * XXX Not locking here -- we should not be writing to + * XXX the same descriptor from different threads + */ + TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens); + + rec->len += tok->len; /* grow record length by token size bytes */ + + /* Token should not be available after this call */ + tok = NULL; + return (0); /* Success */ +} + +/* + * Assemble an audit record out of its tokens, including allocating header and + * trailer tokens. Does not free the token chain, which must be done by the + * caller if desirable. + * + * XXX: Assumes there is sufficient space for the header and trailer. + */ +static int +au_assemble(au_record_t *rec, short event) +{ +#ifdef HAVE_AUDIT_SYSCALLS + struct in6_addr *aptr; + struct auditinfo_addr aia; + struct timeval tm; + size_t hdrsize; +#endif /* HAVE_AUDIT_SYSCALLS */ + token_t *header, *tok, *trailer; + size_t tot_rec_size; + u_char *dptr; + int error; + +#ifdef HAVE_AUDIT_SYSCALLS + /* + * Grab the size of the address family stored in the kernel's audit + * state. + */ + aia.ai_termid.at_type = AU_IPv4; + aia.ai_termid.at_addr[0] = INADDR_ANY; + if (audit_get_kaudit(&aia, sizeof(aia)) != 0) { + if (errno != ENOSYS && errno != EPERM) + return (-1); +#endif /* HAVE_AUDIT_SYSCALLS */ + tot_rec_size = rec->len + AUDIT_HEADER_SIZE + + AUDIT_TRAILER_SIZE; + header = au_to_header(tot_rec_size, event, 0); +#ifdef HAVE_AUDIT_SYSCALLS + } else { + if (gettimeofday(&tm, NULL) < 0) + return (-1); + switch (aia.ai_termid.at_type) { + case AU_IPv4: + hdrsize = (aia.ai_termid.at_addr[0] == INADDR_ANY) ? + AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&aia); + break; + case AU_IPv6: + aptr = (struct in6_addr *)&aia.ai_termid.at_addr[0]; + hdrsize = + (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; + /* + * A header size greater then AUDIT_HEADER_SIZE means + * that we are using an extended header. + */ + if (hdrsize > AUDIT_HEADER_SIZE) + header = au_to_header32_ex_tm(tot_rec_size, event, + 0, tm, &aia); + else + header = au_to_header(tot_rec_size, event, 0); + } +#endif /* HAVE_AUDIT_SYSCALLS */ + if (header == NULL) + return (-1); + + trailer = au_to_trailer(tot_rec_size); + if (trailer == NULL) { + error = errno; + au_free_token(header); + errno = error; + return (-1); + } + + TAILQ_INSERT_HEAD(&rec->token_q, header, tokens); + TAILQ_INSERT_TAIL(&rec->token_q, trailer, tokens); + + rec->len = tot_rec_size; + dptr = rec->data; + + TAILQ_FOREACH(tok, &rec->token_q, tokens) { + memcpy(dptr, tok->t_data, tok->len); + dptr += tok->len; + } + + return (0); +} + +/* + * Given a record that is no longer of interest, tear it down and convert to a + * free record. + */ +static void +au_teardown(au_record_t *rec) +{ + token_t *tok; + + /* Free the token list */ + while ((tok = TAILQ_FIRST(&rec->token_q)) != NULL) { + TAILQ_REMOVE(&rec->token_q, tok, tokens); + free(tok->t_data); + free(tok); + } + + 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 +/* + * Add the header token, identify any missing tokens. Write out the tokens to + * the record memory and finally, call audit. + */ +int +au_close(int d, int keep, short event) +{ + au_record_t *rec; + size_t tot_rec_size; + int retval = 0; + + rec = open_desc_table[d]; + if ((rec == NULL) || (rec->used == 0)) { + errno = EINVAL; + return (-1); /* Invalid descriptor */ + } + + if (keep == AU_TO_NO_WRITE) { + retval = 0; + goto cleanup; + } + + tot_rec_size = rec->len + MAX_AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE; + + if (tot_rec_size > MAX_AUDIT_RECORD_SIZE) { + /* + * XXXRW: Since au_write() is supposed to prevent this, spew + * an error here. + */ + fprintf(stderr, "au_close failed"); + errno = ENOMEM; + retval = -1; + goto cleanup; + } + + if (au_assemble(rec, event) < 0) { + /* + * XXXRW: This is also not supposed to happen, but might if we + * are unable to allocate header and trailer memory. + */ + retval = -1; + goto cleanup; + } + + /* Call the kernel interface to audit */ + retval = audit(rec->data, rec->len); + +cleanup: + /* CLEANUP */ + au_teardown(rec); + return (retval); +} +#endif /* HAVE_AUDIT_SYSCALLS */ + +/* + * au_close(), except onto an in-memory buffer. Buffer size as an argument, + * record size returned via same argument on success. + */ +int +au_close_buffer(int d, short event, u_char *buffer, size_t *buflen) +{ + size_t tot_rec_size; + au_record_t *rec; + int retval; + + rec = open_desc_table[d]; + if ((rec == NULL) || (rec->used == 0)) { + errno = EINVAL; + return (-1); + } + + retval = 0; + tot_rec_size = rec->len + MAX_AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE; + if ((tot_rec_size > MAX_AUDIT_RECORD_SIZE) || + (tot_rec_size > *buflen)) { + /* + * XXXRW: See au_close() comment. + */ + fprintf(stderr, "au_close_buffer failed %zd", tot_rec_size); + errno = ENOMEM; + retval = -1; + goto cleanup; + } + + if (au_assemble(rec, event) < 0) { + /* XXXRW: See au_close() comment. */ + retval = -1; + goto cleanup; + } + + memcpy(buffer, rec->data, rec->len); + *buflen = rec->len; + +cleanup: + au_teardown(rec); + return (retval); +} + +/* + * au_close_token() returns the byte format of a token_t. This won't + * generally be used by applications, but is quite useful for writing test + * tools. Will free the token on either success or failure. + */ +int +au_close_token(token_t *tok, u_char *buffer, size_t *buflen) +{ + + if (tok->len > *buflen) { + au_free_token(tok); + errno = ENOMEM; + return (EINVAL); + } + + memcpy(buffer, tok->t_data, tok->len); + *buflen = tok->len; + au_free_token(tok); + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_class.c b/contrib/openbsm/libbsm/bsm_class.c new file mode 100644 index 0000000..8ee193f --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_class.c @@ -0,0 +1,300 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <config/config.h> + +#include <bsm/libbsm.h> + +#include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK +#include <pthread.h> +#endif +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_STRLCPY +#include <compat/strlcpy.h> +#endif + +/* + * Parse the contents of the audit_class file to return struct au_class_ent + * entries. + */ +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 + * au_class_ent elements; store the result in c. + */ +static struct au_class_ent * +classfromstr(char *str, struct au_class_ent *c) +{ + char *classname, *classdesc, *classflag; + char *last; + + /* Each line contains flag:name:desc. */ + classflag = strtok_r(str, classdelim, &last); + classname = strtok_r(NULL, classdelim, &last); + classdesc = strtok_r(NULL, classdelim, &last); + + if ((classflag == NULL) || (classname == NULL) || (classdesc == NULL)) + return (NULL); + + /* + * Check for very large classnames. + */ + if (strlen(classname) >= AU_CLASS_NAME_MAX) + return (NULL); + strlcpy(c->ac_name, classname, AU_CLASS_NAME_MAX); + + /* + * Check for very large class description. + */ + if (strlen(classdesc) >= AU_CLASS_DESC_MAX) + return (NULL); + strlcpy(c->ac_desc, classdesc, AU_CLASS_DESC_MAX); + c->ac_class = strtoul(classflag, (char **) NULL, 0); + + return (c); +} + +/* + * Return the next au_class_ent structure from the file setauclass should be + * called before invoking this function for the first time. + * + * Must be called with mutex held. + */ +static struct au_class_ent * +getauclassent_r_locked(struct au_class_ent *c) +{ + char *tokptr, *nl; + + if ((fp == NULL) && ((fp = fopen(AUDIT_CLASS_FILE, "r")) == NULL)) + return (NULL); + + /* + * Read until next non-comment line is found, or EOF. + */ + while (1) { + if (fgets(linestr, AU_LINE_MAX, fp) == NULL) + return (NULL); + + /* Skip comments. */ + if (linestr[0] == '#') + continue; + + /* Remove trailing new line character. */ + if ((nl = strrchr(linestr, '\n')) != NULL) + *nl = '\0'; + + /* Parse tokptr to au_class_ent components. */ + tokptr = linestr; + if (classfromstr(tokptr, c) == NULL) + return (NULL); + break; + } + + return (c); +} + +struct au_class_ent * +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); +} + +struct au_class_ent * +getauclassent(void) +{ + static char class_ent_name[AU_CLASS_NAME_MAX]; + static char class_ent_desc[AU_CLASS_DESC_MAX]; + static struct au_class_ent c, *cp; + + bzero(&c, sizeof(c)); + bzero(class_ent_name, sizeof(class_ent_name)); + bzero(class_ent_desc, sizeof(class_ent_desc)); + 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); +} + +/* + * Rewind to the beginning of the enumeration. + * + * Must be called with mutex held. + */ +static void +setauclass_locked(void) +{ + + if (fp != NULL) + fseek(fp, 0, SEEK_SET); +} + +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 +} + +/* + * Return the next au_class_entry having the given class name. + */ +struct au_class_ent * +getauclassnam_r(struct au_class_ent *c, const char *name) +{ + struct au_class_ent *cp; + + 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); +} + +struct au_class_ent * +getauclassnam(const char *name) +{ + static char class_ent_name[AU_CLASS_NAME_MAX]; + static char class_ent_desc[AU_CLASS_DESC_MAX]; + static struct au_class_ent c; + + bzero(&c, sizeof(c)); + bzero(class_ent_name, sizeof(class_ent_name)); + bzero(class_ent_desc, sizeof(class_ent_desc)); + c.ac_name = class_ent_name; + c.ac_desc = class_ent_desc; + + return (getauclassnam_r(&c, name)); +} + + +/* + * Return the next au_class_entry having the given class number. + * + * OpenBSM extension. + */ +struct au_class_ent * +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); +} + +struct au_class_ent * +getauclassnum(au_class_t class_number) +{ + static char class_ent_name[AU_CLASS_NAME_MAX]; + static char class_ent_desc[AU_CLASS_DESC_MAX]; + static struct au_class_ent c; + + bzero(&c, sizeof(c)); + bzero(class_ent_name, sizeof(class_ent_name)); + bzero(class_ent_desc, sizeof(class_ent_desc)); + c.ac_name = class_ent_name; + c.ac_desc = class_ent_desc; + + return (getauclassnum_r(&c, class_number)); +} + +/* + * audit_class processing is complete; close any open files. + */ +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/contrib/openbsm/libbsm/bsm_control.c b/contrib/openbsm/libbsm/bsm_control.c new file mode 100644 index 0000000..94d9420 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_control.c @@ -0,0 +1,708 @@ +/*- + * Copyright (c) 2004, 2009 Apple Inc. + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <config/config.h> + +#include <bsm/libbsm.h> + +#include <ctype.h> +#include <errno.h> +#include <string.h> +#include <strings.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK +#include <pthread.h> +#endif +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_STRLCAT +#include <compat/strlcat.h> +#endif +#ifndef HAVE_STRLCPY +#include <compat/strlcpy.h> +#endif + +#include <sys/stat.h> + +/* + * Parse the contents of the audit_control file to return the audit control + * parameters. These static fields are protected by 'mutex'. + */ +static FILE *fp = NULL; +static char linestr[AU_LINE_MAX]; +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 + +/* + * Audit policy string token table for au_poltostr() and au_strtopol(). + */ +struct audit_polstr { + long ap_policy; + const char *ap_str; +}; + +static struct audit_polstr au_polstr[] = { + { AUDIT_CNT, "cnt" }, + { AUDIT_AHLT, "ahlt" }, + { AUDIT_ARGV, "argv" }, + { AUDIT_ARGE, "arge" }, + { AUDIT_SEQ, "seq" }, + { AUDIT_WINDATA, "windata" }, + { AUDIT_USER, "user" }, + { AUDIT_GROUP, "group" }, + { AUDIT_TRAIL, "trail" }, + { AUDIT_PATH, "path" }, + { AUDIT_SCNT, "scnt" }, + { AUDIT_PUBLIC, "public" }, + { AUDIT_ZONENAME, "zonename" }, + { AUDIT_PERZONE, "perzone" }, + { -1, NULL } +}; + +/* + * Returns the string value corresponding to the given label from the + * configuration file. + * + * Must be called with mutex held. + */ +static int +getstrfromtype_locked(const char *name, char **str) +{ + char *type, *nl; + char *tokptr; + char *last; + + *str = NULL; + + if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL)) + return (-1); /* Error */ + + while (1) { + if (fgets(linestr, AU_LINE_MAX, fp) == NULL) { + if (ferror(fp)) + return (-1); + return (0); /* EOF */ + } + + if (linestr[0] == '#') + continue; + + /* Remove trailing new line character and white space. */ + nl = strchr(linestr, '\0') - 1; + while (nl >= linestr && ('\n' == *nl || ' ' == *nl || + '\t' == *nl)) { + *nl = '\0'; + nl--; + } + + tokptr = linestr; + if ((type = strtok_r(tokptr, delim, &last)) != NULL) { + if (strcmp(name, type) == 0) { + /* Found matching name. */ + *str = strtok_r(NULL, delim, &last); + if (*str == NULL) { + errno = EINVAL; + return (-1); /* Parse error in file */ + } + return (0); /* Success */ + } + } + } +} + +/* + * Convert a given time value with a multiplier (seconds, hours, days, years) to + * seconds. Return 0 on success. + */ +static int +au_timetosec(time_t *seconds, u_long value, char mult) +{ + if (NULL == seconds) + return (-1); + + switch(mult) { + case 's': + /* seconds */ + *seconds = (time_t)value; + break; + + case 'h': + /* hours */ + *seconds = (time_t)value * 60 * 60; + break; + + case 'd': + /* days */ + *seconds = (time_t)value * 60 * 60 * 24; + break; + + case 'y': + /* years. Add a day for each 4th (leap) year. */ + *seconds = (time_t)value * 60 * 60 * 24 * 364 + + ((time_t)value / 4) * 60 * 60 * 24; + break; + + default: + return (-1); + } + return (0); +} + +/* + * Convert a given disk space value with a multiplier (bytes, kilobytes, + * megabytes, gigabytes) to bytes. Return 0 on success. + */ +static int +au_spacetobytes(size_t *bytes, u_long value, char mult) +{ + if (NULL == bytes) + return (-1); + + switch(mult) { + case 'B': + case ' ': + /* Bytes */ + *bytes = (size_t)value; + break; + + case 'K': + /* Kilobytes */ + *bytes = (size_t)value * 1024; + break; + + case 'M': + /* Megabytes */ + *bytes = (size_t)value * 1024 * 1024; + break; + + case 'G': + /* Gigabytes */ + *bytes = (size_t)value * 1024 * 1024 * 1024; + break; + + default: + return (-1); + } + return (0); +} + +/* + * Convert a policy to a string. Return -1 on failure, or >= 0 representing + * the actual size of the string placed in the buffer (excluding terminating + * nul). + */ +ssize_t +au_poltostr(int policy, size_t maxsize, char *buf) +{ + int first = 1; + int i = 0; + + if (maxsize < 1) + return (-1); + buf[0] = '\0'; + + do { + if (policy & au_polstr[i].ap_policy) { + if (!first && strlcat(buf, ",", maxsize) >= maxsize) + return (-1); + if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= + maxsize) + return (-1); + first = 0; + } + } while (NULL != au_polstr[++i].ap_str); + + return (strlen(buf)); +} + +/* + * Convert a string to a policy. Return -1 on failure (with errno EINVAL, + * ENOMEM) or 0 on success. + */ +int +au_strtopol(const char *polstr, int *policy) +{ + char *bufp, *string; + char *buffer; + int i, matched; + + *policy = 0; + buffer = strdup(polstr); + if (buffer == NULL) + return (-1); + + bufp = buffer; + while ((string = strsep(&bufp, ",")) != NULL) { + matched = i = 0; + + do { + if (strcmp(string, au_polstr[i].ap_str) == 0) { + *policy |= au_polstr[i].ap_policy; + matched = 1; + break; + } + } while (NULL != au_polstr[++i].ap_str); + + if (!matched) { + free(buffer); + errno = EINVAL; + return (-1); + } + } + free(buffer); + return (0); +} + +/* + * Rewind the file pointer to beginning. + */ +static void +setac_locked(void) +{ + static time_t lastctime = 0; + struct stat sbuf; + + ptrmoved = 1; + if (fp != NULL) { + /* + * Check to see if the file on disk has changed. If so, + * force a re-read of the file by closing it. + */ + if (fstat(fileno(fp), &sbuf) < 0) + goto closefp; + if (lastctime != sbuf.st_ctime) { + lastctime = sbuf.st_ctime; +closefp: + fclose(fp); + fp = NULL; + return; + } + + fseek(fp, 0, SEEK_SET); + } +} + +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 +} + +/* + * Close the audit_control file. + */ +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 +} + +/* + * Return audit directory information from the audit control file. + */ +int +getacdir(char *name, int len) +{ + char *dir; + int ret = 0; + + /* + * 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) + fseek(fp, 0, SEEK_SET); + 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); +} + +/* + * Return 1 if dist value is set to 'yes' or 'on'. + * Return 0 if dist value is set to something else. + * Return negative value on error. + */ +int +getacdist(void) +{ + char *str; + int ret; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_lock(&mutex); +#endif + setac_locked(); + if (getstrfromtype_locked(DIST_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 (0); + } + if (strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) + ret = 1; + else + ret = 0; +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (ret); +} + +/* + * Return the minimum free diskspace value from the audit control file. + */ +int +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); +} + +/* + * Return the desired trail rotation size from the audit control file. + */ +int +getacfilesz(size_t *filesz_val) +{ + char *str; + size_t val; + char mult; + int nparsed; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_lock(&mutex); +#endif + setac_locked(); + if (getstrfromtype_locked(FILESZ_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 + errno = EINVAL; + return (-1); + } + + /* Trim off any leading white space. */ + while (*str == ' ' || *str == '\t') + str++; + + nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult); + + switch (nparsed) { + case 1: + /* If no multiplier then assume 'B' (bytes). */ + mult = 'B'; + /* fall through */ + case 2: + if (au_spacetobytes(filesz_val, val, mult) == 0) + break; + /* fall through */ + default: + errno = EINVAL; +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + + /* + * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 + * indicates no rotation size. + */ + if (*filesz_val < 0 || (*filesz_val > 0 && + *filesz_val < MIN_AUDIT_FILE_SIZE)) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + filesz_val = 0L; + errno = EINVAL; + return (-1); + } +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (0); +} + +static int +getaccommon(const char *name, char *auditstr, int len) +{ + char *str; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_lock(&mutex); +#endif + setac_locked(); + if (getstrfromtype_locked(name, &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); +} + +/* + * Return the system audit value from the audit contol file. + */ +int +getacflg(char *auditstr, int len) +{ + + return (getaccommon(FLAGS_CONTROL_ENTRY, auditstr, len)); +} + +/* + * Return the non attributable flags from the audit contol file. + */ +int +getacna(char *auditstr, int len) +{ + + return (getaccommon(NA_CONTROL_ENTRY, auditstr, len)); +} + +/* + * Return the policy field from the audit control file. + */ +int +getacpol(char *auditstr, size_t len) +{ + + return (getaccommon(POLICY_CONTROL_ENTRY, auditstr, len)); +} + +int +getachost(char *auditstr, size_t len) +{ + + return (getaccommon(HOST_CONTROL_ENTRY, auditstr, len)); +} + +/* + * Set expiration conditions. + */ +static int +setexpirecond(time_t *age, size_t *size, u_long value, char mult) +{ + + if (isupper(mult) || ' ' == mult) + return (au_spacetobytes(size, value, mult)); + else + return (au_timetosec(age, value, mult)); +} + +/* + * Return the expire-after field from the audit control file. + */ +int +getacexpire(int *andflg, time_t *age, size_t *size) +{ + char *str; + int nparsed; + u_long val1, val2; + char mult1, mult2; + char andor[AU_LINE_MAX]; + + *age = 0L; + *size = 0LL; + *andflg = 0; + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_lock(&mutex); +#endif + setac_locked(); + if (getstrfromtype_locked(EXPIRE_AFTER_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); + } + + /* First, trim off any leading white space. */ + while (*str == ' ' || *str == '\t') + str++; + + nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, + andor, &val2, &mult2); + + switch (nparsed) { + case 1: + /* If no multiplier then assume 'B' (Bytes). */ + mult1 = 'B'; + /* fall through */ + case 2: + /* One expiration condition. */ + if (setexpirecond(age, size, val1, mult1) != 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + break; + + case 5: + /* Two expiration conditions. */ + if (setexpirecond(age, size, val1, mult1) != 0 || + setexpirecond(age, size, val2, mult2) != 0) { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + if (strcasestr(andor, "and") != NULL) + *andflg = 1; + else if (strcasestr(andor, "or") != NULL) + *andflg = 0; + else { +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + break; + + default: +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (-1); + } + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_domain.c b/contrib/openbsm/libbsm/bsm_domain.c new file mode 100644 index 0000000..f6aeef6 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_domain.c @@ -0,0 +1,490 @@ +/*- + * 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. + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <config/config.h> + +#include <bsm/audit_domain.h> +#include <bsm/libbsm.h> + +struct bsm_domain { + u_short bd_bsm_domain; + int bd_local_domain; +}; + +#define PF_NO_LOCAL_MAPPING -600 + +static const struct bsm_domain bsm_domains[] = { + { BSM_PF_UNSPEC, PF_UNSPEC }, + { BSM_PF_LOCAL, PF_LOCAL }, + { BSM_PF_INET, PF_INET }, + { BSM_PF_IMPLINK, +#ifdef PF_IMPLINK + PF_IMPLINK +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_PUP, +#ifdef PF_PUP + PF_PUP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_CHAOS, +#ifdef PF_CHAOS + PF_CHAOS +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NS, +#ifdef PF_NS + PF_NS +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NBS, +#ifdef PF_NBS + PF_NBS +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ECMA, +#ifdef PF_ECMA + PF_ECMA +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_DATAKIT, +#ifdef PF_DATAKIT + PF_DATAKIT +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_CCITT, +#ifdef PF_CCITT + PF_CCITT +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_SNA, PF_SNA }, + { BSM_PF_DECnet, PF_DECnet }, + { BSM_PF_DLI, +#ifdef PF_DLI + PF_DLI +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_LAT, +#ifdef PF_LAT + PF_LAT +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_HYLINK, +#ifdef PF_HYLINK + PF_HYLINK +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_APPLETALK, PF_APPLETALK }, + { BSM_PF_NIT, +#ifdef PF_NIT + PF_NIT +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_802, +#ifdef PF_802 + PF_802 +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_OSI, +#ifdef PF_OSI + PF_OSI +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_X25, +#ifdef PF_X25 + PF_X25 +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_OSINET, +#ifdef PF_OSINET + PF_OSINET +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_GOSIP, +#ifdef PF_GOSIP + PF_GOSIP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_IPX, PF_IPX }, + { BSM_PF_ROUTE, PF_ROUTE }, + { BSM_PF_LINK, +#ifdef PF_LINK + PF_LINK +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_INET6, PF_INET6 }, + { BSM_PF_KEY, PF_KEY }, + { BSM_PF_NCA, +#ifdef PF_NCA + PF_NCA +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_POLICY, +#ifdef PF_POLICY + PF_POLICY +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_INET_OFFLOAD, +#ifdef PF_INET_OFFLOAD + PF_INET_OFFLOAD +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NETBIOS, +#ifdef PF_NETBIOS + PF_NETBIOS +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ISO, +#ifdef PF_ISO + PF_ISO +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_XTP, +#ifdef PF_XTP + PF_XTP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_COIP, +#ifdef PF_COIP + PF_COIP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_CNT, +#ifdef PF_CNT + PF_CNT +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_RTIP, +#ifdef PF_RTIP + PF_RTIP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_SIP, +#ifdef PF_SIP + PF_SIP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_PIP, +#ifdef PF_PIP + PF_PIP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ISDN, +#ifdef PF_ISDN + PF_ISDN +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_E164, +#ifdef PF_E164 + PF_E164 +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NATM, +#ifdef PF_NATM + PF_NATM +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ATM, +#ifdef PF_ATM + PF_ATM +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NETGRAPH, +#ifdef PF_NETGRAPH + PF_NETGRAPH +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_SLOW, +#ifdef PF_SLOW + PF_SLOW +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_SCLUSTER, +#ifdef PF_SCLUSTER + PF_SCLUSTER +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ARP, +#ifdef PF_ARP + PF_ARP +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_BLUETOOTH, +#ifdef PF_BLUETOOTH + PF_BLUETOOTH +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_AX25, +#ifdef PF_AX25 + PF_AX25 +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ROSE, +#ifdef PF_ROSE + PF_ROSE +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_NETBEUI, +#ifdef PF_NETBEUI + PF_NETBEUI +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_SECURITY, +#ifdef PF_SECURITY + PF_SECURITY +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_PACKET, +#ifdef PF_PACKET + PF_PACKET +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ASH, +#ifdef PF_ASH + PF_ASH +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ECONET, +#ifdef PF_ECONET + PF_ECONET +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_ATMSVC, +#ifdef PF_ATMSVC + PF_ATMSVC +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_IRDA, +#ifdef PF_IRDA + PF_IRDA +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_PPPOX, +#ifdef PF_PPPOX + PF_PPPOX +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_WANPIPE, +#ifdef PF_WANPIPE + PF_WANPIPE +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_LLC, +#ifdef PF_LLC + PF_LLC +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_CAN, +#ifdef PF_CAN + PF_CAN +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_TIPC, +#ifdef PF_TIPC + PF_TIPC +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_IUCV, +#ifdef PF_IUCV + PF_IUCV +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_RXRPC, +#ifdef PF_RXRPC + PF_RXRPC +#else + PF_NO_LOCAL_MAPPING +#endif + }, + { BSM_PF_PHONET, +#ifdef PF_PHONET + PF_PHONET +#else + PF_NO_LOCAL_MAPPING +#endif + }, +}; +static const int bsm_domains_count = sizeof(bsm_domains) / + sizeof(bsm_domains[0]); + +static const struct bsm_domain * +bsm_lookup_local_domain(int local_domain) +{ + int i; + + for (i = 0; i < bsm_domains_count; i++) { + if (bsm_domains[i].bd_local_domain == local_domain) + return (&bsm_domains[i]); + } + return (NULL); +} + +u_short +au_domain_to_bsm(int local_domain) +{ + const struct bsm_domain *bstp; + + bstp = bsm_lookup_local_domain(local_domain); + if (bstp == NULL) + return (BSM_PF_UNKNOWN); + return (bstp->bd_bsm_domain); +} + +static const struct bsm_domain * +bsm_lookup_bsm_domain(u_short bsm_domain) +{ + int i; + + for (i = 0; i < bsm_domains_count; i++) { + if (bsm_domains[i].bd_bsm_domain == bsm_domain) + return (&bsm_domains[i]); + } + return (NULL); +} + +int +au_bsm_to_domain(u_short bsm_domain, int *local_domainp) +{ + const struct bsm_domain *bstp; + + bstp = bsm_lookup_bsm_domain(bsm_domain); + if (bstp == NULL || bstp->bd_local_domain) + return (-1); + *local_domainp = bstp->bd_local_domain; + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_errno.c b/contrib/openbsm/libbsm/bsm_errno.c new file mode 100644 index 0000000..b4b22f3 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_errno.c @@ -0,0 +1,771 @@ +/*- + * 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. + */ + +#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. + * + * Don't include string definitions when this code is compiled into a kernel. + */ +struct bsm_errno { + int be_bsm_errno; + int be_local_errno; +#if !defined(KERNEL) && !defined(_KERNEL) + const char *be_strerror; +#endif +}; + +#define ERRNO_NO_LOCAL_MAPPING -600 + +#if !defined(KERNEL) && !defined(_KERNEL) +#define ES(x) x +#else +#define ES(x) +#endif + +/* + * 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_errno bsm_errnos[] = { + { BSM_ERRNO_ESUCCESS, 0, ES("Success") }, + { BSM_ERRNO_EPERM, EPERM, ES("Operation not permitted") }, + { BSM_ERRNO_ENOENT, ENOENT, ES("No such file or directory") }, + { BSM_ERRNO_ESRCH, ESRCH, ES("No such process") }, + { BSM_ERRNO_EINTR, EINTR, ES("Interrupted system call") }, + { BSM_ERRNO_EIO, EIO, ES("Input/output error") }, + { BSM_ERRNO_ENXIO, ENXIO, ES("Device not configured") }, + { BSM_ERRNO_E2BIG, E2BIG, ES("Argument list too long") }, + { BSM_ERRNO_ENOEXEC, ENOEXEC, ES("Exec format error") }, + { BSM_ERRNO_EBADF, EBADF, ES("Bad file descriptor") }, + { BSM_ERRNO_ECHILD, ECHILD, ES("No child processes") }, + { BSM_ERRNO_EAGAIN, EAGAIN, ES("Resource temporarily unavailable") }, + { BSM_ERRNO_ENOMEM, ENOMEM, ES("Cannot allocate memory") }, + { BSM_ERRNO_EACCES, EACCES, ES("Permission denied") }, + { BSM_ERRNO_EFAULT, EFAULT, ES("Bad address") }, + { BSM_ERRNO_ENOTBLK, ENOTBLK, ES("Block device required") }, + { BSM_ERRNO_EBUSY, EBUSY, ES("Device busy") }, + { BSM_ERRNO_EEXIST, EEXIST, ES("File exists") }, + { BSM_ERRNO_EXDEV, EXDEV, ES("Cross-device link") }, + { BSM_ERRNO_ENODEV, ENODEV, ES("Operation not supported by device") }, + { BSM_ERRNO_ENOTDIR, ENOTDIR, ES("Not a directory") }, + { BSM_ERRNO_EISDIR, EISDIR, ES("Is a directory") }, + { BSM_ERRNO_EINVAL, EINVAL, ES("Invalid argument") }, + { BSM_ERRNO_ENFILE, ENFILE, ES("Too many open files in system") }, + { BSM_ERRNO_EMFILE, EMFILE, ES("Too many open files") }, + { BSM_ERRNO_ENOTTY, ENOTTY, ES("Inappropriate ioctl for device") }, + { BSM_ERRNO_ETXTBSY, ETXTBSY, ES("Text file busy") }, + { BSM_ERRNO_EFBIG, EFBIG, ES("File too large") }, + { BSM_ERRNO_ENOSPC, ENOSPC, ES("No space left on device") }, + { BSM_ERRNO_ESPIPE, ESPIPE, ES("Illegal seek") }, + { BSM_ERRNO_EROFS, EROFS, ES("Read-only file system") }, + { BSM_ERRNO_EMLINK, EMLINK, ES("Too many links") }, + { BSM_ERRNO_EPIPE, EPIPE, ES("Broken pipe") }, + { BSM_ERRNO_EDOM, EDOM, ES("Numerical argument out of domain") }, + { BSM_ERRNO_ERANGE, ERANGE, ES("Result too large") }, + { BSM_ERRNO_ENOMSG, ENOMSG, ES("No message of desired type") }, + { BSM_ERRNO_EIDRM, EIDRM, ES("Identifier removed") }, + { BSM_ERRNO_ECHRNG, +#ifdef ECHRNG + ECHRNG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Channel number out of range") }, + { BSM_ERRNO_EL2NSYNC, +#ifdef EL2NSYNC + EL2NSYNC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Level 2 not synchronized") }, + { BSM_ERRNO_EL3HLT, +#ifdef EL3HLT + EL3HLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Level 3 halted") }, + { BSM_ERRNO_EL3RST, +#ifdef EL3RST + EL3RST, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Level 3 reset") }, + { BSM_ERRNO_ELNRNG, +#ifdef ELNRNG + ELNRNG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Link number out of range") }, + { BSM_ERRNO_EUNATCH, +#ifdef EUNATCH + EUNATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Protocol driver not attached") }, + { BSM_ERRNO_ENOCSI, +#ifdef ENOCSI + ENOCSI, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("No CSI structure available") }, + { BSM_ERRNO_EL2HLT, +#ifdef EL2HLT + EL2HLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Level 2 halted") }, + { BSM_ERRNO_EDEADLK, EDEADLK, ES("Resource deadlock avoided") }, + { BSM_ERRNO_ENOLCK, ENOLCK, ES("No locks available") }, + { BSM_ERRNO_ECANCELED, ECANCELED, ES("Operation canceled") }, + { BSM_ERRNO_ENOTSUP, ENOTSUP, ES("Operation not supported") }, + { BSM_ERRNO_EDQUOT, EDQUOT, ES("Disc quota exceeded") }, + { BSM_ERRNO_EBADE, +#ifdef EBADE + EBADE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Invalid exchange") }, + { BSM_ERRNO_EBADR, +#ifdef EBADR + EBADR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Invalid request descriptor") }, + { BSM_ERRNO_EXFULL, +#ifdef EXFULL + EXFULL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Exchange full") }, + { BSM_ERRNO_ENOANO, +#ifdef ENOANO + ENOANO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("No anode") }, + { BSM_ERRNO_EBADRQC, +#ifdef EBADRQC + EBADRQC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Invalid request descriptor") }, + { BSM_ERRNO_EBADSLT, +#ifdef EBADSLT + EBADSLT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Invalid slot") }, + { BSM_ERRNO_EDEADLOCK, +#ifdef EDEADLOCK + EDEADLOCK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Resource deadlock avoided") }, + { BSM_ERRNO_EBFONT, +#ifdef EBFONT + EBFONT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Bad font file format") }, + { BSM_ERRNO_EOWNERDEAD, +#ifdef EOWNERDEAD + EOWNERDEAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Process died with the lock") }, + { BSM_ERRNO_ENOTRECOVERABLE, +#ifdef ENOTRECOVERABLE + ENOTRECOVERABLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Lock is not recoverable") }, + { BSM_ERRNO_ENOSTR, +#ifdef ENOSTR + ENOSTR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Device not a stream") }, + { BSM_ERRNO_ENONET, +#ifdef ENONET + ENONET, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Machine is not on the network") }, + { BSM_ERRNO_ENOPKG, +#ifdef ENOPKG + ENOPKG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Package not installed") }, + { BSM_ERRNO_EREMOTE, EREMOTE, + ES("Too many levels of remote in path") }, + { BSM_ERRNO_ENOLINK, +#ifdef ENOLINK + ENOLINK, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Link has been severed") }, + { BSM_ERRNO_EADV, +#ifdef EADV + EADV, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Advertise error") }, + { BSM_ERRNO_ESRMNT, +#ifdef ESRMNT + ESRMNT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("srmount error") }, + { BSM_ERRNO_ECOMM, +#ifdef ECOMM + ECOMM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Communication error on send") }, + { BSM_ERRNO_EPROTO, +#ifdef EPROTO + EPROTO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Protocol error") }, + { BSM_ERRNO_ELOCKUNMAPPED, +#ifdef ELOCKUNMAPPED + ELOCKUNMAPPED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Locked lock was unmapped") }, + { BSM_ERRNO_ENOTACTIVE, +#ifdef ENOTACTIVE + ENOTACTIVE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Facility is not active") }, + { BSM_ERRNO_EMULTIHOP, +#ifdef EMULTIHOP + EMULTIHOP, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Multihop attempted") }, + { BSM_ERRNO_EBADMSG, +#ifdef EBADMSG + EBADMSG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Bad message") }, + { BSM_ERRNO_ENAMETOOLONG, ENAMETOOLONG, ES("File name too long") }, + { BSM_ERRNO_EOVERFLOW, EOVERFLOW, + ES("Value too large to be stored in data type") }, + { BSM_ERRNO_ENOTUNIQ, +#ifdef ENOTUNIQ + ENOTUNIQ, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Given log name not unique") }, + { BSM_ERRNO_EBADFD, +#ifdef EBADFD + EBADFD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Given f.d. invalid for this operation") }, + { BSM_ERRNO_EREMCHG, +#ifdef EREMCHG + EREMCHG, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Remote address changed") }, + { BSM_ERRNO_ELIBACC, +#ifdef ELIBACC + ELIBACC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Can't access a needed shared lib") }, + { BSM_ERRNO_ELIBBAD, +#ifdef ELIBBAD + ELIBBAD, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Accessing a corrupted shared lib") }, + { BSM_ERRNO_ELIBSCN, +#ifdef ELIBSCN + ELIBSCN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES(".lib section in a.out corrupted") }, + { BSM_ERRNO_ELIBMAX, +#ifdef ELIBMAX + ELIBMAX, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Attempting to link in too many libs") }, + { BSM_ERRNO_ELIBEXEC, +#ifdef ELIBEXEC + ELIBEXEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Attempting to exec a shared library") }, + { BSM_ERRNO_EILSEQ, EILSEQ, ES("Illegal byte sequence") }, + { BSM_ERRNO_ENOSYS, ENOSYS, ES("Function not implemented") }, + { BSM_ERRNO_ELOOP, ELOOP, ES("Too many levels of symbolic links") }, + { BSM_ERRNO_ERESTART, +#ifdef ERESTART + ERESTART, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Restart syscall") }, + { BSM_ERRNO_ESTRPIPE, +#ifdef ESTRPIPE + ESTRPIPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("If pipe/FIFO, don't sleep in stream head") }, + { BSM_ERRNO_ENOTEMPTY, ENOTEMPTY, ES("Directory not empty") }, + { BSM_ERRNO_EUSERS, EUSERS, ES("Too many users") }, + { BSM_ERRNO_ENOTSOCK, ENOTSOCK, + ES("Socket operation on non-socket") }, + { BSM_ERRNO_EDESTADDRREQ, EDESTADDRREQ, + ES("Destination address required") }, + { BSM_ERRNO_EMSGSIZE, EMSGSIZE, ES("Message too long") }, + { BSM_ERRNO_EPROTOTYPE, EPROTOTYPE, + ES("Protocol wrong type for socket") }, + { BSM_ERRNO_ENOPROTOOPT, ENOPROTOOPT, ES("Protocol not available") }, + { BSM_ERRNO_EPROTONOSUPPORT, EPROTONOSUPPORT, + ES("Protocol not supported") }, + { BSM_ERRNO_ESOCKTNOSUPPORT, ESOCKTNOSUPPORT, + ES("Socket type not supported") }, + { BSM_ERRNO_EOPNOTSUPP, EOPNOTSUPP, ES("Operation not supported") }, + { BSM_ERRNO_EPFNOSUPPORT, EPFNOSUPPORT, + ES("Protocol family not supported") }, + { BSM_ERRNO_EAFNOSUPPORT, EAFNOSUPPORT, + ES("Address family not supported by protocol family") }, + { BSM_ERRNO_EADDRINUSE, EADDRINUSE, ES("Address already in use") }, + { BSM_ERRNO_EADDRNOTAVAIL, EADDRNOTAVAIL, + ES("Can't assign requested address") }, + { BSM_ERRNO_ENETDOWN, ENETDOWN, ES("Network is down") }, + { BSM_ERRNO_ENETRESET, ENETRESET, + ES("Network dropped connection on reset") }, + { BSM_ERRNO_ECONNABORTED, ECONNABORTED, + ES("Software caused connection abort") }, + { BSM_ERRNO_ECONNRESET, ECONNRESET, ES("Connection reset by peer") }, + { BSM_ERRNO_ENOBUFS, ENOBUFS, ES("No buffer space available") }, + { BSM_ERRNO_EISCONN, EISCONN, ES("Socket is already connected") }, + { BSM_ERRNO_ENOTCONN, ENOTCONN, ES("Socket is not connected") }, + { BSM_ERRNO_ESHUTDOWN, ESHUTDOWN, + ES("Can't send after socket shutdown") }, + { BSM_ERRNO_ETOOMANYREFS, ETOOMANYREFS, + ES("Too many references: can't splice") }, + { BSM_ERRNO_ETIMEDOUT, ETIMEDOUT, ES("Operation timed out") }, + { BSM_ERRNO_ECONNREFUSED, ECONNREFUSED, ES("Connection refused") }, + { BSM_ERRNO_EHOSTDOWN, EHOSTDOWN, ES("Host is down") }, + { BSM_ERRNO_EHOSTUNREACH, EHOSTUNREACH, ES("No route to host") }, + { BSM_ERRNO_EALREADY, EALREADY, ES("Operation already in progress") }, + { BSM_ERRNO_EINPROGRESS, EINPROGRESS, + ES("Operation now in progress") }, + { BSM_ERRNO_ESTALE, ESTALE, ES("Stale NFS file handle") }, + { BSM_ERRNO_EPROCLIM, +#ifdef EPROCLIM + EPROCLIM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Too many processes") }, + { BSM_ERRNO_EBADRPC, +#ifdef EBADRPC + EBADRPC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("RPC struct is bad") }, + { BSM_ERRNO_ERPCMISMATCH, +#ifdef ERPCMISMATCH + ERPCMISMATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("RPC version wrong") }, + { BSM_ERRNO_EPROGUNAVAIL, +#ifdef EPROGUNAVAIL + EPROGUNAVAIL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("RPC prog. not avail") }, + { BSM_ERRNO_EPROGMISMATCH, +#ifdef EPROGMISMATCH + EPROGMISMATCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("RPC version wrong") }, + { BSM_ERRNO_EPROCUNAVAIL, +#ifdef EPROCUNAVAIL + EPROCUNAVAIL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Bad procedure for program") }, + { BSM_ERRNO_EFTYPE, +#ifdef EFTYPE + EFTYPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Inappropriate file type or format") }, + { BSM_ERRNO_EAUTH, +#ifdef EAUTH + EAUTH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Authenticateion error") }, + { BSM_ERRNO_ENEEDAUTH, +#ifdef ENEEDAUTH + ENEEDAUTH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Need authenticator") }, + { BSM_ERRNO_ENOATTR, +#ifdef ENOATTR + ENOATTR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Attribute not found") }, + { BSM_ERRNO_EDOOFUS, +#ifdef EDOOFUS + EDOOFUS, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Programming error") }, + { BSM_ERRNO_EJUSTRETURN, +#ifdef EJUSTRETURN + EJUSTRETURN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Just return") }, + { BSM_ERRNO_ENOIOCTL, +#ifdef ENOIOCTL + ENOIOCTL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("ioctl not handled by this layer") }, + { BSM_ERRNO_EDIRIOCTL, +#ifdef EDIRIOCTL + EDIRIOCTL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("do direct ioctl in GEOM") }, + { BSM_ERRNO_EPWROFF, +#ifdef EPWROFF + EPWROFF, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Device power is off") }, + { BSM_ERRNO_EDEVERR, +#ifdef EDEVERR + EDEVERR, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Device error") }, + { BSM_ERRNO_EBADEXEC, +#ifdef EBADEXEC + EBADEXEC, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Bad executable") }, + { BSM_ERRNO_EBADARCH, +#ifdef EBADARCH + EBADARCH, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Bad CPU type in executable") }, + { BSM_ERRNO_ESHLIBVERS, +#ifdef ESHLIBVERS + ESHLIBVERS, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Shared library version mismatch") }, + { BSM_ERRNO_EBADMACHO, +#ifdef EBADMACHO + EBADMACHO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Malformed Macho file") }, + { BSM_ERRNO_EPOLICY, +#ifdef EPOLICY + EPOLICY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Operation failed by policy") }, + { BSM_ERRNO_EDOTDOT, +#ifdef EDOTDOT + EDOTDOT, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("RFS specific error") }, + { BSM_ERRNO_EUCLEAN, +#ifdef EUCLEAN + EUCLEAN, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Structure needs cleaning") }, + { BSM_ERRNO_ENOTNAM, +#ifdef ENOTNAM + ENOTNAM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Not a XENIX named type file") }, + { BSM_ERRNO_ENAVAIL, +#ifdef ENAVAIL + ENAVAIL, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("No XENIX semaphores available") }, + { BSM_ERRNO_EISNAM, +#ifdef EISNAM + EISNAM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Is a named type file") }, + { BSM_ERRNO_EREMOTEIO, +#ifdef EREMOTEIO + EREMOTEIO, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Remote I/O error") }, + { BSM_ERRNO_ENOMEDIUM, +#ifdef ENOMEDIUM + ENOMEDIUM, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("No medium found") }, + { BSM_ERRNO_EMEDIUMTYPE, +#ifdef EMEDIUMTYPE + EMEDIUMTYPE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Wrong medium type") }, + { BSM_ERRNO_ENOKEY, +#ifdef ENOKEY + ENOKEY, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Required key not available") }, + { BSM_ERRNO_EKEYEXPIRED, +#ifdef EKEYEXPIRED + EKEYEXPIRED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Key has expired") }, + { BSM_ERRNO_EKEYREVOKED, +#ifdef EKEYREVOKED + EKEYREVOKED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Key has been revoked") }, + { BSM_ERRNO_EKEYREJECTED, +#ifdef EKEYREJECTED + EKEYREJECTED, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Key was rejected by service") }, + { BSM_ERRNO_ENOTCAPABLE, +#ifdef ENOTCAPABLE + ENOTCAPABLE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Capabilities insufficient") }, + { BSM_ERRNO_ECAPMODE, +#ifdef ECAPMODE + ECAPMODE, +#else + ERRNO_NO_LOCAL_MAPPING, +#endif + ES("Not permitted in capability mode") }, +}; +static const int bsm_errnos_count = sizeof(bsm_errnos) / sizeof(bsm_errnos[0]); + +static const struct bsm_errno * +bsm_lookup_errno_local(int local_errno) +{ + int i; + + for (i = 0; i < bsm_errnos_count; i++) { + if (bsm_errnos[i].be_local_errno == local_errno) + return (&bsm_errnos[i]); + } + return (NULL); +} + +/* + * Conversion to the BSM errno space isn't allowed to fail; we simply map to + * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it. + */ +u_char +au_errno_to_bsm(int local_errno) +{ + const struct bsm_errno *bsme; + + bsme = bsm_lookup_errno_local(local_errno); + if (bsme == NULL) + return (BSM_ERRNO_UNKNOWN); + return (bsme->be_bsm_errno); +} + +static const struct bsm_errno * +bsm_lookup_errno_bsm(u_char bsm_errno) +{ + int i; + + for (i = 0; i < bsm_errnos_count; i++) { + if (bsm_errnos[i].be_bsm_errno == bsm_errno) + return (&bsm_errnos[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. + */ +int +au_bsm_to_errno(u_char bsm_errno, int *errorp) +{ + const struct bsm_errno *bsme; + + bsme = bsm_lookup_errno_bsm(bsm_errno); + if (bsme == NULL || bsme->be_local_errno == ERRNO_NO_LOCAL_MAPPING) + return (-1); + *errorp = bsme->be_local_errno; + return (0); +} + +#if !defined(KERNEL) && !defined(_KERNEL) +const char * +au_strerror(u_char bsm_errno) +{ + const struct bsm_errno *bsme; + + bsme = bsm_lookup_errno_bsm(bsm_errno); + if (bsme == NULL) + return ("Unrecognized BSM error"); + if (bsme->be_local_errno != ERRNO_NO_LOCAL_MAPPING) + return (strerror(bsme->be_local_errno)); + return (bsme->be_strerror); +} +#endif diff --git a/contrib/openbsm/libbsm/bsm_event.c b/contrib/openbsm/libbsm/bsm_event.c new file mode 100644 index 0000000..5499083 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_event.c @@ -0,0 +1,361 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <config/config.h> + +#include <bsm/libbsm.h> + +#include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK +#include <pthread.h> +#endif +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_STRLCPY +#include <compat/strlcpy.h> +#endif + + +/* + * Parse the contents of the audit_event file to return + * au_event_ent entries + */ +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. + */ +static struct au_event_ent * +eventfromstr(char *str, struct au_event_ent *e) +{ + char *evno, *evname, *evdesc, *evclass; + struct au_mask evmask; + char *last; + + evno = strtok_r(str, eventdelim, &last); + evname = strtok_r(NULL, eventdelim, &last); + evdesc = strtok_r(NULL, eventdelim, &last); + evclass = strtok_r(NULL, eventdelim, &last); + + if ((evno == NULL) || (evname == NULL)) + return (NULL); + + if (strlen(evname) >= AU_EVENT_NAME_MAX) + return (NULL); + + strlcpy(e->ae_name, evname, AU_EVENT_NAME_MAX); + if (evdesc != NULL) { + if (strlen(evdesc) >= AU_EVENT_DESC_MAX) + return (NULL); + strlcpy(e->ae_desc, evdesc, AU_EVENT_DESC_MAX); + } else + strlcpy(e->ae_desc, "", AU_EVENT_DESC_MAX); + + e->ae_number = atoi(evno); + + /* + * Find out the mask that corresponds to the given list of classes. + */ + if (evclass != NULL) { + if (getauditflagsbin(evclass, &evmask) != 0) + e->ae_class = 0; + else + e->ae_class = evmask.am_success; + } else + e->ae_class = 0; + + return (e); +} + +/* + * Rewind the audit_event file. + */ +static void +setauevent_locked(void) +{ + + if (fp != NULL) + fseek(fp, 0, SEEK_SET); +} + +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 +} + +/* + * Close the open file pointers. + */ +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 +} + +/* + * Enumerate the au_event_ent entries. + */ +static struct au_event_ent * +getauevent_r_locked(struct au_event_ent *e) +{ + char *nl; + + if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) + return (NULL); + + while (1) { + if (fgets(linestr, AU_LINE_MAX, fp) == NULL) + return (NULL); + + /* Remove new lines. */ + if ((nl = strrchr(linestr, '\n')) != NULL) + *nl = '\0'; + + /* Skip comments. */ + if (linestr[0] == '#') + continue; + + /* Get the next event structure. */ + if (eventfromstr(linestr, e) == NULL) + return (NULL); + break; + } + + return (e); +} + +struct au_event_ent * +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); +} + +struct au_event_ent * +getauevent(void) +{ + static char event_ent_name[AU_EVENT_NAME_MAX]; + static char event_ent_desc[AU_EVENT_DESC_MAX]; + static struct au_event_ent e; + + bzero(&e, sizeof(e)); + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + return (getauevent_r(&e)); +} + +/* + * Search for an audit event structure having the given event name. + * + * XXXRW: Why accept NULL name? + */ +static struct au_event_ent * +getauevnam_r_locked(struct au_event_ent *e, const char *name) +{ + char *nl; + + if (name == NULL) + return (NULL); + + /* Rewind to beginning of the file. */ + setauevent_locked(); + + if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) + return (NULL); + + while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { + /* Remove new lines. */ + if ((nl = strrchr(linestr, '\n')) != NULL) + *nl = '\0'; + + if (eventfromstr(linestr, e) != NULL) { + if (strcmp(name, e->ae_name) == 0) + return (e); + } + } + + return (NULL); +} + +struct au_event_ent * +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); +} + +struct au_event_ent * +getauevnam(const char *name) +{ + static char event_ent_name[AU_EVENT_NAME_MAX]; + static char event_ent_desc[AU_EVENT_DESC_MAX]; + static struct au_event_ent e; + + bzero(&e, sizeof(e)); + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + return (getauevnam_r(&e, name)); +} + +/* + * Search for an audit event structure having the given event number. + */ +static struct au_event_ent * +getauevnum_r_locked(struct au_event_ent *e, au_event_t event_number) +{ + char *nl; + + /* Rewind to beginning of the file. */ + setauevent_locked(); + + if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) + return (NULL); + + while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { + /* Remove new lines. */ + if ((nl = strrchr(linestr, '\n')) != NULL) + *nl = '\0'; + + if (eventfromstr(linestr, e) != NULL) { + if (event_number == e->ae_number) + return (e); + } + } + + return (NULL); +} + +struct au_event_ent * +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); +} + +struct au_event_ent * +getauevnum(au_event_t event_number) +{ + static char event_ent_name[AU_EVENT_NAME_MAX]; + static char event_ent_desc[AU_EVENT_DESC_MAX]; + static struct au_event_ent e; + + bzero(&e, sizeof(e)); + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + return (getauevnum_r(&e, event_number)); +} + +/* + * Search for an audit_event entry with a given event_name and returns the + * corresponding event number. + */ +au_event_t * +getauevnonam_r(au_event_t *ev, const char *event_name) +{ + static char event_ent_name[AU_EVENT_NAME_MAX]; + static char event_ent_desc[AU_EVENT_DESC_MAX]; + static struct au_event_ent e, *ep; + + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + bzero(&e, sizeof(e)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + + ep = getauevnam_r(&e, event_name); + if (ep == NULL) + return (NULL); + + *ev = e.ae_number; + return (ev); +} + +au_event_t * +getauevnonam(const char *event_name) +{ + static au_event_t event; + + return (getauevnonam_r(&event, event_name)); +} diff --git a/contrib/openbsm/libbsm/bsm_fcntl.c b/contrib/openbsm/libbsm/bsm_fcntl.c new file mode 100644 index 0000000..45ae5da --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_fcntl.c @@ -0,0 +1,287 @@ +/*- + * Copyright (c) 2008-2009 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. + */ + +#include <sys/param.h> +#include <sys/fcntl.h> + +#include <config/config.h> + +#include <bsm/audit_fcntl.h> +#include <bsm/libbsm.h> + +struct bsm_fcntl_cmd { + u_short bfc_bsm_fcntl_cmd; + int bfc_local_fcntl_cmd; +}; +typedef struct bsm_fcntl_cmd bsm_fcntl_cmd_t; + +static const bsm_fcntl_cmd_t bsm_fcntl_cmdtab[] = { + { BSM_F_DUPFD, F_DUPFD }, + { BSM_F_GETFD, F_GETFD }, + { BSM_F_SETFD, F_SETFD }, + { BSM_F_GETFL, F_GETFL }, + { BSM_F_SETFL, F_SETFL }, +#ifdef F_O_GETLK + { BSM_F_O_GETLK, F_O_GETLK }, +#endif + { BSM_F_SETLK, F_SETLK }, + { BSM_F_SETLKW, F_SETLK }, +#ifdef F_CHFL + { BSM_F_CHKFL, F_CHKFL }, +#endif +#ifdef F_DUP2FD + { BSM_F_DUP2FD, F_DUP2FD }, +#endif +#ifdef F_ALLOCSP + { BSM_F_ALLOCSP, F_ALLOCSP }, +#endif +#ifdef F_FREESP + { BSM_F_FREESP, F_FREESP }, +#endif +#ifdef F_ISSTREAM + { BSM_F_ISSTREAM, F_ISSTREAM}, +#endif + { BSM_F_GETLK, F_GETLK }, +#ifdef F_PRIV + { BSM_F_PRIV, F_PRIV }, +#endif +#ifdef F_NPRIV + { BSM_F_NPRIV, F_NPRIV }, +#endif +#ifdef F_QUOTACTL + { BSM_F_QUOTACTL, F_QUOTACTL }, +#endif +#ifdef F_BLOCKS + { BSM_F_BLOCKS, F_BLOCKS }, +#endif +#ifdef F_BLKSIZE + { BSM_F_BLKSIZE, F_BLKSIZE }, +#endif + { BSM_F_GETOWN, F_GETOWN }, + { BSM_F_SETOWN, F_SETOWN }, +#ifdef F_REVOKE + { BSM_F_REVOKE, F_REVOKE }, +#endif +#ifdef F_HASREMOTEBLOCKS + { BSM_F_HASREMOTEBLOCKS, + F_HASREMOTEBLOCKS }, +#endif +#ifdef F_FREESP + { BSM_F_FREESP, F_FREESP }, +#endif +#ifdef F_ALLOCSP + { BSM_F_ALLOCSP, F_ALLOCSP }, +#endif +#ifdef F_FREESP64 + { BSM_F_FREESP64, F_FREESP64 }, +#endif +#ifdef F_ALLOCSP64 + { BSM_F_ALLOCSP64, F_ALLOCSP64 }, +#endif +#ifdef F_GETLK64 + { BSM_F_GETLK64, F_GETLK64 }, +#endif +#ifdef F_SETLK64 + { BSM_F_SETLK64, F_SETLK64 }, +#endif +#ifdef F_SETLKW64 + { BSM_F_SETLKW64, F_SETLKW64 }, +#endif +#ifdef F_SHARE + { BSM_F_SHARE, F_SHARE }, +#endif +#ifdef F_UNSHARE + { BSM_F_UNSHARE, F_UNSHARE }, +#endif +#ifdef F_SETLK_NBMAND + { BSM_F_SETLK_NBMAND, F_SETLK_NBMAND }, +#endif +#ifdef F_SHARE_NBMAND + { BSM_F_SHARE_NBMAND, F_SHARE_NBMAND }, +#endif +#ifdef F_SETLK64_NBMAND + { BSM_F_SETLK64_NBMAND, F_SETLK64_NBMAND }, +#endif +#ifdef F_GETXFL + { BSM_F_GETXFL, F_GETXFL }, +#endif +#ifdef F_BADFD + { BSM_F_BADFD, F_BADFD }, +#endif +#ifdef F_OGETLK + { BSM_F_OGETLK, F_OGETLK }, +#endif +#ifdef F_OSETLK + { BSM_F_OSETLK, F_OSETLK }, +#endif +#ifdef F_OSETLKW + { BSM_F_OSETLKW, F_OSETLKW }, +#endif +#ifdef F_SETLK_REMOTE + { BSM_F_SETLK_REMOTE, F_SETLK_REMOTE }, +#endif + +#ifdef F_SETSIG + { BSM_F_SETSIG, F_SETSIG }, +#endif +#ifdef F_GETSIG + { BSM_F_GETSIG, F_GETSIG }, +#endif + +#ifdef F_CHKCLEAN + { BSM_F_CHKCLEAN, F_CHKCLEAN }, +#endif +#ifdef F_PREALLOCATE + { BSM_F_PREALLOCATE, F_PREALLOCATE }, +#endif +#ifdef F_SETSIZE + { BSM_F_SETSIZE, F_SETSIZE }, +#endif +#ifdef F_RDADVISE + { BSM_F_RDADVISE, F_RDADVISE }, +#endif +#ifdef F_RDAHEAD + { BSM_F_RDAHEAD, F_RDAHEAD }, +#endif +#ifdef F_READBOOTSTRAP + { BSM_F_READBOOTSTRAP, F_READBOOTSTRAP }, +#endif +#ifdef F_WRITEBOOTSTRAP + { BSM_F_WRITEBOOTSTRAP, F_WRITEBOOTSTRAP }, +#endif +#ifdef F_NOCACHE + { BSM_F_NOCACHE, F_NOCACHE }, +#endif +#ifdef F_LOG2PHYS + { BSM_F_LOG2PHYS, F_LOG2PHYS }, +#endif +#ifdef F_GETPATH + { BSM_F_GETPATH, F_GETPATH }, +#endif +#ifdef F_FULLFSYNC + { BSM_F_FULLFSYNC, F_FULLFSYNC }, +#endif +#ifdef F_PATHPKG_CHECK + { BSM_F_PATHPKG_CHECK, F_PATHPKG_CHECK }, +#endif +#ifdef F_FREEZE_FS + { BSM_F_FREEZE_FS, F_FREEZE_FS }, +#endif +#ifdef F_THAW_FS + { BSM_F_THAW_FS, F_THAW_FS }, +#endif +#ifdef F_GLOBAL_NOCACHE + { BSM_F_GLOBAL_NOCACHE, F_GLOBAL_NOCACHE }, +#endif +#ifdef F_OPENFROM + { BSM_F_OPENFROM, F_OPENFROM }, +#endif +#ifdef F_UNLINKFROM + { BSM_F_UNLINKFROM, F_UNLINKFROM }, +#endif +#ifdef F_CHECK_OPENEVT + { BSM_F_CHECK_OPENEVT, F_CHECK_OPENEVT }, +#endif +#ifdef F_ADDSIGS + { BSM_F_ADDSIGS, F_ADDSIGS }, +#endif +#ifdef F_MARKDEPENDENCY + { BSM_F_MARKDEPENDENCY, F_MARKDEPENDENCY }, +#endif + +#ifdef FCNTL_FS_SPECIFIC_BASE + { BSM_F_FS_SPECIFIC_0, FCNTL_FS_SPECIFIC_BASE}, + { BSM_F_FS_SPECIFIC_1, FCNTL_FS_SPECIFIC_BASE + 1}, + { BSM_F_FS_SPECIFIC_2, FCNTL_FS_SPECIFIC_BASE + 2}, + { BSM_F_FS_SPECIFIC_3, FCNTL_FS_SPECIFIC_BASE + 3}, + { BSM_F_FS_SPECIFIC_4, FCNTL_FS_SPECIFIC_BASE + 4}, + { BSM_F_FS_SPECIFIC_5, FCNTL_FS_SPECIFIC_BASE + 5}, + { BSM_F_FS_SPECIFIC_6, FCNTL_FS_SPECIFIC_BASE + 6}, + { BSM_F_FS_SPECIFIC_7, FCNTL_FS_SPECIFIC_BASE + 7}, + { BSM_F_FS_SPECIFIC_8, FCNTL_FS_SPECIFIC_BASE + 8}, + { BSM_F_FS_SPECIFIC_9, FCNTL_FS_SPECIFIC_BASE + 9}, + { BSM_F_FS_SPECIFIC_10, FCNTL_FS_SPECIFIC_BASE + 10}, + { BSM_F_FS_SPECIFIC_11, FCNTL_FS_SPECIFIC_BASE + 11}, + { BSM_F_FS_SPECIFIC_12, FCNTL_FS_SPECIFIC_BASE + 12}, + { BSM_F_FS_SPECIFIC_13, FCNTL_FS_SPECIFIC_BASE + 13}, + { BSM_F_FS_SPECIFIC_14, FCNTL_FS_SPECIFIC_BASE + 14}, + { BSM_F_FS_SPECIFIC_15, FCNTL_FS_SPECIFIC_BASE + 15}, +#endif /* FCNTL_FS_SPECIFIC_BASE */ +}; +static const int bsm_fcntl_cmd_count = sizeof(bsm_fcntl_cmdtab) / + sizeof(bsm_fcntl_cmdtab[0]); + +static const bsm_fcntl_cmd_t * +bsm_lookup_local_fcntl_cmd(int local_fcntl_cmd) +{ + int i; + + for (i = 0; i < bsm_fcntl_cmd_count; i++) { + if (bsm_fcntl_cmdtab[i].bfc_local_fcntl_cmd == + local_fcntl_cmd) + return (&bsm_fcntl_cmdtab[i]); + } + return (NULL); +} + +u_short +au_fcntl_cmd_to_bsm(int local_fcntl_cmd) +{ + const bsm_fcntl_cmd_t *bfcp; + + bfcp = bsm_lookup_local_fcntl_cmd(local_fcntl_cmd); + if (bfcp == NULL) + return (BSM_F_UNKNOWN); + return (bfcp->bfc_bsm_fcntl_cmd); +} + +static const bsm_fcntl_cmd_t * +bsm_lookup_bsm_fcntl_cmd(u_short bsm_fcntl_cmd) +{ + int i; + + for (i = 0; i < bsm_fcntl_cmd_count; i++) { + if (bsm_fcntl_cmdtab[i].bfc_bsm_fcntl_cmd == + bsm_fcntl_cmd) + return (&bsm_fcntl_cmdtab[i]); + } + return (NULL); +} + +int +au_bsm_to_fcntl_cmd(u_short bsm_fcntl_cmd, int *local_fcntl_cmdp) +{ + const bsm_fcntl_cmd_t *bfcp; + + bfcp = bsm_lookup_bsm_fcntl_cmd(bsm_fcntl_cmd); + if (bfcp == NULL || bfcp->bfc_local_fcntl_cmd) + return (-1); + *local_fcntl_cmdp = bfcp->bfc_local_fcntl_cmd; + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_flags.c b/contrib/openbsm/libbsm/bsm_flags.c new file mode 100644 index 0000000..46b8a1f --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_flags.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <config/config.h> + +#include <bsm/libbsm.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#ifndef HAVE_STRLCPY +#include <compat/strlcpy.h> +#endif + +static const char *flagdelim = ","; + +/* + * Convert the character representation of audit values into the au_mask_t + * field. + */ +int +getauditflagsbin(char *auditstr, au_mask_t *masks) +{ + char class_ent_name[AU_CLASS_NAME_MAX]; + char class_ent_desc[AU_CLASS_DESC_MAX]; + struct au_class_ent c; + char *tok; + char sel, sub; + char *last; + + bzero(&c, sizeof(c)); + bzero(class_ent_name, sizeof(class_ent_name)); + bzero(class_ent_desc, sizeof(class_ent_desc)); + c.ac_name = class_ent_name; + c.ac_desc = class_ent_desc; + + masks->am_success = 0; + masks->am_failure = 0; + + tok = strtok_r(auditstr, flagdelim, &last); + while (tok != NULL) { + /* Check for the events that should not be audited. */ + if (tok[0] == '^') { + sub = 1; + tok++; + } else + sub = 0; + + /* Check for the events to be audited for success. */ + if (tok[0] == '+') { + sel = AU_PRS_SUCCESS; + tok++; + } else if (tok[0] == '-') { + sel = AU_PRS_FAILURE; + tok++; + } else + sel = AU_PRS_BOTH; + + if ((getauclassnam_r(&c, tok)) != NULL) { + if (sub) + SUB_FROM_MASK(masks, c.ac_class, sel); + else + ADD_TO_MASK(masks, c.ac_class, sel); + } else { + errno = EINVAL; + return (-1); + } + + /* Get the next class. */ + tok = strtok_r(NULL, flagdelim, &last); + } + return (0); +} + +/* + * Convert the au_mask_t fields into a string value. If verbose is non-zero + * the long flag names are used else the short (2-character)flag names are + * used. + * + * XXXRW: If bits are specified that are not matched by any class, they are + * omitted rather than rejected with EINVAL. + * + * XXXRW: This is not thread-safe as it relies on atomicity between + * setauclass() and sequential calls to getauclassent(). This could be + * fixed by iterating through the bitmask fields rather than iterating + * through the classes. + */ +int +getauditflagschar(char *auditstr, au_mask_t *masks, int verbose) +{ + char class_ent_name[AU_CLASS_NAME_MAX]; + char class_ent_desc[AU_CLASS_DESC_MAX]; + struct au_class_ent c; + char *strptr = auditstr; + u_char sel; + + bzero(&c, sizeof(c)); + bzero(class_ent_name, sizeof(class_ent_name)); + bzero(class_ent_desc, sizeof(class_ent_desc)); + c.ac_name = class_ent_name; + c.ac_desc = class_ent_desc; + + /* + * Enumerate the class entries, check if each is selected in either + * the success or failure masks. + */ + setauclass(); + while ((getauclassent_r(&c)) != NULL) { + sel = 0; + + /* Dont do anything for class = no. */ + if (c.ac_class == 0) + continue; + + sel |= ((c.ac_class & masks->am_success) == c.ac_class) ? + AU_PRS_SUCCESS : 0; + sel |= ((c.ac_class & masks->am_failure) == c.ac_class) ? + AU_PRS_FAILURE : 0; + + /* + * No prefix should be attached if both success and failure + * are selected. + */ + if ((sel & AU_PRS_BOTH) == 0) { + if ((sel & AU_PRS_SUCCESS) != 0) { + *strptr = '+'; + strptr = strptr + 1; + } else if ((sel & AU_PRS_FAILURE) != 0) { + *strptr = '-'; + strptr = strptr + 1; + } + } + + if (sel != 0) { + if (verbose) { + strlcpy(strptr, c.ac_desc, AU_CLASS_DESC_MAX); + strptr += strlen(c.ac_desc); + } else { + strlcpy(strptr, c.ac_name, AU_CLASS_NAME_MAX); + strptr += strlen(c.ac_name); + } + *strptr = ','; /* delimiter */ + strptr = strptr + 1; + } + } + + /* Overwrite the last delimiter with the string terminator. */ + if (strptr != auditstr) + *(strptr-1) = '\0'; + + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_io.c b/contrib/openbsm/libbsm/bsm_io.c new file mode 100644 index 0000000..43cf7e9 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_io.c @@ -0,0 +1,4612 @@ +/*- + * Copyright (c) 2004-2009 Apple Inc. + * Copyright (c) 2005 SPARTA, Inc. + * Copyright (c) 2006 Robert N. M. Watson + * Copyright (c) 2006 Martin Voros + * All rights reserved. + * + * This code was developed in part by Robert N. M. Watson, Senior Principal + * Scientist, SPARTA, Inc. + * + * 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. + */ + +#include <sys/types.h> + +#include <config/config.h> + +#ifdef USE_ENDIAN_H +#include <endian.h> +#endif +#ifdef USE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif +#ifdef USE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#endif +#ifdef USE_COMPAT_ENDIAN_H +#include <compat/endian.h> +#endif +#ifdef USE_COMPAT_ENDIAN_ENC_H +#include <compat/endian_enc.h> +#endif + +#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/socket.h> + +#include <bsm/libbsm.h> + +#include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> +#include <grp.h> + +#ifdef HAVE_VIS +#include <vis.h> +#else +#include <compat/vis.h> +#endif + +#include <bsm/audit_internal.h> + +#define READ_TOKEN_BYTES(buf, len, dest, size, bytesread, err) do { \ + if ((bytesread) + (size) > (u_int32_t)(len)) { \ + (err) = 1; \ + } else { \ + memcpy((dest), (buf) + (bytesread), (size)); \ + bytesread += size; \ + } \ +} while (0) + +#define READ_TOKEN_U_CHAR(buf, len, dest, bytesread, err) do { \ + if ((bytesread) + sizeof(u_char) <= (u_int32_t)(len)) { \ + (dest) = buf[(bytesread)]; \ + (bytesread) += sizeof(u_char); \ + } else \ + (err) = 1; \ +} while (0) + +#define READ_TOKEN_U_INT16(buf, len, dest, bytesread, err) do { \ + if ((bytesread) + sizeof(u_int16_t) <= (u_int32_t)(len)) { \ + (dest) = be16dec((buf) + (bytesread)); \ + (bytesread) += sizeof(u_int16_t); \ + } else \ + (err) = 1; \ +} while (0) + +#define READ_TOKEN_U_INT32(buf, len, dest, bytesread, err) do { \ + if ((bytesread) + sizeof(u_int32_t) <= (u_int32_t)(len)) { \ + (dest) = be32dec((buf) + (bytesread)); \ + (bytesread) += sizeof(u_int32_t); \ + } else \ + (err) = 1; \ +} while (0) + +#define READ_TOKEN_U_INT64(buf, len, dest, bytesread, err) do { \ + if ((bytesread) + sizeof(u_int64_t) <= (u_int32_t)(len)) { \ + dest = be64dec((buf) + (bytesread)); \ + (bytesread) += sizeof(u_int64_t); \ + } else \ + (err) = 1; \ +} while (0) + +#define SET_PTR(buf, len, ptr, size, bytesread, err) do { \ + if ((bytesread) + (size) > (u_int32_t)(len)) \ + (err) = 1; \ + else { \ + (ptr) = (buf) + (bytesread); \ + (bytesread) += (size); \ + } \ +} while (0) + +/* + * XML option. + */ +#define AU_PLAIN 0 +#define AU_XML 1 + +/* + * Prints the delimiter string. + */ +static void +print_delim(FILE *fp, const char *del) +{ + + fprintf(fp, "%s", del); +} + +/* + * Prints a single byte in the given format. + */ +static void +print_1_byte(FILE *fp, u_char val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Print 2 bytes in the given format. + */ +static void +print_2_bytes(FILE *fp, u_int16_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints 4 bytes in the given format. + */ +static void +print_4_bytes(FILE *fp, u_int32_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints 8 bytes in the given format. + */ +static void +print_8_bytes(FILE *fp, u_int64_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints the given size of data bytes in hex. + */ +static void +print_mem(FILE *fp, u_char *data, size_t len) +{ + u_int32_t i; + + if (len > 0) { + fprintf(fp, "0x"); + for (i = 0; i < len; i++) + fprintf(fp, "%02x", data[i]); + } +} + +/* + * Prints the given data bytes as a string. + */ +static void +print_string(FILE *fp, const char *str, size_t len) +{ + u_int32_t i; + + if (len > 0) { + for (i = 0; i < len; i++) { + if (str[i] != '\0') + fprintf(fp, "%c", str[i]); + } + } +} + +/* + * Prints the given data bytes as an XML-sanitized string. + */ +static void +print_xml_string(FILE *fp, const char *str, size_t len) +{ + u_int32_t i; + char visbuf[5]; + + if (len == 0) + return; + + for (i = 0; i < len; i++) { + switch (str[i]) { + case '\0': + return; + + case '&': + (void) fprintf(fp, "&"); + break; + + case '<': + (void) fprintf(fp, "<"); + break; + + case '>': + (void) fprintf(fp, ">"); + break; + + case '\"': + (void) fprintf(fp, """); + break; + + case '\'': + (void) fprintf(fp, "'"); + break; + + default: + (void) vis(visbuf, str[i], VIS_CSTYLE, 0); + (void) fprintf(fp, "%s", visbuf); + break; + } + } +} + +/* + * Prints the beginning of an attribute. + */ +static void +open_attr(FILE *fp, const char *str) +{ + + fprintf(fp,"%s=\"", str); +} + +/* + * Prints the end of an attribute. + */ +static void +close_attr(FILE *fp) +{ + + fprintf(fp,"\" "); +} + +/* + * Prints the end of a tag. + */ +static void +close_tag(FILE *fp, u_char type) +{ + + switch(type) { + case AUT_HEADER32: + fprintf(fp, ">"); + break; + + case AUT_HEADER32_EX: + fprintf(fp, ">"); + break; + + case AUT_HEADER64: + fprintf(fp, ">"); + break; + + case AUT_HEADER64_EX: + fprintf(fp, ">"); + break; + + case AUT_ARG32: + fprintf(fp, "/>"); + break; + + case AUT_ARG64: + fprintf(fp, "/>"); + break; + + case AUT_ATTR32: + fprintf(fp, "/>"); + break; + + case AUT_ATTR64: + fprintf(fp, "/>"); + break; + + case AUT_EXIT: + fprintf(fp, "/>"); + break; + + case AUT_EXEC_ARGS: + fprintf(fp, "</exec_args>"); + break; + + case AUT_EXEC_ENV: + fprintf(fp, "</exec_env>"); + break; + + case AUT_OTHER_FILE32: + fprintf(fp, "</file>"); + break; + + case AUT_NEWGROUPS: + fprintf(fp, "</group>"); + break; + + case AUT_IN_ADDR: + fprintf(fp, "</ip_address>"); + break; + + case AUT_IN_ADDR_EX: + fprintf(fp, "</ip_address>"); + break; + + case AUT_IP: + fprintf(fp, "/>"); + break; + + case AUT_IPC: + fprintf(fp, "/>"); + break; + + case AUT_IPC_PERM: + fprintf(fp, "/>"); + break; + + case AUT_IPORT: + fprintf(fp, "</ip_port>"); + break; + + case AUT_OPAQUE: + fprintf(fp, "</opaque>"); + break; + + case AUT_PATH: + fprintf(fp, "</path>"); + break; + + case AUT_PROCESS32: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS32_EX: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS64: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS64_EX: + fprintf(fp, "/>"); + break; + + case AUT_RETURN32: + fprintf(fp, "/>"); + break; + + case AUT_RETURN64: + fprintf(fp, "/>"); + break; + + case AUT_SEQ: + fprintf(fp, "/>"); + break; + + case AUT_SOCKET: + fprintf(fp, "/>"); + break; + + case AUT_SOCKINET32: + fprintf(fp, "/>"); + break; + + case AUT_SOCKUNIX: + fprintf(fp, "/>"); + break; + + case AUT_SOCKINET128: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT32: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT64: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT32_EX: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT64_EX: + fprintf(fp, "/>"); + break; + + case AUT_TEXT: + fprintf(fp, "</text>"); + break; + + case AUT_SOCKET_EX: + fprintf(fp, "/>"); + break; + + case AUT_DATA: + fprintf(fp, "</arbitrary>"); + break; + + case AUT_ZONENAME: + fprintf(fp, "/>"); + break; + } +} + +/* + * Prints the token type in either the raw or the default form. + */ +static void +print_tok_type(FILE *fp, u_char type, const char *tokname, int oflags) +{ + + if (oflags & AU_OFLAG_XML) { + switch(type) { + case AUT_HEADER32: + fprintf(fp, "<record "); + break; + + case AUT_HEADER32_EX: + fprintf(fp, "<record "); + break; + + case AUT_HEADER64: + fprintf(fp, "<record "); + break; + + case AUT_HEADER64_EX: + fprintf(fp, "<record "); + break; + + case AUT_TRAILER: + fprintf(fp, "</record>"); + break; + + case AUT_ARG32: + fprintf(fp, "<argument "); + break; + + case AUT_ARG64: + fprintf(fp, "<argument "); + break; + + case AUT_ATTR32: + fprintf(fp, "<attribute "); + break; + + case AUT_ATTR64: + fprintf(fp, "<attribute "); + break; + + case AUT_EXIT: + fprintf(fp, "<exit "); + break; + + case AUT_EXEC_ARGS: + fprintf(fp, "<exec_args>"); + break; + + case AUT_EXEC_ENV: + fprintf(fp, "<exec_env>"); + break; + + case AUT_OTHER_FILE32: + fprintf(fp, "<file "); + break; + + case AUT_NEWGROUPS: + fprintf(fp, "<group>"); + break; + + case AUT_IN_ADDR: + fprintf(fp, "<ip_address>"); + break; + + case AUT_IN_ADDR_EX: + fprintf(fp, "<ip_address>"); + break; + + case AUT_IP: + fprintf(fp, "<ip "); + break; + + case AUT_IPC: + fprintf(fp, "<IPC"); + break; + + case AUT_IPC_PERM: + fprintf(fp, "<IPC_perm "); + break; + + case AUT_IPORT: + fprintf(fp, "<ip_port>"); + break; + + case AUT_OPAQUE: + fprintf(fp, "<opaque>"); + break; + + case AUT_PATH: + fprintf(fp, "<path>"); + break; + + case AUT_PROCESS32: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS32_EX: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS64: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS64_EX: + fprintf(fp, "<process "); + break; + + case AUT_RETURN32: + fprintf(fp, "<return "); + break; + + case AUT_RETURN64: + fprintf(fp, "<return "); + break; + + case AUT_SEQ: + fprintf(fp, "<sequence "); + break; + + case AUT_SOCKET: + fprintf(fp, "<socket "); + break; + + case AUT_SOCKINET32: + fprintf(fp, "<socket-inet "); + break; + + case AUT_SOCKUNIX: + fprintf(fp, "<socket-unix "); + break; + + case AUT_SOCKINET128: + fprintf(fp, "<socket-inet6 "); + break; + + case AUT_SUBJECT32: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT64: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT32_EX: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT64_EX: + fprintf(fp, "<subject "); + break; + + case AUT_TEXT: + fprintf(fp, "<text>"); + break; + + case AUT_SOCKET_EX: + fprintf(fp, "<socket "); + break; + + case AUT_DATA: + fprintf(fp, "<arbitrary "); + break; + + case AUT_ZONENAME: + fprintf(fp, "<zone "); + break; + } + } else { + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", type); + else + fprintf(fp, "%s", tokname); + } +} + +/* + * Prints a user value. + */ +static void +print_user(FILE *fp, u_int32_t usr, int oflags) +{ + struct passwd *pwent; + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%d", usr); + else { + pwent = getpwuid(usr); + if (pwent != NULL) + fprintf(fp, "%s", pwent->pw_name); + else + fprintf(fp, "%d", usr); + } +} + +/* + * Prints a group value. + */ +static void +print_group(FILE *fp, u_int32_t grp, int oflags) +{ + struct group *grpent; + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%d", grp); + else { + grpent = getgrgid(grp); + if (grpent != NULL) + fprintf(fp, "%s", grpent->gr_name); + else + fprintf(fp, "%d", grp); + } +} + +/* + * Prints the event from the header token in either the short, default or raw + * form. + */ +static void +print_event(FILE *fp, u_int16_t ev, int oflags) +{ + char event_ent_name[AU_EVENT_NAME_MAX]; + char event_ent_desc[AU_EVENT_DESC_MAX]; + struct au_event_ent e, *ep; + + bzero(&e, sizeof(e)); + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + + ep = getauevnum_r(&e, ev); + if (ep == NULL) { + fprintf(fp, "%u", ev); + return; + } + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", ev); + else if (oflags & AU_OFLAG_SHORT) + fprintf(fp, "%s", e.ae_name); + else + fprintf(fp, "%s", e.ae_desc); +} + + +/* + * Prints the event modifier from the header token in either the default or + * raw form. + */ +static void +print_evmod(FILE *fp, u_int16_t evmod, int oflags) +{ + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", evmod); + else + fprintf(fp, "%u", evmod); +} + +/* + * Prints seconds in the ctime format. + */ +static void +print_sec32(FILE *fp, u_int32_t sec, int oflags) +{ + time_t timestamp; + char timestr[26]; + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", sec); + else { + timestamp = (time_t)sec; + ctime_r(×tamp, timestr); + timestr[24] = '\0'; /* No new line */ + fprintf(fp, "%s", timestr); + } +} + +/* + * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we + * assume a 32-bit time_t, we simply truncate for now. + */ +static void +print_sec64(FILE *fp, u_int64_t sec, int oflags) +{ + time_t timestamp; + char timestr[26]; + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", (u_int32_t)sec); + else { + timestamp = (time_t)sec; + ctime_r(×tamp, timestr); + timestr[24] = '\0'; /* No new line */ + fprintf(fp, "%s", timestr); + } +} + +/* + * Prints the excess milliseconds. + */ +static void +print_msec32(FILE *fp, u_int32_t msec, int oflags) +{ + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", msec); + else + fprintf(fp, " + %u msec", msec); +} + +/* + * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we assume + * a 32-bit msec, we simply truncate for now. + */ +static void +print_msec64(FILE *fp, u_int64_t msec, int oflags) +{ + + msec &= 0xffffffff; + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", (u_int32_t)msec); + else + fprintf(fp, " + %u msec", (u_int32_t)msec); +} + +/* + * Prints a dotted form for the IP address. + */ +static void +print_ip_address(FILE *fp, u_int32_t ip) +{ + struct in_addr ipaddr; + + ipaddr.s_addr = ip; + fprintf(fp, "%s", inet_ntoa(ipaddr)); +} + +/* + * Prints a string value for the given ip address. + */ +static void +print_ip_ex_address(FILE *fp, u_int32_t type, u_int32_t *ipaddr) +{ + struct in_addr ipv4; + struct in6_addr ipv6; + char dst[INET6_ADDRSTRLEN]; + + switch (type) { + case AU_IPv4: + ipv4.s_addr = (in_addr_t)(ipaddr[0]); + fprintf(fp, "%s", inet_ntop(AF_INET, &ipv4, dst, + INET6_ADDRSTRLEN)); + break; + + case AU_IPv6: + bcopy(ipaddr, &ipv6, sizeof(ipv6)); + fprintf(fp, "%s", inet_ntop(AF_INET6, &ipv6, dst, + INET6_ADDRSTRLEN)); + break; + + default: + fprintf(fp, "invalid"); + } +} + +/* + * Prints return value as success or failure. + */ +static void +print_retval(FILE *fp, u_char status, int oflags) +{ + int error; + + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", status); + else { + /* + * 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); + } +} + +/* + * Prints the exit value. + */ +static void +print_errval(FILE *fp, u_int32_t val) +{ + + fprintf(fp, "Error %u", val); +} + +/* + * Prints IPC type. + */ +static void +print_ipctype(FILE *fp, u_char type, int oflags) +{ + if (oflags & AU_OFLAG_RAW) + fprintf(fp, "%u", type); + else { + if (type == AT_IPC_MSG) + fprintf(fp, "Message IPC"); + else if (type == AT_IPC_SEM) + fprintf(fp, "Semaphore IPC"); + else if (type == AT_IPC_SHM) + fprintf(fp, "Shared Memory IPC"); + else + fprintf(fp, "%u", type); + } +} + +/* + * Print XML header. + */ +void +au_print_xml_header(FILE *outfp) +{ + + fprintf(outfp, "<?xml version='1.0' ?>\n"); + fprintf(outfp, "<audit>\n"); +} + +/* + * Print XML footer. + */ +void +au_print_xml_footer(FILE *outfp) +{ + + fprintf(outfp, "</audit>\n"); +} + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +static int +fetch_header32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "header", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr32.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr32.e_type, oflags); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr32.e_mod, oflags); + close_attr(fp); + open_attr(fp, "time"); + print_sec32(fp, tok->tt.hdr32.s, oflags); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.hdr32.ms, oflags); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr32.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr32.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr32.e_type, oflags); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr32.e_mod, oflags); + print_delim(fp, del); + print_sec32(fp, tok->tt.hdr32.s, oflags); + print_delim(fp, del); + print_msec32(fp, tok->tt.hdr32.ms, oflags); + } +} + +/* + * The Solaris specifications for AUE_HEADER32_EX seem to differ a bit + * depending on the bit of the specifications found. The OpenSolaris source + * code uses a 4-byte address length, followed by some number of bytes of + * address data. This contrasts with the Solaris audit.log.5 man page, which + * specifies a 1-byte length field. We use the Solaris 10 definition so that + * we can parse audit trails from that system. + * + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * [ Solaris man page: address type/length 1 byte] + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32/64-bits) + * nanoseconds of time 4 bytes/8 bytes (32/64-bits) + */ +static int +fetch_header32_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32_ex.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ad_type, tok->len, err); + if (err) + return (-1); + + bzero(tok->tt.hdr32_ex.addr, sizeof(tok->tt.hdr32_ex.addr)); + switch (tok->tt.hdr32_ex.ad_type) { + case AU_IPv4: + READ_TOKEN_BYTES(buf, len, &tok->tt.hdr32_ex.addr[0], + sizeof(tok->tt.hdr32_ex.addr[0]), tok->len, err); + if (err) + return (-1); + break; + + case AU_IPv6: + READ_TOKEN_BYTES(buf, len, tok->tt.hdr32_ex.addr, + sizeof(tok->tt.hdr32_ex.addr), tok->len, err); + break; + } + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header32_ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "header_ex", oflags); + if (oflags & AU_OFLAG_RAW) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr32_ex.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr32_ex.e_type, oflags); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr32_ex.e_mod, oflags); + close_attr(fp); + open_attr(fp, "host"); + print_ip_ex_address(fp, tok->tt.hdr32_ex.ad_type, + tok->tt.hdr32_ex.addr); + close_attr(fp); + open_attr(fp, "time"); + print_sec32(fp, tok->tt.hdr32_ex.s, oflags); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.hdr32_ex.ms, oflags); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr32_ex.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr32_ex.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr32_ex.e_type, oflags); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr32_ex.e_mod, oflags); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.hdr32_ex.ad_type, + tok->tt.hdr32_ex.addr); + print_delim(fp, del); + print_sec32(fp, tok->tt.hdr32_ex.s, oflags); + print_delim(fp, del); + print_msec32(fp, tok->tt.hdr32_ex.ms, oflags); + } +} + +/* + * record byte count 4 bytes + * event type 2 bytes + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * version # + */ +static int +fetch_header64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "header", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr64.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr64.e_type, oflags); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr64.e_mod, oflags); + close_attr(fp); + open_attr(fp, "time"); + print_sec64(fp, tok->tt.hdr64.s, oflags); + close_attr(fp); + open_attr(fp, "msec"); + print_msec64(fp, tok->tt.hdr64.ms, oflags); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr64.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr64.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr64.e_type, oflags); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr64.e_mod, oflags); + print_delim(fp, del); + print_sec64(fp, tok->tt.hdr64.s, oflags); + print_delim(fp, del); + print_msec64(fp, tok->tt.hdr64.ms, oflags); + } +} + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * [ Solaris man page: address type/length 1 byte] + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32/64-bits) + * nanoseconds of time 4 bytes/8 bytes (32/64-bits) + * + * XXXAUDIT: See comment by fetch_header32_ex_tok() for details on the + * accuracy of the BSM spec. + */ +static int +fetch_header64_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64_ex.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.ad_type, tok->len, err); + if (err) + return (-1); + + bzero(tok->tt.hdr64_ex.addr, sizeof(tok->tt.hdr64_ex.addr)); + switch (tok->tt.hdr64_ex.ad_type) { + case AU_IPv4: + READ_TOKEN_BYTES(buf, len, &tok->tt.hdr64_ex.addr[0], + sizeof(tok->tt.hdr64_ex.addr[0]), tok->len, err); + if (err) + return (-1); + break; + + case AU_IPv6: + READ_TOKEN_BYTES(buf, len, tok->tt.hdr64_ex.addr, + sizeof(tok->tt.hdr64_ex.addr), tok->len, err); + break; + } + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header64_ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "header_ex", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr64_ex.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr64_ex.e_type, oflags); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr64_ex.e_mod, oflags); + close_attr(fp); + open_attr(fp, "host"); + print_ip_ex_address(fp, tok->tt.hdr64_ex.ad_type, + tok->tt.hdr64_ex.addr); + close_attr(fp); + open_attr(fp, "time"); + print_sec64(fp, tok->tt.hdr64_ex.s, oflags); + close_attr(fp); + open_attr(fp, "msec"); + print_msec64(fp, tok->tt.hdr64_ex.ms, oflags); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr64_ex.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr64_ex.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr64_ex.e_type, oflags); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr64_ex.e_mod, oflags); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.hdr64_ex.ad_type, + tok->tt.hdr64_ex.addr); + print_delim(fp, del); + print_sec64(fp, tok->tt.hdr64_ex.s, oflags); + print_delim(fp, del); + print_msec64(fp, tok->tt.hdr64_ex.ms, oflags); + } +} + +/* + * trailer magic 2 bytes + * record size 4 bytes + */ +static int +fetch_trailer_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.trail.magic, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.trail.count, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_trailer_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "trailer", oflags); + if (!(oflags & AU_OFLAG_XML)) { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.trail.count, "%u"); + } +} + +/* + * argument # 1 byte + * argument value 4 bytes/8 bytes (32-bit/64-bit value) + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +static int +fetch_arg32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arg32.no, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.arg32.val, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.arg32.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.arg32.text, tok->tt.arg32.len, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arg32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "argument", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "arg-num"); + print_1_byte(fp, tok->tt.arg32.no, "%u"); + close_attr(fp); + open_attr(fp, "value"); + print_4_bytes(fp, tok->tt.arg32.val, "0x%x"); + close_attr(fp); + open_attr(fp, "desc"); + print_string(fp, tok->tt.arg32.text, tok->tt.arg32.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_1_byte(fp, tok->tt.arg32.no, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.arg32.val, "0x%x"); + print_delim(fp, del); + print_string(fp, tok->tt.arg32.text, tok->tt.arg32.len); + } +} + +static int +fetch_arg64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arg64.no, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.arg64.val, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.arg64.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.arg64.text, tok->tt.arg64.len, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arg64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "argument", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "arg-num"); + print_1_byte(fp, tok->tt.arg64.no, "%u"); + close_attr(fp); + open_attr(fp, "value"); + print_8_bytes(fp, tok->tt.arg64.val, "0x%llx"); + close_attr(fp); + open_attr(fp, "desc"); + print_string(fp, tok->tt.arg64.text, tok->tt.arg64.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_1_byte(fp, tok->tt.arg64.no, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.arg64.val, "0x%llx"); + print_delim(fp, del); + print_string(fp, tok->tt.arg64.text, tok->tt.arg64.len); + } +} + +/* + * how to print 1 byte + * basic unit 1 byte + * unit count 1 byte + * data items (depends on basic unit) + */ +static int +fetch_arb_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int datasize; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.howtopr, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.bu, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.uc, tok->len, err); + if (err) + return (-1); + + /* + * Determine the size of the basic unit. + */ + switch(tok->tt.arb.bu) { + case AUR_BYTE: + /* case AUR_CHAR: */ + datasize = AUR_BYTE_SIZE; + break; + + case AUR_SHORT: + datasize = AUR_SHORT_SIZE; + break; + + case AUR_INT32: + /* case AUR_INT: */ + datasize = AUR_INT32_SIZE; + break; + + case AUR_INT64: + datasize = AUR_INT64_SIZE; + break; + + default: + return (-1); + } + + SET_PTR(buf, len, tok->tt.arb.data, datasize * tok->tt.arb.uc, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arb_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + char *str; + char *format; + size_t size; + int i; + + print_tok_type(fp, tok->id, "arbitrary", oflags); + if (!(oflags & AU_OFLAG_XML)) + print_delim(fp, del); + + switch(tok->tt.arb.howtopr) { + case AUP_BINARY: + str = "binary"; + format = " %c"; + break; + + case AUP_OCTAL: + str = "octal"; + format = " %o"; + break; + + case AUP_DECIMAL: + str = "decimal"; + format = " %d"; + break; + + case AUP_HEX: + str = "hex"; + format = " %x"; + break; + + case AUP_STRING: + str = "string"; + format = "%c"; + break; + + default: + return; + } + + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "print"); + fprintf(fp, "%s",str); + close_attr(fp); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + } + switch(tok->tt.arb.bu) { + case AUR_BYTE: + /* case AUR_CHAR: */ + str = "byte"; + size = AUR_BYTE_SIZE; + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + fprintf(fp, "%zu", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i<tok->tt.arb.uc; i++) + fprintf(fp, format, *(tok->tt.arb.data + + (size * i))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i<tok->tt.arb.uc; i++) + fprintf(fp, format, *(tok->tt.arb.data + + (size * i))); + } + break; + + case AUR_SHORT: + str = "short"; + size = AUR_SHORT_SIZE; + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + fprintf(fp, "%zu", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int16_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int16_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + case AUR_INT32: + /* case AUR_INT: */ + str = "int"; + size = AUR_INT32_SIZE; + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + fprintf(fp, "%zu", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int32_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int32_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + case AUR_INT64: + str = "int64"; + size = AUR_INT64_SIZE; + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + fprintf(fp, "%zu", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int64_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int64_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + default: + return; + } +} + +/* + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +static int +fetch_attr32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.fsid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr32.nid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.dev, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_attr32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "attribute", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.attr32.mode, "%o"); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.attr32.uid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.attr32.gid, oflags); + close_attr(fp); + open_attr(fp, "fsid"); + print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); + close_attr(fp); + open_attr(fp, "nodeid"); + print_8_bytes(fp, tok->tt.attr32.nid, "%lld"); + close_attr(fp); + open_attr(fp, "device"); + print_4_bytes(fp, tok->tt.attr32.dev, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.mode, "%o"); + print_delim(fp, del); + print_user(fp, tok->tt.attr32.uid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.attr32.gid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr32.nid, "%lld"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.dev, "%u"); + } +} + +/* + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +static int +fetch_attr64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.fsid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.nid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.dev, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_attr64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "attribute", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.attr64.mode, "%o"); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.attr64.uid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.attr64.gid, oflags); + close_attr(fp); + open_attr(fp, "fsid"); + print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); + close_attr(fp); + open_attr(fp, "nodeid"); + print_8_bytes(fp, tok->tt.attr64.nid, "%lld"); + close_attr(fp); + open_attr(fp, "device"); + print_8_bytes(fp, tok->tt.attr64.dev, "%llu"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr64.mode, "%o"); + print_delim(fp, del); + print_user(fp, tok->tt.attr64.uid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.attr64.gid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr64.nid, "%lld"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr64.dev, "%llu"); + } +} + +/* + * status 4 bytes + * return value 4 bytes + */ +static int +fetch_exit_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.exit.status, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.exit.ret, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_exit_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "exit", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "errval"); + print_errval(fp, tok->tt.exit.status); + close_attr(fp); + open_attr(fp, "retval"); + print_4_bytes(fp, tok->tt.exit.ret, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_errval(fp, tok->tt.exit.status); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.exit.ret, "%u"); + } +} + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +static int +fetch_execarg_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + u_int32_t i; + u_char *bptr; + + READ_TOKEN_U_INT32(buf, len, tok->tt.execarg.count, tok->len, err); + if (err) + return (-1); + + for (i = 0; i < tok->tt.execarg.count; i++) { + bptr = buf + tok->len; + if (i < AUDIT_MAX_ARGS) + tok->tt.execarg.text[i] = (char*)bptr; + + /* Look for a null terminated string. */ + while (bptr && (*bptr != '\0')) { + if (++tok->len >= (u_int32_t)len) + return (-1); + bptr = buf + tok->len; + } + if (!bptr) + return (-1); + tok->len++; /* \0 character */ + } + if (tok->tt.execarg.count > AUDIT_MAX_ARGS) + tok->tt.execarg.count = AUDIT_MAX_ARGS; + + return (0); +} + +static void +print_execarg_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + u_int32_t i; + + print_tok_type(fp, tok->id, "exec arg", oflags); + for (i = 0; i < tok->tt.execarg.count; i++) { + if (oflags & AU_OFLAG_XML) { + fprintf(fp, "<arg>"); + print_xml_string(fp, tok->tt.execarg.text[i], + strlen(tok->tt.execarg.text[i])); + fprintf(fp, "</arg>"); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.execarg.text[i], + strlen(tok->tt.execarg.text[i])); + } + } + if (oflags & AU_OFLAG_XML) + close_tag(fp, tok->id); +} + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +static int +fetch_execenv_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + u_int32_t i; + u_char *bptr; + + READ_TOKEN_U_INT32(buf, len, tok->tt.execenv.count, tok->len, err); + if (err) + return (-1); + + for (i = 0; i < tok->tt.execenv.count; i++) { + bptr = buf + tok->len; + if (i < AUDIT_MAX_ENV) + tok->tt.execenv.text[i] = (char*)bptr; + + /* Look for a null terminated string. */ + while (bptr && (*bptr != '\0')) { + if (++tok->len >= (u_int32_t)len) + return (-1); + bptr = buf + tok->len; + } + if (!bptr) + return (-1); + tok->len++; /* \0 character */ + } + if (tok->tt.execenv.count > AUDIT_MAX_ENV) + tok->tt.execenv.count = AUDIT_MAX_ENV; + + return (0); +} + +static void +print_execenv_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + u_int32_t i; + + print_tok_type(fp, tok->id, "exec env", oflags); + for (i = 0; i< tok->tt.execenv.count; i++) { + if (oflags & AU_OFLAG_XML) { + fprintf(fp, "<env>"); + print_xml_string(fp, tok->tt.execenv.text[i], + strlen(tok->tt.execenv.text[i])); + fprintf(fp, "</env>"); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.execenv.text[i], + strlen(tok->tt.execenv.text[i])); + } + } + if (oflags & AU_OFLAG_XML) + close_tag(fp, tok->id); +} + +/* + * seconds of time 4 bytes + * milliseconds of time 4 bytes + * file name len 2 bytes + * file pathname N bytes + 1 terminating NULL byte + */ +static int +fetch_file_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.file.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.file.ms, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.file.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.file.name, tok->tt.file.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_file_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "file", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "time"); + print_sec32(fp, tok->tt.file.s, oflags); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.file.ms, oflags); + close_attr(fp); + fprintf(fp, ">"); + print_string(fp, tok->tt.file.name, tok->tt.file.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_sec32(fp, tok->tt.file.s, oflags); + print_delim(fp, del); + print_msec32(fp, tok->tt.file.ms, oflags); + print_delim(fp, del); + print_string(fp, tok->tt.file.name, tok->tt.file.len); + } +} + +/* + * number groups 2 bytes + * group list count * 4 bytes + */ +static int +fetch_newgroups_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int i; + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.grps.no, tok->len, err); + if (err) + return (-1); + + for (i = 0; i<tok->tt.grps.no; i++) { + READ_TOKEN_U_INT32(buf, len, tok->tt.grps.list[i], tok->len, + err); + if (err) + return (-1); + } + + return (0); +} + +static void +print_newgroups_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + int i; + + print_tok_type(fp, tok->id, "group", oflags); + for (i = 0; i < tok->tt.grps.no; i++) { + if (oflags & AU_OFLAG_XML) { + fprintf(fp, "<gid>"); + print_group(fp, tok->tt.grps.list[i], oflags); + fprintf(fp, "</gid>"); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_group(fp, tok->tt.grps.list[i], oflags); + } + } +} + +/* + * Internet addr 4 bytes + */ +static int +fetch_inaddr_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr.addr, sizeof(uint32_t), + tok->len, err); + if (err) + return (-1); + + return (0); + +} + +static void +print_inaddr_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "ip addr", oflags); + if (oflags & AU_OFLAG_XML) { + print_ip_address(fp, tok->tt.inaddr.addr); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ip_address(fp, tok->tt.inaddr.addr); + } +} + +/* + * type 4 bytes + * address 16 bytes + */ +static int +fetch_inaddr_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.inaddr_ex.type, tok->len, err); + if (err) + return (-1); + + if (tok->tt.inaddr_ex.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr_ex.addr[0], + sizeof(tok->tt.inaddr_ex.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.inaddr_ex.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.inaddr_ex.addr, + sizeof(tok->tt.inaddr_ex.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_inaddr_ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "ip addr ex", oflags); + if (oflags & AU_OFLAG_XML) { + print_ip_ex_address(fp, tok->tt.inaddr_ex.type, + tok->tt.inaddr_ex.addr); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.inaddr_ex.type, + tok->tt.inaddr_ex.addr); + } +} + +/* + * ip header 20 bytes + */ +static int +fetch_ip_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.tos, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.len, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.id, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.offset, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.ttl, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.prot, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.chksm, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.src, sizeof(tok->tt.ip.src), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.dest, sizeof(tok->tt.ip.dest), + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ip_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "ip", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "version"); + print_mem(fp, (u_char *)(&tok->tt.ip.version), + sizeof(u_char)); + close_attr(fp); + open_attr(fp, "service_type"); + print_mem(fp, (u_char *)(&tok->tt.ip.tos), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "len"); + print_2_bytes(fp, ntohs(tok->tt.ip.len), "%u"); + close_attr(fp); + open_attr(fp, "id"); + print_2_bytes(fp, ntohs(tok->tt.ip.id), "%u"); + close_attr(fp); + open_attr(fp, "offset"); + print_2_bytes(fp, ntohs(tok->tt.ip.offset), "%u"); + close_attr(fp); + open_attr(fp, "time_to_live"); + print_mem(fp, (u_char *)(&tok->tt.ip.ttl), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "protocol"); + print_mem(fp, (u_char *)(&tok->tt.ip.prot), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "cksum"); + print_2_bytes(fp, ntohs(tok->tt.ip.chksm), "%u"); + close_attr(fp); + open_attr(fp, "src_addr"); + print_ip_address(fp, tok->tt.ip.src); + close_attr(fp); + open_attr(fp, "dest_addr"); + print_ip_address(fp, tok->tt.ip.dest); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.version), + sizeof(u_char)); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.tos), sizeof(u_char)); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.len), "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.id), "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.offset), "%u"); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.ttl), sizeof(u_char)); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.prot), sizeof(u_char)); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.chksm), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.ip.src); + print_delim(fp, del); + print_ip_address(fp, tok->tt.ip.dest); + } +} + +/* + * object ID type 1 byte + * Object ID 4 bytes + */ +static int +fetch_ipc_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ipc.type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipc.id, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ipc_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "IPC", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "ipc-type"); + print_ipctype(fp, tok->tt.ipc.type, oflags); + close_attr(fp); + open_attr(fp, "ipc-id"); + print_4_bytes(fp, tok->tt.ipc.id, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ipctype(fp, tok->tt.ipc.type, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipc.id, "%u"); + } +} + +/* + * owner user id 4 bytes + * owner group id 4 bytes + * creator user id 4 bytes + * creator group id 4 bytes + * access mode 4 bytes + * slot seq 4 bytes + * key 4 bytes + */ +static int +fetch_ipcperm_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.puid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.pgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.seq, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.key, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ipcperm_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "IPC perm", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "uid"); + print_user(fp, tok->tt.ipcperm.uid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.ipcperm.gid, oflags); + close_attr(fp); + open_attr(fp, "creator-uid"); + print_user(fp, tok->tt.ipcperm.puid, oflags); + close_attr(fp); + open_attr(fp, "creator-gid"); + print_group(fp, tok->tt.ipcperm.pgid, oflags); + close_attr(fp); + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); + close_attr(fp); + open_attr(fp, "seq"); + print_4_bytes(fp, tok->tt.ipcperm.seq, "%u"); + close_attr(fp); + open_attr(fp, "key"); + print_4_bytes(fp, tok->tt.ipcperm.key, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.ipcperm.uid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.ipcperm.gid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.ipcperm.puid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.ipcperm.pgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.seq, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.key, "%u"); + } +} + +/* + * port Ip address 2 bytes + */ +static int +fetch_iport_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_BYTES(buf, len, &tok->tt.iport.port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_iport_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "ip port", oflags); + if (oflags & AU_OFLAG_XML) { + print_2_bytes(fp, ntohs(tok->tt.iport.port), "%#x"); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.iport.port), "%#x"); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_opaque_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.opaque.size, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.opaque.data, tok->tt.opaque.size, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_opaque_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "opaque", oflags); + if (oflags & AU_OFLAG_XML) { + print_mem(fp, (u_char*)tok->tt.opaque.data, + tok->tt.opaque.size); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.opaque.size, "%u"); + print_delim(fp, del); + print_mem(fp, (u_char*)tok->tt.opaque.data, + tok->tt.opaque.size); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_path_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.path.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.path.path, tok->tt.path.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_path_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "path", oflags); + if (oflags & AU_OFLAG_XML) { + print_string(fp, tok->tt.path.path, tok->tt.path.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.path.path, tok->tt.path.len); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes + * machine id 4 bytes + */ +static int +fetch_process32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.proc32.tid.addr, + sizeof(tok->tt.proc32.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_process32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "process", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc32.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc32.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc32.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc32.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc32.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc32.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc32.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.proc32.tid.port, "%u"); + print_ip_address(fp, tok->tt.proc32.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc32.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc32.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc32.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc32.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc32.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.tid.port, "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.proc32.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 8 bytes + * machine id 4 bytes + */ +static int +fetch_process64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.proc64.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.proc64.tid.addr, + sizeof(tok->tt.proc64.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_process64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + print_tok_type(fp, tok->id, "process", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc64.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc64.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc64.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc64.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc64.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc64.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc64.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.proc64.tid.port, "%llu"); + print_ip_address(fp, tok->tt.proc64.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc64.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc64.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc64.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc64.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc64.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.proc64.tid.port, "%llu"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.proc64.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes + * address type-len 4 bytes + * machine address 16 bytes + */ +static int +fetch_process32ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.proc32_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.proc32_ex.tid.addr[0], + sizeof(tok->tt.proc32_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.proc32_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.proc32_ex.tid.addr, + sizeof(tok->tt.proc32_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_process32ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "process_ex", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc32_ex.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc32_ex.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc32_ex.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc32_ex.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc32_ex.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc32_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.proc32_ex.tid.port, "%u"); + print_ip_ex_address(fp, tok->tt.proc32_ex.tid.type, + tok->tt.proc32_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc32_ex.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc32_ex.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.tid.port, "%u"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.proc32_ex.tid.type, + tok->tt.proc32_ex.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 8 bytes + * address type-len 4 bytes + * machine address 16 bytes + */ +static int +fetch_process64ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.proc64_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.proc64_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.proc64_ex.tid.addr[0], + sizeof(tok->tt.proc64_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.proc64_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.proc64_ex.tid.addr, + sizeof(tok->tt.proc64_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_process64ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + print_tok_type(fp, tok->id, "process_ex", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc64_ex.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc64_ex.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc64_ex.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc64_ex.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc64_ex.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc64_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.proc64_ex.tid.port, "%llu"); + print_ip_ex_address(fp, tok->tt.proc64_ex.tid.type, + tok->tt.proc64_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc64_ex.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.proc64_ex.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64_ex.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.proc64_ex.tid.port, "%llu"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.proc64_ex.tid.type, + tok->tt.proc64_ex.tid.addr); + } +} + +/* + * errno 1 byte + * return value 4 bytes + */ +static int +fetch_return32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ret32.status, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ret32.ret, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_return32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "return", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp ,"errval"); + print_retval(fp, tok->tt.ret32.status, oflags); + close_attr(fp); + open_attr(fp, "retval"); + print_4_bytes(fp, tok->tt.ret32.ret, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_retval(fp, tok->tt.ret32.status, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ret32.ret, "%u"); + } +} + +static int +fetch_return64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ret64.err, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.ret64.val, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_return64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "return", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "errval"); + print_retval(fp, tok->tt.ret64.err, oflags); + close_attr(fp); + open_attr(fp, "retval"); + print_8_bytes(fp, tok->tt.ret64.val, "%lld"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_retval(fp, tok->tt.ret64.err, oflags); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.ret64.val, "%lld"); + } +} + +/* + * seq 4 bytes + */ +static int +fetch_seq_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.seq.seqno, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_seq_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "sequence", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "seq-num"); + print_4_bytes(fp, tok->tt.seq.seqno, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.seq.seqno, "%u"); + } +} + +/* + * socket family 2 bytes + * local port 2 bytes + * socket address 4 bytes + */ +static int +fetch_sock_inet32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.sockinet_ex32.family, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet_ex32.port, + sizeof(uint16_t), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet_ex32.addr, + sizeof(tok->tt.sockinet_ex32.addr[0]), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_sock_inet32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "socket-inet", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + print_2_bytes(fp, tok->tt.sockinet_ex32.family, "%u"); + close_attr(fp); + open_attr(fp, "port"); + print_2_bytes(fp, ntohs(tok->tt.sockinet_ex32.port), "%u"); + close_attr(fp); + open_attr(fp, "addr"); + print_ip_address(fp, tok->tt.sockinet_ex32.addr[0]); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.sockinet_ex32.family, "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.sockinet_ex32.port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.sockinet_ex32.addr[0]); + } +} + +/* + * socket family 2 bytes + * local port 2 bytes + * socket address 16 bytes + */ +static int +fetch_sock_inet128_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.sockinet_ex32.family, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet_ex32.port, + sizeof(uint16_t), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet_ex32.addr, + sizeof(tok->tt.sockinet_ex32.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_sock_inet128_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "socket-inet6", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + print_2_bytes(fp, tok->tt.sockinet_ex32.family, "%u"); + close_attr(fp); + open_attr(fp, "port"); + print_2_bytes(fp, ntohs(tok->tt.sockinet_ex32.port), "%u"); + close_attr(fp); + open_attr(fp, "addr"); + print_ip_ex_address(fp, AU_IPv6, tok->tt.sockinet_ex32.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.sockinet_ex32.family, "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.sockinet_ex32.port), "%u"); + print_delim(fp, del); + print_ip_ex_address(fp, AU_IPv6, tok->tt.sockinet_ex32.addr); + } +} + +/* + * socket family 2 bytes + * path (up to) 104 bytes + NULL (NULL terminated string). + */ +static int +fetch_sock_unix_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + u_char *p; + int slen; + + + READ_TOKEN_U_INT16(buf, len, tok->tt.sockunix.family, tok->len, err); + if (err) + return (-1); + + /* slen = strnlen((buf + tok->len), 104) + 1; */ + p = (u_char *)memchr((const void *)(buf + tok->len), '\0', 104); + slen = (p ? (int)(p - (buf + tok->len)) : 104) + 1; + + READ_TOKEN_BYTES(buf, len, tok->tt.sockunix.path, slen, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_sock_unix_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "socket-unix", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + print_2_bytes(fp, tok->tt.sockunix.family, "%u"); + close_attr(fp); + open_attr(fp, "port"); + close_attr(fp); + open_attr(fp, "addr"); + print_string(fp, tok->tt.sockunix.path, + strlen(tok->tt.sockunix.path)); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.sockunix.family, "%u"); + print_delim(fp, del); + print_string(fp, tok->tt.sockunix.path, + strlen(tok->tt.sockunix.path)); + } +} + +/* + * socket type 2 bytes + * local port 2 bytes + * local address 4 bytes + * remote port 2 bytes + * remote address 4 bytes + */ +static int +fetch_socket_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.socket.type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr, + sizeof(tok->tt.socket.l_addr), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.r_port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr, + sizeof(tok->tt.socket.r_addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_socket_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "socket", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "sock_type"); + print_2_bytes(fp, tok->tt.socket.type, "%u"); + close_attr(fp); + open_attr(fp, "lport"); + print_2_bytes(fp, ntohs(tok->tt.socket.l_port), "%u"); + close_attr(fp); + open_attr(fp, "laddr"); + print_ip_address(fp, tok->tt.socket.l_addr); + close_attr(fp); + open_attr(fp, "fport"); + print_2_bytes(fp, ntohs(tok->tt.socket.r_port), "%u"); + close_attr(fp); + open_attr(fp, "faddr"); + print_ip_address(fp, tok->tt.socket.r_addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.socket.type, "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.socket.l_port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket.l_addr); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.socket.r_port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket.r_addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes/8 bytes (32-bit/64-bit value) + * machine id 4 bytes + */ +static int +fetch_subject32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.subj32.tid.addr, + sizeof(tok->tt.subj32.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_subject32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "subject", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj32.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj32.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj32.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj32.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj32.rgid, oflags); + close_attr(fp); + open_attr(fp,"pid"); + print_4_bytes(fp, tok->tt.subj32.pid, "%u"); + close_attr(fp); + open_attr(fp,"sid"); + print_4_bytes(fp, tok->tt.subj32.sid, "%u"); + close_attr(fp); + open_attr(fp,"tid"); + print_4_bytes(fp, tok->tt.subj32.tid.port, "%u "); + print_ip_address(fp, tok->tt.subj32.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj32.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj32.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj32.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj32.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj32.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.tid.port, "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.subj32.tid.addr); + } +} + +static void +print_upriv_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "use of privilege", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "status"); + if (tok->tt.priv.sorf) + (void) fprintf(fp, "successful use of priv"); + else + (void) fprintf(fp, "failed use of priv"); + close_attr(fp); + open_attr(fp, "name"); + print_string(fp, tok->tt.priv.priv, tok->tt.priv.privstrlen); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + if (tok->tt.priv.sorf) + (void) fprintf(fp, "successful use of priv"); + else + (void) fprintf(fp, "failed use of priv"); + print_delim(fp, del); + print_string(fp, tok->tt.priv.priv, tok->tt.priv.privstrlen); + } +} + +/* + * status 1 byte + * privstrlen 2 bytes + * priv N bytes + 1 (\0 byte) + */ +static int +fetch_priv_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.priv.sorf, tok->len, err); + if (err) + return (-1); + READ_TOKEN_U_INT16(buf, len, tok->tt.priv.privstrlen, tok->len, err); + if (err) + return (-1); + SET_PTR((char *)buf, len, tok->tt.priv.priv, tok->tt.priv.privstrlen, + tok->len, err); + if (err) + return (-1); + return (0); +} + +/* + * privtstrlen 1 byte + * privtstr N bytes + 1 + * privstrlen 1 byte + * privstr N bytes + 1 + */ +static int +fetch_privset_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.privset.privtstrlen, + tok->len, err); + if (err) + return (-1); + SET_PTR((char *)buf, len, tok->tt.privset.privtstr, + tok->tt.privset.privtstrlen, tok->len, err); + if (err) + return (-1); + READ_TOKEN_U_INT16(buf, len, tok->tt.privset.privstrlen, + tok->len, err); + if (err) + return (-1); + SET_PTR((char *)buf, len, tok->tt.privset.privstr, + tok->tt.privset.privstrlen, tok->len, err); + if (err) + return (-1); + return (0); +} + +static void +print_privset_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "privilege", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "type"); + print_string(fp, tok->tt.privset.privtstr, + tok->tt.privset.privtstrlen); + close_attr(fp); + open_attr(fp, "priv"); + print_string(fp, tok->tt.privset.privstr, + tok->tt.privset.privstrlen); + close_attr(fp); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.privset.privtstr, + tok->tt.privset.privtstrlen); + print_delim(fp, del); + print_string(fp, tok->tt.privset.privstr, + tok->tt.privset.privstrlen); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes/8 bytes (32-bit/64-bit value) + * machine id 4 bytes + */ +static int +fetch_subject64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.subj64.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.subj64.tid.addr, + sizeof(tok->tt.subj64.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_subject64_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "subject", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj64.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj64.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj64.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj64.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj64.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj64.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj64.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.subj64.tid.port, "%llu"); + print_ip_address(fp, tok->tt.subj64.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj64.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj64.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj64.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj64.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj64.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.subj64.tid.port, "%llu"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.subj64.tid.addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes + * type 4 bytes + * machine id 16 bytes + */ +static int +fetch_subject32ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.subj32_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.subj32_ex.tid.addr[0], + sizeof(tok->tt.subj32_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.subj32_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.subj32_ex.tid.addr, + sizeof(tok->tt.subj32_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_subject32ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "subject_ex", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj32_ex.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj32_ex.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj32_ex.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj32_ex.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj32_ex.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj32_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.subj32_ex.tid.port, "%u"); + print_ip_ex_address(fp, tok->tt.subj32_ex.tid.type, + tok->tt.subj32_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj32_ex.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj32_ex.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.tid.port, "%u"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.subj32_ex.tid.type, + tok->tt.subj32_ex.tid.addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 8 bytes + * type 4 bytes + * machine id 16 bytes + */ +static int +fetch_subject64ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.subj64_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.subj64_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.subj64_ex.tid.addr[0], + sizeof(tok->tt.subj64_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.subj64_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.subj64_ex.tid.addr, + sizeof(tok->tt.subj64_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_subject64ex_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + print_tok_type(fp, tok->id, "subject_ex", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj64_ex.auid, oflags); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj64_ex.euid, oflags); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj64_ex.egid, oflags); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj64_ex.ruid, oflags); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj64_ex.rgid, oflags); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj64_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.subj64_ex.tid.port, "%llu"); + print_ip_ex_address(fp, tok->tt.subj64_ex.tid.type, + tok->tt.subj64_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.auid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.euid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj64_ex.egid, oflags); + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.ruid, oflags); + print_delim(fp, del); + print_group(fp, tok->tt.subj64_ex.rgid, oflags); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64_ex.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.subj64_ex.tid.port, "%llu"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.subj64_ex.tid.type, + tok->tt.subj64_ex.tid.addr); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_text_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.text.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.text.text, tok->tt.text.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_text_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "text", oflags); + if (oflags & AU_OFLAG_XML) { + print_string(fp, tok->tt.text.text, tok->tt.text.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.text.text, tok->tt.text.len); + } +} + +/* + * socket domain 2 bytes + * socket type 2 bytes + * address type 2 bytes + * local port 2 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.domain, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.atype, tok->len, + err); + if (err) + return (-1); + + 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.l_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.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_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); +} + +static void +print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + /* + * This print routine prints BSM constant space domains and socket + * types rather than converting them. If we add string printers for + * these constants in the future, we may want to call conversion + * routines. + */ + print_tok_type(fp, tok->id, "socket", oflags); + if (oflags & AU_OFLAG_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); + open_attr(fp, "lport"); + print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x"); + close_attr(fp); + open_attr(fp, "laddr"); + 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_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"); + close_attr(fp); + 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_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_ex_address(fp, tok->tt.socket_ex32.atype, + tok->tt.socket_ex32.r_addr); + } +} + +static int +fetch_invalid_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int recoversize; + + recoversize = len - (tok->len + AUDIT_TRAILER_SIZE); + if (recoversize <= 0) + return (-1); + + tok->tt.invalid.length = recoversize; + + SET_PTR((char*)buf, len, tok->tt.invalid.data, recoversize, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_invalid_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + if (!(oflags & AU_OFLAG_XML)) { + print_tok_type(fp, tok->id, "unknown", oflags); + print_delim(fp, del); + print_mem(fp, (u_char*)tok->tt.invalid.data, + tok->tt.invalid.length); + } +} + + +/* + * size 2 bytes; + * zonename size bytes; + */ +static int +fetch_zonename_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.zonename.len, tok->len, err); + if (err) + return (-1); + SET_PTR((char *)buf, len, tok->tt.zonename.zonename, tok->tt.zonename.len, + tok->len, err); + if (err) + return (-1); + return (0); +} + +static void +print_zonename_tok(FILE *fp, tokenstr_t *tok, char *del, int oflags) +{ + + print_tok_type(fp, tok->id, "zone", oflags); + if (oflags & AU_OFLAG_XML) { + open_attr(fp, "name"); + print_string(fp, tok->tt.zonename.zonename, + tok->tt.zonename.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.zonename.zonename, + tok->tt.zonename.len); + } +} + +/* + * Reads the token beginning at buf into tok. + */ +int +au_fetch_tok(tokenstr_t *tok, u_char *buf, int len) +{ + + if (len <= 0) + return (-1); + + tok->len = 1; + tok->data = buf; + tok->id = *buf; + + switch(tok->id) { + case AUT_HEADER32: + return (fetch_header32_tok(tok, buf, len)); + + case AUT_HEADER32_EX: + return (fetch_header32_ex_tok(tok, buf, len)); + + case AUT_HEADER64: + return (fetch_header64_tok(tok, buf, len)); + + case AUT_HEADER64_EX: + return (fetch_header64_ex_tok(tok, buf, len)); + + case AUT_TRAILER: + return (fetch_trailer_tok(tok, buf, len)); + + case AUT_ARG32: + return (fetch_arg32_tok(tok, buf, len)); + + case AUT_ARG64: + return (fetch_arg64_tok(tok, buf, len)); + + case AUT_ATTR32: + return (fetch_attr32_tok(tok, buf, len)); + + case AUT_ATTR64: + return (fetch_attr64_tok(tok, buf, len)); + + case AUT_EXIT: + return (fetch_exit_tok(tok, buf, len)); + + case AUT_EXEC_ARGS: + return (fetch_execarg_tok(tok, buf, len)); + + case AUT_EXEC_ENV: + return (fetch_execenv_tok(tok, buf, len)); + + case AUT_OTHER_FILE32: + return (fetch_file_tok(tok, buf, len)); + + case AUT_NEWGROUPS: + return (fetch_newgroups_tok(tok, buf, len)); + + case AUT_IN_ADDR: + return (fetch_inaddr_tok(tok, buf, len)); + + case AUT_IN_ADDR_EX: + return (fetch_inaddr_ex_tok(tok, buf, len)); + + case AUT_IP: + return (fetch_ip_tok(tok, buf, len)); + + case AUT_IPC: + return (fetch_ipc_tok(tok, buf, len)); + + case AUT_IPC_PERM: + return (fetch_ipcperm_tok(tok, buf, len)); + + case AUT_IPORT: + return (fetch_iport_tok(tok, buf, len)); + + case AUT_OPAQUE: + return (fetch_opaque_tok(tok, buf, len)); + + case AUT_PATH: + return (fetch_path_tok(tok, buf, len)); + + case AUT_PROCESS32: + return (fetch_process32_tok(tok, buf, len)); + + case AUT_PROCESS32_EX: + return (fetch_process32ex_tok(tok, buf, len)); + + case AUT_PROCESS64: + return (fetch_process64_tok(tok, buf, len)); + + case AUT_PROCESS64_EX: + return (fetch_process64ex_tok(tok, buf, len)); + + case AUT_RETURN32: + return (fetch_return32_tok(tok, buf, len)); + + case AUT_RETURN64: + return (fetch_return64_tok(tok, buf, len)); + + case AUT_SEQ: + return (fetch_seq_tok(tok, buf, len)); + + case AUT_SOCKET: + return (fetch_socket_tok(tok, buf, len)); + + case AUT_SOCKINET32: + return (fetch_sock_inet32_tok(tok, buf, len)); + + case AUT_SOCKUNIX: + return (fetch_sock_unix_tok(tok, buf, len)); + + case AUT_SOCKINET128: + return (fetch_sock_inet128_tok(tok, buf, len)); + + case AUT_SUBJECT32: + return (fetch_subject32_tok(tok, buf, len)); + + case AUT_SUBJECT32_EX: + return (fetch_subject32ex_tok(tok, buf, len)); + + case AUT_SUBJECT64: + return (fetch_subject64_tok(tok, buf, len)); + + case AUT_SUBJECT64_EX: + return (fetch_subject64ex_tok(tok, buf, len)); + + case AUT_TEXT: + return (fetch_text_tok(tok, buf, len)); + + case AUT_SOCKET_EX: + return (fetch_socketex32_tok(tok, buf, len)); + + case AUT_DATA: + return (fetch_arb_tok(tok, buf, len)); + + case AUT_ZONENAME: + return (fetch_zonename_tok(tok, buf, len)); + + case AUT_UPRIV: + return (fetch_priv_tok(tok, buf, len)); + + case AUT_PRIV: + return (fetch_privset_tok(tok, buf, len)); + + default: + return (fetch_invalid_tok(tok, buf, len)); + } +} + +void +au_print_flags_tok(FILE *outfp, tokenstr_t *tok, char *del, int oflags) +{ + + switch(tok->id) { + case AUT_HEADER32: + print_header32_tok(outfp, tok, del, oflags); + return; + + case AUT_HEADER32_EX: + print_header32_ex_tok(outfp, tok, del, oflags); + return; + + case AUT_HEADER64: + print_header64_tok(outfp, tok, del, oflags); + return; + + case AUT_HEADER64_EX: + print_header64_ex_tok(outfp, tok, del, oflags); + return; + + case AUT_TRAILER: + print_trailer_tok(outfp, tok, del, oflags); + return; + + case AUT_ARG32: + print_arg32_tok(outfp, tok, del, oflags); + return; + + case AUT_ARG64: + print_arg64_tok(outfp, tok, del, oflags); + return; + + case AUT_DATA: + print_arb_tok(outfp, tok, del, oflags); + return; + + case AUT_ATTR32: + print_attr32_tok(outfp, tok, del, oflags); + return; + + case AUT_ATTR64: + print_attr64_tok(outfp, tok, del, oflags); + return; + + case AUT_EXIT: + print_exit_tok(outfp, tok, del, oflags); + return; + + case AUT_EXEC_ARGS: + print_execarg_tok(outfp, tok, del, oflags); + return; + + case AUT_EXEC_ENV: + print_execenv_tok(outfp, tok, del, oflags); + return; + + case AUT_OTHER_FILE32: + print_file_tok(outfp, tok, del, oflags); + return; + + case AUT_NEWGROUPS: + print_newgroups_tok(outfp, tok, del, oflags); + return; + + case AUT_IN_ADDR: + print_inaddr_tok(outfp, tok, del, oflags); + return; + + case AUT_IN_ADDR_EX: + print_inaddr_ex_tok(outfp, tok, del, oflags); + return; + + case AUT_IP: + print_ip_tok(outfp, tok, del, oflags); + return; + + case AUT_IPC: + print_ipc_tok(outfp, tok, del, oflags); + return; + + case AUT_IPC_PERM: + print_ipcperm_tok(outfp, tok, del, oflags); + return; + + case AUT_IPORT: + print_iport_tok(outfp, tok, del, oflags); + return; + + case AUT_OPAQUE: + print_opaque_tok(outfp, tok, del, oflags); + return; + + case AUT_PATH: + print_path_tok(outfp, tok, del, oflags); + return; + + case AUT_PROCESS32: + print_process32_tok(outfp, tok, del, oflags); + return; + + case AUT_PROCESS32_EX: + print_process32ex_tok(outfp, tok, del, oflags); + return; + + case AUT_PROCESS64: + print_process64_tok(outfp, tok, del, oflags); + return; + + case AUT_PROCESS64_EX: + print_process64ex_tok(outfp, tok, del, oflags); + return; + + case AUT_RETURN32: + print_return32_tok(outfp, tok, del, oflags); + return; + + case AUT_RETURN64: + print_return64_tok(outfp, tok, del, oflags); + return; + + case AUT_SEQ: + print_seq_tok(outfp, tok, del, oflags); + return; + + case AUT_SOCKET: + print_socket_tok(outfp, tok, del, oflags); + return; + + case AUT_SOCKINET32: + print_sock_inet32_tok(outfp, tok, del, oflags); + return; + + case AUT_SOCKUNIX: + print_sock_unix_tok(outfp, tok, del, oflags); + return; + + case AUT_SOCKINET128: + print_sock_inet128_tok(outfp, tok, del, oflags); + return; + + case AUT_SUBJECT32: + print_subject32_tok(outfp, tok, del, oflags); + return; + + case AUT_SUBJECT64: + print_subject64_tok(outfp, tok, del, oflags); + return; + + case AUT_SUBJECT32_EX: + print_subject32ex_tok(outfp, tok, del, oflags); + return; + + case AUT_SUBJECT64_EX: + print_subject64ex_tok(outfp, tok, del, oflags); + return; + + case AUT_TEXT: + print_text_tok(outfp, tok, del, oflags); + return; + + case AUT_SOCKET_EX: + print_socketex32_tok(outfp, tok, del, oflags); + return; + + case AUT_ZONENAME: + print_zonename_tok(outfp, tok, del, oflags); + return; + + case AUT_UPRIV: + print_upriv_tok(outfp, tok, del, oflags); + return; + + case AUT_PRIV: + print_privset_tok(outfp, tok, del, oflags); + return; + + default: + print_invalid_tok(outfp, tok, del, oflags); + } +} + +/* + * 'prints' the token out to outfp. + */ +void +au_print_tok(FILE *outfp, tokenstr_t *tok, char *del, char raw, char sfrm) +{ + int oflags = AU_OFLAG_NONE; + + if (raw) + oflags |= AU_OFLAG_RAW; + if (sfrm) + oflags |= AU_OFLAG_SHORT; + + au_print_flags_tok(outfp, tok, del, oflags); +} + +/* + * 'prints' the token out to outfp in XML format. + */ +void +au_print_tok_xml(FILE *outfp, tokenstr_t *tok, char *del, char raw, + char sfrm) +{ + int oflags = AU_OFLAG_XML; + + if (raw) + oflags |= AU_OFLAG_RAW; + if (sfrm) + oflags |= AU_OFLAG_SHORT; + + au_print_flags_tok(outfp, tok, del, oflags); +} + +/* + * Read a record from the file pointer, store data in buf memory for buf is + * also allocated in this function and has to be free'd outside this call. + * + * au_read_rec() handles two possibilities: a stand-alone file token, or a + * complete audit record. + * + * XXXRW: Note that if we hit an error, we leave the stream in an unusable + * state, because it will be partly offset into a record. We should rewind + * or do something more intelligent. Particularly interesting is the case + * where we perform a partial read of a record from a non-blockable file + * descriptor. We should return the partial read and continue...? + */ +int +au_read_rec(FILE *fp, u_char **buf) +{ + u_char *bptr; + u_int32_t recsize; + u_int32_t bytestoread; + u_char type; + + u_int32_t sec, msec; + u_int16_t filenamelen; + + type = fgetc(fp); + + switch (type) { + case AUT_HEADER32: + case AUT_HEADER32_EX: + case AUT_HEADER64: + case AUT_HEADER64_EX: + /* read the record size from the token */ + if (fread(&recsize, 1, sizeof(u_int32_t), fp) < + sizeof(u_int32_t)) { + errno = EINVAL; + return (-1); + } + recsize = be32toh(recsize); + + /* Check for recsize sanity */ + if (recsize < (sizeof(u_int32_t) + sizeof(u_char))) { + errno = EINVAL; + return (-1); + } + + *buf = calloc(recsize, sizeof(u_char)); + if (*buf == NULL) + return (-1); + bptr = *buf; + + /* store the token contents already read, back to the buffer*/ + *bptr = type; + bptr++; + be32enc(bptr, recsize); + bptr += sizeof(u_int32_t); + + /* now read remaining record bytes */ + bytestoread = recsize - (sizeof(u_int32_t) + sizeof(u_char)); + + if (fread(bptr, 1, bytestoread, fp) < bytestoread) { + free(*buf); + errno = EINVAL; + return (-1); + } + break; + + case AUT_OTHER_FILE32: + /* + * The file token is variable-length, as it includes a + * pathname. As a result, we have to read incrementally + * until we know the total length, then allocate space and + * read the rest. + */ + if (fread(&sec, 1, sizeof(sec), fp) < sizeof(sec)) { + errno = EINVAL; + return (-1); + } + if (fread(&msec, 1, sizeof(msec), fp) < sizeof(msec)) { + errno = EINVAL; + return (-1); + } + if (fread(&filenamelen, 1, sizeof(filenamelen), fp) < + sizeof(filenamelen)) { + errno = EINVAL; + return (-1); + } + recsize = sizeof(type) + sizeof(sec) + sizeof(msec) + + sizeof(filenamelen) + ntohs(filenamelen); + *buf = malloc(recsize); + if (*buf == NULL) + return (-1); + bptr = *buf; + + bcopy(&type, bptr, sizeof(type)); + bptr += sizeof(type); + bcopy(&sec, bptr, sizeof(sec)); + bptr += sizeof(sec); + bcopy(&msec, bptr, sizeof(msec)); + bptr += sizeof(msec); + bcopy(&filenamelen, bptr, sizeof(filenamelen)); + bptr += sizeof(filenamelen); + + if (fread(bptr, 1, ntohs(filenamelen), fp) < + ntohs(filenamelen)) { + free(buf); + errno = EINVAL; + return (-1); + } + break; + + default: + errno = EINVAL; + return (-1); + } + + return (recsize); +} diff --git a/contrib/openbsm/libbsm/bsm_mask.c b/contrib/openbsm/libbsm/bsm_mask.c new file mode 100644 index 0000000..42e4e71 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_mask.c @@ -0,0 +1,212 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2005 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <sys/types.h> + +#include <config/config.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 <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; + +/* + * XXX ev_cache, once created, sticks around until the calling program exits. + * This may or may not be a problem as far as absolute memory usage goes, but + * at least there don't appear to be any leaks in using the cache. + * + * XXXRW: Note that despite (mutex), load_event_table() could race with + * other consumers of the getauevents() API. + */ +struct audit_event_map { + char ev_name[AU_EVENT_NAME_MAX]; + char ev_desc[AU_EVENT_DESC_MAX]; + struct au_event_ent ev; + LIST_ENTRY(audit_event_map) ev_list; +}; +static LIST_HEAD(, audit_event_map) ev_cache; + +static struct audit_event_map * +audit_event_map_alloc(void) +{ + struct audit_event_map *aemp; + + aemp = malloc(sizeof(*aemp)); + if (aemp == NULL) + return (aemp); + bzero(aemp, sizeof(*aemp)); + aemp->ev.ae_name = aemp->ev_name; + aemp->ev.ae_desc = aemp->ev_desc; + return (aemp); +} + +static void +audit_event_map_free(struct audit_event_map *aemp) +{ + + free(aemp); +} + +/* + * When reading into the cache fails, we need to flush the entire cache to + * prevent it from containing some but not all records. + */ +static void +flush_cache(void) +{ + struct audit_event_map *aemp; + + /* XXX: Would assert 'mutex'. */ + + while ((aemp = LIST_FIRST(&ev_cache)) != NULL) { + LIST_REMOVE(aemp, ev_list); + audit_event_map_free(aemp); + } +} + +static int +load_event_table(void) +{ + struct audit_event_map *aemp; + struct au_event_ent *ep; + + /* + * XXX: Would assert 'mutex'. + * Loading of the cache happens only once; dont check if cache is + * already loaded. + */ + LIST_INIT(&ev_cache); + setauevent(); /* Rewind to beginning of entries. */ + do { + aemp = audit_event_map_alloc(); + if (aemp == NULL) { + flush_cache(); + return (-1); + } + ep = getauevent_r(&aemp->ev); + if (ep != NULL) + LIST_INSERT_HEAD(&ev_cache, aemp, ev_list); + else + audit_event_map_free(aemp); + } while (ep != NULL); + return (1); +} + +/* + * Read the event with the matching event number from the cache. + */ +static struct au_event_ent * +read_from_cache(au_event_t event) +{ + struct audit_event_map *elem; + + /* XXX: Would assert 'mutex'. */ + + LIST_FOREACH(elem, &ev_cache, ev_list) { + if (elem->ev.ae_number == event) + return (&elem->ev); + } + + return (NULL); +} + +/* + * Check if the audit event is preselected against the preselection mask. + */ +int +au_preselect(au_event_t event, au_mask_t *mask_p, int sorf, int flag) +{ + struct au_event_ent *ev; + au_class_t effmask = 0; + + if (mask_p == NULL) + 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); + } + } + switch (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); + break; + case AU_PRS_USECACHE: + ev = read_from_cache(event); + break; + default: + 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/contrib/openbsm/libbsm/bsm_notify.c b/contrib/openbsm/libbsm/bsm_notify.c new file mode 100644 index 0000000..a2dda74 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_notify.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2004-2009 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. + */ + +/* + * Based on sample code from Marc Majka. + */ +#include <sys/types.h> + +#include <config/config.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 <bsm/audit_internal.h> +#include <bsm/libbsm.h> + +#include <errno.h> +#include <inttypes.h> +#include <stdarg.h> +#include <string.h> +#include <syslog.h> + + +#ifdef __APPLE__ +#include <notify.h> +/* If 1, assumes a kernel that sends the right notification. */ +#define AUDIT_NOTIFICATION_ENABLED 1 + +#if AUDIT_NOTIFICATION_ENABLED +static int token = 0; +#endif /* AUDIT_NOTIFICATION_ENABLED */ + +static int au_cond = AUC_UNSET; /* <bsm/audit.h> */ + +uint32_t +au_notify_initialize(void) +{ +#if AUDIT_NOTIFICATION_ENABLED + uint32_t status; + int ignore_first; + + status = notify_register_check(__BSM_INTERNAL_NOTIFY_KEY, &token); + if (status != NOTIFY_STATUS_OK) + return (status); + status = notify_check(token, &ignore_first); + if (status != NOTIFY_STATUS_OK) + return (status); +#endif + + if (audit_get_cond(&au_cond) != 0) { + syslog(LOG_ERR, "Initial audit status check failed (%s)", + strerror(errno)); + if (errno == ENOSYS) /* auditon() unimplemented. */ + return (AU_UNIMPL); + return (NOTIFY_STATUS_FAILED); /* Is there a better code? */ + } + return (NOTIFY_STATUS_OK); +} + +int +au_notify_terminate(void) +{ + +#if AUDIT_NOTIFICATION_ENABLED + return ((notify_cancel(token) == NOTIFY_STATUS_OK) ? 0 : -1); +#else + return (0); +#endif +} + +/* + * On error of any notify(3) call, reset 'au_cond' to ensure we re-run + * au_notify_initialize() next time 'round--but assume auditing is on. This + * is a slight performance hit if auditing is off, but at least the system + * will behave correctly. The notification calls are unlikely to fail, + * anyway. + */ +int +au_get_state(void) +{ +#if AUDIT_NOTIFICATION_ENABLED + int did_notify; +#endif + int status; + + /* + * Don't make the client initialize this set of routines, but take the + * slight performance hit by checking ourselves every time. + */ + if (au_cond == AUC_UNSET) { + status = au_notify_initialize(); + if (status != NOTIFY_STATUS_OK) { + if (status == AU_UNIMPL) + return (AU_UNIMPL); + return (AUC_AUDITING); + } else + return (au_cond); + } +#if AUDIT_NOTIFICATION_ENABLED + status = notify_check(token, &did_notify); + if (status != NOTIFY_STATUS_OK) { + au_cond = AUC_UNSET; + return (AUC_AUDITING); + } + + if (did_notify == 0) + return (au_cond); +#endif + + if (audit_get_cond(&au_cond) != 0) { + /* XXX Reset au_cond to AUC_UNSET? */ + syslog(LOG_ERR, "Audit status check failed (%s)", + strerror(errno)); + if (errno == ENOSYS) /* Function unimplemented. */ + return (AU_UNIMPL); + return (errno); + } + + switch (au_cond) { + case AUC_NOAUDIT: /* Auditing suspended. */ + case AUC_DISABLED: /* Auditing shut off. */ + return (AUC_NOAUDIT); + + case AUC_UNSET: /* Uninitialized; shouldn't get here. */ + case AUC_AUDITING: /* Audit on. */ + default: + return (AUC_AUDITING); + } +} +#endif /* !__APPLE__ */ + +int +cannot_audit(int val __unused) +{ +#ifdef __APPLE__ + return (!(au_get_state() == AUC_AUDITING)); +#else + int cond; + + if (audit_get_cond(&cond) != 0) { + if (errno != ENOSYS) { + syslog(LOG_ERR, "Audit status check failed (%s)", + strerror(errno)); + } + return (1); + } + if (cond == AUC_NOAUDIT || cond == AUC_DISABLED) + return (1); + return (0); +#endif /* !__APPLE__ */ +} diff --git a/contrib/openbsm/libbsm/bsm_socket_type.c b/contrib/openbsm/libbsm/bsm_socket_type.c new file mode 100644 index 0000000..ffbe39e --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_socket_type.c @@ -0,0 +1,102 @@ +/*- + * 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. + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <config/config.h> + +#include <bsm/audit_socket_type.h> +#include <bsm/libbsm.h> + +struct bsm_socket_type { + u_short bst_bsm_socket_type; + int bst_local_socket_type; +}; + +#define ST_NO_LOCAL_MAPPING -600 + +static const struct bsm_socket_type bsm_socket_types[] = { + { BSM_SOCK_DGRAM, SOCK_DGRAM }, + { BSM_SOCK_STREAM, SOCK_STREAM }, + { BSM_SOCK_RAW, SOCK_RAW }, + { BSM_SOCK_RDM, SOCK_RDM }, + { BSM_SOCK_SEQPACKET, SOCK_SEQPACKET }, +}; +static const int bsm_socket_types_count = sizeof(bsm_socket_types) / + sizeof(bsm_socket_types[0]); + +static const struct bsm_socket_type * +bsm_lookup_local_socket_type(int local_socket_type) +{ + int i; + + for (i = 0; i < bsm_socket_types_count; i++) { + if (bsm_socket_types[i].bst_local_socket_type == + local_socket_type) + return (&bsm_socket_types[i]); + } + return (NULL); +} + +u_short +au_socket_type_to_bsm(int local_socket_type) +{ + const struct bsm_socket_type *bstp; + + bstp = bsm_lookup_local_socket_type(local_socket_type); + if (bstp == NULL) + return (BSM_SOCK_UNKNOWN); + return (bstp->bst_bsm_socket_type); +} + +static const struct bsm_socket_type * +bsm_lookup_bsm_socket_type(u_short bsm_socket_type) +{ + int i; + + for (i = 0; i < bsm_socket_types_count; i++) { + if (bsm_socket_types[i].bst_bsm_socket_type == + bsm_socket_type) + return (&bsm_socket_types[i]); + } + return (NULL); +} + +int +au_bsm_to_socket_type(u_short bsm_socket_type, int *local_socket_typep) +{ + const struct bsm_socket_type *bstp; + + bstp = bsm_lookup_bsm_socket_type(bsm_socket_type); + if (bstp == NULL || bstp->bst_local_socket_type) + return (-1); + *local_socket_typep = bstp->bst_local_socket_type; + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_token.c b/contrib/openbsm/libbsm/bsm_token.c new file mode 100644 index 0000000..682836f --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_token.c @@ -0,0 +1,1645 @@ +/*- + * Copyright (c) 2004-2009 Apple Inc. + * Copyright (c) 2005 SPARTA, Inc. + * All rights reserved. + * + * This code was developed in part by Robert N. M. Watson, Senior Principal + * Scientist, SPARTA, Inc. + * + * 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. + */ + +#include <sys/types.h> + +#include <config/config.h> + +#ifdef USE_ENDIAN_H +#include <endian.h> +#endif +#ifdef USE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif +#ifdef USE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#endif +#ifdef USE_COMPAT_ENDIAN_H +#include <compat/endian.h> +#endif +#ifdef USE_COMPAT_ENDIAN_ENC_H +#include <compat/endian_enc.h> +#endif + +#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/socket.h> +#include <sys/time.h> +#include <sys/un.h> + +#include <sys/ipc.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#include <bsm/audit_internal.h> +#include <bsm/libbsm.h> + +#define GET_TOKEN_AREA(t, dptr, length) do { \ + (t) = malloc(sizeof(token_t)); \ + if ((t) != NULL) { \ + (t)->len = (length); \ + (dptr) = (t->t_data) = calloc((length), sizeof(u_char)); \ + if ((dptr) == NULL) { \ + free(t); \ + (t) = NULL; \ + } \ + } else \ + (dptr) = NULL; \ + assert((t) == NULL || (dptr) != NULL); \ +} while (0) + +/* + * token ID 1 byte + * success/failure 1 byte + * privstrlen 2 bytes + * privstr N bytes + 1 (\0 byte) + */ +token_t * +au_to_upriv(char sorf, char *priv) +{ + u_int16_t textlen; + u_char *dptr; + token_t *t; + + textlen = strlen(priv) + 1; + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) + + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + ADD_U_CHAR(dptr, AUT_UPRIV); + ADD_U_CHAR(dptr, sorf); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, priv, textlen); + return (t); +} + +/* + * token ID 1 byte + * privtstrlen 2 bytes + * privtstr N bytes + 1 + * privstrlen 2 bytes + * privstr N bytes + 1 + */ +token_t * +au_to_privset(char *privtypestr, char *privstr) +{ + u_int16_t type_len, priv_len; + u_char *dptr; + token_t *t; + + type_len = strlen(privtypestr) + 1; + priv_len = strlen(privstr) + 1; + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + + sizeof(u_int16_t) + type_len + priv_len); + if (t == NULL) + return (NULL); + ADD_U_CHAR(dptr, AUT_PRIV); + ADD_U_INT16(dptr, type_len); + ADD_STRING(dptr, privtypestr, type_len); + ADD_U_INT16(dptr, priv_len); + ADD_STRING(dptr, privstr, priv_len); + return (t); +} + +/* + * token ID 1 byte + * argument # 1 byte + * argument value 4 bytes/8 bytes (32-bit/64-bit value) + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +token_t * +au_to_arg32(char n, const char *text, u_int32_t v) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ARG32); + ADD_U_CHAR(dptr, n); + ADD_U_INT32(dptr, v); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +token_t * +au_to_arg64(char n, const char *text, u_int64_t v) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ARG64); + ADD_U_CHAR(dptr, n); + ADD_U_INT64(dptr, v); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +token_t * +au_to_arg(char n, const char *text, u_int32_t v) +{ + + return (au_to_arg32(n, text, v)); +} + +#if defined(_KERNEL) || defined(KERNEL) +/* + * token ID 1 byte + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +token_t * +au_to_attr32(struct vnode_au_info *vni) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t pad0_16 = 0; + u_int32_t pad0_32 = 0; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + + 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ATTR32); + + /* + * 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); + + ADD_U_INT32(dptr, vni->vn_uid); + ADD_U_INT32(dptr, vni->vn_gid); + ADD_U_INT32(dptr, vni->vn_fsid); + + /* + * Some systems use 32-bit file ID's, others use 64-bit file IDs. + * Attempt to handle both, and let the compiler sort it out. If we + * could pick this out at compile-time, it would be better, so as to + * avoid the else case below. + */ + if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { + ADD_U_INT32(dptr, pad0_32); + ADD_U_INT32(dptr, vni->vn_fileid); + } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) + ADD_U_INT64(dptr, vni->vn_fileid); + else + ADD_U_INT64(dptr, 0LL); + + ADD_U_INT32(dptr, vni->vn_dev); + + return (t); +} + +token_t * +au_to_attr64(struct vnode_au_info *vni) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t pad0_16 = 0; + u_int32_t pad0_32 = 0; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + + 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ATTR64); + + /* + * 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); + + ADD_U_INT32(dptr, vni->vn_uid); + ADD_U_INT32(dptr, vni->vn_gid); + ADD_U_INT32(dptr, vni->vn_fsid); + + /* + * Some systems use 32-bit file ID's, other's use 64-bit file IDs. + * Attempt to handle both, and let the compiler sort it out. If we + * could pick this out at compile-time, it would be better, so as to + * avoid the else case below. + */ + if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { + ADD_U_INT32(dptr, pad0_32); + ADD_U_INT32(dptr, vni->vn_fileid); + } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) + ADD_U_INT64(dptr, vni->vn_fileid); + else + ADD_U_INT64(dptr, 0LL); + + ADD_U_INT64(dptr, vni->vn_dev); + + return (t); +} + +token_t * +au_to_attr(struct vnode_au_info *vni) +{ + + return (au_to_attr32(vni)); +} +#endif /* !(defined(_KERNEL) || defined(KERNEL) */ + +/* + * token ID 1 byte + * how to print 1 byte + * basic unit 1 byte + * unit count 1 byte + * data items (depends on basic unit) + */ +token_t * +au_to_data(char unit_print, char unit_type, char unit_count, const char *p) +{ + token_t *t; + u_char *dptr = NULL; + size_t datasize, totdata; + + /* Determine the size of the basic unit. */ + switch (unit_type) { + case AUR_BYTE: + /* case AUR_CHAR: */ + datasize = AUR_BYTE_SIZE; + break; + + case AUR_SHORT: + datasize = AUR_SHORT_SIZE; + break; + + case AUR_INT32: + /* case AUR_INT: */ + datasize = AUR_INT32_SIZE; + break; + + case AUR_INT64: + datasize = AUR_INT64_SIZE; + break; + + default: + errno = EINVAL; + return (NULL); + } + + totdata = datasize * unit_count; + + GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata); + 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); + ADD_U_CHAR(dptr, unit_count); + ADD_MEM(dptr, p, totdata); + + return (t); +} + + +/* + * token ID 1 byte + * status 4 bytes + * return value 4 bytes + */ +token_t * +au_to_exit(int retval, int err) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXIT); + ADD_U_INT32(dptr, err); + ADD_U_INT32(dptr, retval); + + return (t); +} + +/* + */ +token_t * +au_to_groups(int *groups) +{ + + return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups)); +} + +/* + * token ID 1 byte + * number groups 2 bytes + * group list count * 4 bytes + */ +token_t * +au_to_newgroups(u_int16_t n, gid_t *groups) +{ + token_t *t; + u_char *dptr = NULL; + int i; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + + n * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_NEWGROUPS); + ADD_U_INT16(dptr, n); + for (i = 0; i < n; i++) + ADD_U_INT32(dptr, groups[i]); + + return (t); +} + +/* + * token ID 1 byte + * internet address 4 bytes + */ +token_t * +au_to_in_addr(struct in_addr *internet_addr) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IN_ADDR); + ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t)); + + return (t); +} + +/* + * token ID 1 byte + * address type/length 4 bytes + * address 16 bytes + */ +token_t * +au_to_in_addr_ex(struct in6_addr *internet_addr) +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t type = AU_IPv6; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); + ADD_U_INT32(dptr, type); + ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t)); + + return (t); +} + +/* + * token ID 1 byte + * ip header 20 bytes + * + * The IP header should be submitted in network byte order. + */ +token_t * +au_to_ip(struct ip *ip) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IP); + ADD_MEM(dptr, ip, sizeof(struct ip)); + + return (t); +} + +/* + * token ID 1 byte + * object ID type 1 byte + * object ID 4 bytes + */ +token_t * +au_to_ipc(char type, int id) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPC); + ADD_U_CHAR(dptr, type); + ADD_U_INT32(dptr, id); + + return (t); +} + +/* + * token ID 1 byte + * owner user ID 4 bytes + * owner group ID 4 bytes + * creator user ID 4 bytes + * creator group ID 4 bytes + * access mode 4 bytes + * slot sequence # 4 bytes + * key 4 bytes + */ +token_t * +au_to_ipc_perm(struct ipc_perm *perm) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t pad0 = 0; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) + + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPC_PERM); + + /* + * 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. + */ + 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); + + ADD_U_INT16(dptr, pad0); + +#ifdef HAVE_IPC_PERM___SEQ + ADD_U_INT16(dptr, perm->__seq); +#else /* HAVE_IPC_PERM___SEQ */ +#ifdef HAVE_IPC_PERM__SEQ + ADD_U_INT16(dptr, perm->_seq); +#else /* HAVE_IPC_PERM__SEQ */ + ADD_U_INT16(dptr, perm->seq); +#endif /* HAVE_IPC_PERM__SEQ */ +#endif /* HAVE_IPC_PERM___SEQ */ + +#ifdef HAVE_IPC_PERM___KEY + ADD_U_INT32(dptr, perm->__key); +#else /* HAVE_IPC_PERM___KEY */ +#ifdef HAVE_IPC_PERM__KEY + ADD_U_INT32(dptr, perm->_key); +#else /* HAVE_IPC_PERM__KEY */ + ADD_U_INT32(dptr, perm->key); +#endif /* HAVE_IPC_PERM__KEY */ +#endif /* HAVE_IPC_PERM___KEY */ + + return (t); +} + +/* + * token ID 1 byte + * port IP address 2 bytes + */ +token_t * +au_to_iport(u_int16_t iport) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPORT); + ADD_U_INT16(dptr, iport); + + return (t); +} + +/* + * token ID 1 byte + * size 2 bytes + * data size bytes + */ +token_t * +au_to_opaque(const char *data, u_int16_t bytes) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_OPAQUE); + ADD_U_INT16(dptr, bytes); + ADD_MEM(dptr, data, bytes); + + return (t); +} + +/* + * token ID 1 byte + * seconds of time 4 bytes + * milliseconds of time 4 bytes + * file name len 2 bytes + * file pathname N bytes + 1 terminating NULL byte + */ +token_t * +au_to_file(const char *file, struct timeval tm) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t filelen; + u_int32_t timems; + + filelen = strlen(file); + filelen += 1; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + + sizeof(u_int16_t) + filelen); + if (t == NULL) + return (NULL); + + timems = tm.tv_usec/1000; + + ADD_U_CHAR(dptr, AUT_OTHER_FILE32); + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + ADD_U_INT16(dptr, filelen); + ADD_STRING(dptr, file, filelen); + + return (t); +} + +/* + * token ID 1 byte + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +token_t * +au_to_text(const char *text) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + 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); + + ADD_U_CHAR(dptr, AUT_TEXT); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +/* + * token ID 1 byte + * path length 2 bytes + * path N bytes + 1 terminating NULL byte + */ +token_t * +au_to_path(const char *text) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PATH); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +token_t * +au_to_process32(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_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS32); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, 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); +} + +token_t * +au_to_process64(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_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) + + sizeof(u_int64_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS64); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, 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); +} + +token_t * +au_to_process(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_t *tid) +{ + + return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * address type-len 4 bytes + * machine address 16 bytes + */ +token_t * +au_to_process32_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) +{ + token_t *t; + u_char *dptr = NULL; + + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 10 * sizeof(u_int32_t)); + else if (tid->at_type == AU_IPv6) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 13 * sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS32_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + if (tid->at_type == AU_IPv6) { + ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); + } + + return (t); +} + +token_t * +au_to_process64_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) +{ + token_t *t; + u_char *dptr = NULL; + + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + + 2 * sizeof(u_int32_t)); + else if (tid->at_type == AU_IPv6) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + + 5 * sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS64_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT64(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + if (tid->at_type == AU_IPv6) { + ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t)); + ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t)); + } + + return (t); +} + +token_t * +au_to_process_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) +{ + + return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * token ID 1 byte + * error status 1 byte + * return value 4 bytes/8 bytes (32-bit/64-bit value) + */ +token_t * +au_to_return32(char status, u_int32_t ret) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_RETURN32); + ADD_U_CHAR(dptr, status); + ADD_U_INT32(dptr, ret); + + return (t); +} + +token_t * +au_to_return64(char status, u_int64_t ret) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_RETURN64); + ADD_U_CHAR(dptr, status); + ADD_U_INT64(dptr, ret); + + return (t); +} + +token_t * +au_to_return(char status, u_int32_t ret) +{ + + return (au_to_return32(status, ret)); +} + +/* + * token ID 1 byte + * sequence number 4 bytes + */ +token_t * +au_to_seq(long audit_count) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SEQ); + ADD_U_INT32(dptr, audit_count); + + return (t); +} + +/* + * 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) + * + * Domain and type arguments to this routine are assumed to already have been + * converted to the BSM constant space, so we don't do that here. + */ +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) + 8 * sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKET_EX); + ADD_U_INT16(dptr, au_domain_to_bsm(so_domain)); + ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type)); + 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 (up to) 104 bytes + NULL (NULL terminated string) + */ +token_t * +au_to_sock_unix(struct sockaddr_un *so) +{ + token_t *t; + u_char *dptr; + + GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKUNIX); + /* BSM token has two bytes for family */ + ADD_U_CHAR(dptr, 0); + ADD_U_CHAR(dptr, so->sun_family); + ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); + + return (t); +} + +/* + * token ID 1 byte + * socket family 2 bytes + * local port 2 bytes + * socket address 4 bytes + */ +token_t * +au_to_sock_inet32(struct sockaddr_in *so) +{ + token_t *t; + u_char *dptr = NULL; + uint16_t family; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) + + sizeof(uint32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKINET32); + /* + * BSM defines the family field as 16 bits, but many operating + * systems have an 8-bit sin_family field. Extend to 16 bits before + * writing into the token. Assume that both the port and the address + * in the sockaddr_in are already in network byte order, but family + * is in local byte order. + * + * XXXRW: Should a name space conversion be taking place on the value + * of sin_family? + */ + family = so->sin_family; + ADD_U_INT16(dptr, family); + ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t)); + ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); + + return (t); +} + +token_t * +au_to_sock_inet128(struct sockaddr_in6 *so) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + + 4 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKINET128); + /* + * 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); + + ADD_U_INT16(dptr, so->sin6_port); + ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); + + return (t); +} + +token_t * +au_to_sock_inet(struct sockaddr_in *so) +{ + + return (au_to_sock_inet32(so)); +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +token_t * +au_to_subject32(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_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT32); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->port); + ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); + + return (t); +} + +token_t * +au_to_subject64(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_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) + + sizeof(u_int64_t) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT64); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT64(dptr, tid->port); + ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); + + return (t); +} + +token_t * +au_to_subject(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_t *tid) +{ + + return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes/8 bytes (32-bit/64-bit value) + * address type/length 4 bytes + * machine address 16 bytes + */ +token_t * +au_to_subject32_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) +{ + token_t *t; + u_char *dptr = NULL; + + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * + sizeof(u_int32_t)); + else if (tid->at_type == AU_IPv6) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * + sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + if (tid->at_type == AU_IPv6) + ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); + else + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + + return (t); +} + +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) +{ + token_t *t; + u_char *dptr = NULL; + + if (tid->at_type == AU_IPv4) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + + 2 * sizeof(u_int32_t)); + else if (tid->at_type == AU_IPv6) + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + + 7 * sizeof(u_int32_t) + sizeof(u_int64_t) + + 5 * sizeof(u_int32_t)); + else { + errno = EINVAL; + return (NULL); + } + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT64_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT64(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + if (tid->at_type == AU_IPv6) + ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); + else + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + + return (t); +} + +token_t * +au_to_subject_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) +{ + + return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS) +/* + * Collects audit information for the current process and creates a subject + * token from it. + */ +token_t * +au_to_me(void) +{ + auditinfo_t auinfo; + auditinfo_addr_t aia; + + /* + * Try to use getaudit_addr(2) first. If this kernel does not support + * it, then fall back on to getaudit(2). + */ + if (getaudit_addr(&aia, sizeof(aia)) != 0) { + if (errno == ENOSYS) { + if (getaudit(&auinfo) != 0) + return (NULL); + return (au_to_subject32(auinfo.ai_auid, geteuid(), + getegid(), getuid(), getgid(), getpid(), + auinfo.ai_asid, &auinfo.ai_termid)); + } else { + /* getaudit_addr(2) failed for some other reason. */ + return (NULL); + } + } + + return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(), + getgid(), getpid(), aia.ai_asid, &aia.ai_termid)); +} +#endif + +/* + * token ID 1 byte + * count 4 bytes + * text count null-terminated strings + */ +token_t * +au_to_exec_args(char **argv) +{ + token_t *t; + u_char *dptr = NULL; + const char *nextarg; + int i, count = 0; + size_t totlen = 0; + + nextarg = *argv; + + while (nextarg != NULL) { + int nextlen; + + nextlen = strlen(nextarg); + totlen += nextlen + 1; + count++; + nextarg = *(argv + count); + } + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXEC_ARGS); + ADD_U_INT32(dptr, count); + + for (i = 0; i < count; i++) { + nextarg = *(argv + i); + ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); + } + + return (t); +} + +/* + * token ID 1 byte + * count 4 bytes + * text count null-terminated strings + */ +token_t * +au_to_exec_env(char **envp) +{ + token_t *t; + u_char *dptr = NULL; + int i, count = 0; + size_t totlen = 0; + const char *nextenv; + + nextenv = *envp; + + while (nextenv != NULL) { + int nextlen; + + nextlen = strlen(nextenv); + totlen += nextlen + 1; + count++; + nextenv = *(envp + count); + } + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXEC_ENV); + ADD_U_INT32(dptr, count); + + for (i = 0; i < count; i++) { + nextenv = *(envp + i); + ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); + } + + return (t); +} + +/* + * 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 + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +token_t * +au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm) +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t timems; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_HEADER32); + ADD_U_INT32(dptr, rec_size); + ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); + ADD_U_INT16(dptr, e_type); + ADD_U_INT16(dptr, e_mod); + + timems = tm.tv_usec/1000; + /* Add the timestamp */ + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + + return (t); +} + +/* + * token ID 1 byte + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +token_t * +au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm, struct auditinfo_addr *aia) +{ + token_t *t; + u_char *dptr = NULL; + 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) + + sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 * + sizeof(u_int32_t) + tid->at_type); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_HEADER32_EX); + ADD_U_INT32(dptr, rec_size); + ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); + ADD_U_INT16(dptr, e_type); + ADD_U_INT16(dptr, e_mod); + + ADD_U_INT32(dptr, tid->at_type); + if (tid->at_type == AU_IPv6) + ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t)); + else + ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t)); + timems = tm.tv_usec/1000; + /* Add the timestamp */ + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + + return (t); +} + +token_t * +au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm) +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t timems; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_HEADER64); + ADD_U_INT32(dptr, rec_size); + ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM); + ADD_U_INT16(dptr, e_type); + ADD_U_INT16(dptr, e_mod); + + timems = tm.tv_usec/1000; + /* Add the timestamp */ + ADD_U_INT64(dptr, tm.tv_sec); + ADD_U_INT64(dptr, timems); /* We need time in ms. */ + + return (t); +} + +#if !defined(KERNEL) && !defined(_KERNEL) +#ifdef HAVE_AUDIT_SYSCALLS +token_t * +au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + struct timeval tm; + struct auditinfo_addr aia; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + if (audit_get_kaudit(&aia, sizeof(aia)) != 0) { + if (errno != ENOSYS) + return (NULL); + return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); + } + return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia)); +} +#endif /* HAVE_AUDIT_SYSCALLS */ + +token_t * +au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + struct timeval tm; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); +} + +token_t * +au_to_header64(__unused int rec_size, __unused au_event_t e_type, + __unused au_emod_t e_mod) +{ + struct timeval tm; + + if (gettimeofday(&tm, NULL) == -1) + return (NULL); + return (au_to_header64_tm(rec_size, e_type, e_mod, tm)); +} + +token_t * +au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + + return (au_to_header32(rec_size, e_type, e_mod)); +} + +#ifdef HAVE_AUDIT_SYSCALLS +token_t * +au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + + return (au_to_header32_ex(rec_size, e_type, e_mod)); +} +#endif /* HAVE_AUDIT_SYSCALLS */ +#endif /* !defined(KERNEL) && !defined(_KERNEL) */ + +/* + * token ID 1 byte + * trailer magic number 2 bytes + * record byte count 4 bytes + */ +token_t * +au_to_trailer(int rec_size) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t magic = AUT_TRAILER_MAGIC; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_TRAILER); + ADD_U_INT16(dptr, magic); + ADD_U_INT32(dptr, rec_size); + + return (t); +} diff --git a/contrib/openbsm/libbsm/bsm_user.c b/contrib/openbsm/libbsm/bsm_user.c new file mode 100644 index 0000000..5b48070 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_user.c @@ -0,0 +1,294 @@ +/*- + * Copyright (c) 2004 Apple Inc. + * Copyright (c) 2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +#include <config/config.h> + +#include <bsm/libbsm.h> + +#include <string.h> +#ifdef HAVE_PTHREAD_MUTEX_LOCK +#include <pthread.h> +#endif +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_STRLCPY +#include <compat/strlcpy.h> +#endif + +/* + * Parse the contents of the audit_user file into au_user_ent structures. + */ + +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. + */ +static struct au_user_ent * +userfromstr(char *str, struct au_user_ent *u) +{ + char *username, *always, *never; + char *last; + + username = strtok_r(str, user_delim, &last); + always = strtok_r(NULL, user_delim, &last); + never = strtok_r(NULL, user_delim, &last); + + if ((username == NULL) || (always == NULL) || (never == NULL)) + return (NULL); + + if (strlen(username) >= AU_USER_NAME_MAX) + return (NULL); + + strlcpy(u->au_name, username, AU_USER_NAME_MAX); + if (getauditflagsbin(always, &(u->au_always)) == -1) + return (NULL); + + if (getauditflagsbin(never, &(u->au_never)) == -1) + return (NULL); + + return (u); +} + +/* + * Rewind to beginning of the file + */ +static void +setauuser_locked(void) +{ + + if (fp != NULL) + fseek(fp, 0, SEEK_SET); +} + +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 +} + +/* + * Close the file descriptor + */ +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 +} + +/* + * Enumerate the au_user_ent structures from the file + */ +static struct au_user_ent * +getauuserent_r_locked(struct au_user_ent *u) +{ + char *nl; + + if ((fp == NULL) && ((fp = fopen(AUDIT_USER_FILE, "r")) == NULL)) + return (NULL); + + while (1) { + if (fgets(linestr, AU_LINE_MAX, fp) == NULL) + return (NULL); + + /* Remove new lines. */ + if ((nl = strrchr(linestr, '\n')) != NULL) + *nl = '\0'; + + /* Skip comments. */ + if (linestr[0] == '#') + continue; + + /* Get the next structure. */ + if (userfromstr(linestr, u) == NULL) + return (NULL); + break; + } + + return (u); +} + +struct au_user_ent * +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); +} + +struct au_user_ent * +getauuserent(void) +{ + static char user_ent_name[AU_USER_NAME_MAX]; + static struct au_user_ent u; + + bzero(&u, sizeof(u)); + bzero(user_ent_name, sizeof(user_ent_name)); + u.au_name = user_ent_name; + + return (getauuserent_r(&u)); +} + +/* + * Find a au_user_ent structure matching the given user name. + */ +struct au_user_ent * +getauusernam_r(struct au_user_ent *u, const char *name) +{ + struct au_user_ent *up; + + 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 (up); + } + } + +#ifdef HAVE_PTHREAD_MUTEX_LOCK + pthread_mutex_unlock(&mutex); +#endif + return (NULL); + +} + +struct au_user_ent * +getauusernam(const char *name) +{ + static char user_ent_name[AU_USER_NAME_MAX]; + static struct au_user_ent u; + + bzero(&u, sizeof(u)); + bzero(user_ent_name, sizeof(user_ent_name)); + u.au_name = user_ent_name; + + return (getauusernam_r(&u, name)); +} + +/* + * Read the default system wide audit classes from audit_control, combine with + * the per-user audit class and update the binary preselection mask. + */ +int +au_user_mask(char *username, au_mask_t *mask_p) +{ + char auditstring[MAX_AUDITSTRING_LEN + 1]; + char user_ent_name[AU_USER_NAME_MAX]; + struct au_user_ent u, *up; + + bzero(&u, sizeof(u)); + bzero(user_ent_name, sizeof(user_ent_name)); + u.au_name = user_ent_name; + + /* Get user mask. */ + if ((up = getauusernam_r(&u, username)) != NULL) { + if (-1 == getfauditflags(&up->au_always, &up->au_never, + mask_p)) + return (-1); + return (0); + } + + /* Read the default system mask. */ + if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { + if (-1 == getauditflagsbin(auditstring, mask_p)) + return (-1); + return (0); + } + + /* No masks defined. */ + return (-1); +} + +/* + * Generate the process audit state by combining the audit masks passed as + * parameters with the system audit masks. + */ +int +getfauditflags(au_mask_t *usremask, au_mask_t *usrdmask, au_mask_t *lastmask) +{ + char auditstring[MAX_AUDITSTRING_LEN + 1]; + + if ((usremask == NULL) || (usrdmask == NULL) || (lastmask == NULL)) + return (-1); + + lastmask->am_success = 0; + lastmask->am_failure = 0; + + /* Get the system mask. */ + if (getacflg(auditstring, MAX_AUDITSTRING_LEN) == 0) { + if (getauditflagsbin(auditstring, lastmask) != 0) + return (-1); + } + + ADDMASK(lastmask, usremask); + SUBMASK(lastmask, usrdmask); + + return (0); +} diff --git a/contrib/openbsm/libbsm/bsm_wrappers.c b/contrib/openbsm/libbsm/bsm_wrappers.c new file mode 100644 index 0000000..01daaf1 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_wrappers.c @@ -0,0 +1,821 @@ +/*- + * Copyright (c) 2004-2009 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. + */ + +#ifdef __APPLE__ +#define _SYS_AUDIT_H /* Prevent include of sys/audit.h. */ +#endif + +#include <sys/param.h> +#include <sys/stat.h> + +#ifdef __APPLE__ +#include <sys/queue.h> /* Our bsm/audit.h doesn't include queue.h. */ +#endif + +#include <sys/sysctl.h> + +#include <bsm/libbsm.h> + +#include <unistd.h> +#include <syslog.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> + +/* These are not advertised in libbsm.h */ +int audit_set_terminal_port(dev_t *p); +int audit_set_terminal_host(uint32_t *m); + +/* + * General purpose audit submission mechanism for userspace. + */ +int +audit_submit(short au_event, au_id_t auid, char status, + int reterr, const char *fmt, ...) +{ + char text[MAX_AUDITSTRING_LEN]; + token_t *token; + int acond; + va_list ap; + pid_t pid; + int error, afd, subj_ex; + struct auditinfo ai; + struct auditinfo_addr aia; + au_tid_t atid; + + if (audit_get_cond(&acond) != 0) { + /* + * If auditon(2) returns ENOSYS, then audit has not been + * compiled into the kernel, so just return. + */ + if (errno == ENOSYS) + return (0); + error = errno; + syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s", + strerror(errno)); + errno = error; + return (-1); + } + if (acond == AUC_NOAUDIT) + return (0); + afd = au_open(); + if (afd < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, "audit: au_open failed: %s", + strerror(errno)); + errno = error; + return (-1); + } + /* + * 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_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_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) { + 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, &atid); + } else + token = au_to_subject_ex(auid, geteuid(), getegid(), + getuid(), getgid(), pid, pid, &aia.ai_termid); + if (token == NULL) { + syslog(LOG_AUTH | LOG_ERR, + "audit: unable to build subject token"); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = EPERM; + return (-1); + } + if (au_write(afd, token) < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, + "audit: au_write failed: %s", strerror(errno)); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = error; + return (-1); + } + if (fmt != NULL) { + va_start(ap, fmt); + (void) vsnprintf(text, MAX_AUDITSTRING_LEN, fmt, ap); + va_end(ap); + token = au_to_text(text); + if (token == NULL) { + syslog(LOG_AUTH | LOG_ERR, + "audit: failed to generate text token"); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = EPERM; + return (-1); + } + if (au_write(afd, token) < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, + "audit: au_write failed: %s", strerror(errno)); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = error; + return (-1); + } + } + token = au_to_return32(au_errno_to_bsm(status), reterr); + if (token == NULL) { + syslog(LOG_AUTH | LOG_ERR, + "audit: unable to build return token"); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = EPERM; + return (-1); + } + if (au_write(afd, token) < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, + "audit: au_write failed: %s", strerror(errno)); + (void) au_close(afd, AU_TO_NO_WRITE, au_event); + errno = error; + return (-1); + } + if (au_close(afd, AU_TO_WRITE, au_event) < 0) { + error = errno; + syslog(LOG_AUTH | LOG_ERR, "audit: record not committed"); + errno = error; + return (-1); + } + return (0); +} + +int +audit_set_terminal_port(dev_t *p) +{ + struct stat st; + + if (p == NULL) + return (kAUBadParamErr); + +#ifdef NODEV + *p = NODEV; +#else + *p = -1; +#endif + + /* for /usr/bin/login, try fstat() first */ + if (fstat(STDIN_FILENO, &st) != 0) { + if (errno != EBADF) { + syslog(LOG_ERR, "fstat() failed (%s)", + strerror(errno)); + return (kAUStatErr); + } + if (stat("/dev/console", &st) != 0) { + syslog(LOG_ERR, "stat() failed (%s)", + strerror(errno)); + return (kAUStatErr); + } + } + *p = st.st_rdev; + return (kAUNoErr); +} + +int +audit_set_terminal_host(uint32_t *m) +{ + +#ifdef KERN_HOSTID + int name[2] = { CTL_KERN, KERN_HOSTID }; + size_t len; + + if (m == NULL) + return (kAUBadParamErr); + *m = 0; + len = sizeof(*m); + if (sysctl(name, 2, m, &len, NULL, 0) != 0) { + syslog(LOG_ERR, "sysctl() failed (%s)", strerror(errno)); + return (kAUSysctlErr); + } + return (kAUNoErr); +#else + *m = -1; + return (kAUNoErr); +#endif +} + +int +audit_set_terminal_id(au_tid_t *tid) +{ + int ret; + + if (tid == NULL) + return (kAUBadParamErr); + if ((ret = audit_set_terminal_port(&tid->port)) != kAUNoErr) + return (ret); + return (audit_set_terminal_host(&tid->machine)); +} + +/* + * This is OK for those callers who have only one token to write. If you have + * multiple tokens that logically form part of the same audit record, you need + * to use the existing au_open()/au_write()/au_close() API: + * + * aufd = au_open(); + * tok = au_to_random_token_1(...); + * au_write(aufd, tok); + * tok = au_to_random_token_2(...); + * au_write(aufd, tok); + * ... + * au_close(aufd, AU_TO_WRITE, AUE_your_event_type); + * + * Assumes, like all wrapper calls, that the caller has previously checked + * that auditing is enabled via the audit_get_state() call. + * + * XXX: Should be more robust against bad arguments. + */ +int +audit_write(short event_code, token_t *subject, token_t *misctok, char retval, + int errcode) +{ + int aufd; + char *func = "audit_write()"; + token_t *rettok; + + if ((aufd = au_open()) == -1) { + au_free_token(subject); + au_free_token(misctok); + syslog(LOG_ERR, "%s: au_open() failed", func); + return (kAUOpenErr); + } + + /* Save subject. */ + if (subject && au_write(aufd, subject) == -1) { + au_free_token(subject); + au_free_token(misctok); + (void)au_close(aufd, AU_TO_NO_WRITE, event_code); + syslog(LOG_ERR, "%s: write of subject failed", func); + return (kAUWriteSubjectTokErr); + } + + /* Save the event-specific token. */ + if (misctok && au_write(aufd, misctok) == -1) { + au_free_token(misctok); + (void)au_close(aufd, AU_TO_NO_WRITE, event_code); + syslog(LOG_ERR, "%s: write of caller token failed", func); + return (kAUWriteCallerTokErr); + } + + /* Tokenize and save the return value. */ + if ((rettok = au_to_return32(retval, errcode)) == NULL) { + (void)au_close(aufd, AU_TO_NO_WRITE, event_code); + syslog(LOG_ERR, "%s: au_to_return32() failed", func); + return (kAUMakeReturnTokErr); + } + + if (au_write(aufd, rettok) == -1) { + au_free_token(rettok); + (void)au_close(aufd, AU_TO_NO_WRITE, event_code); + syslog(LOG_ERR, "%s: write of return code failed", func); + return (kAUWriteReturnTokErr); + } + + /* + * We assume the caller wouldn't have bothered with this + * function if it hadn't already decided to keep the record. + */ + if (au_close(aufd, AU_TO_WRITE, event_code) < 0) { + syslog(LOG_ERR, "%s: au_close() failed", func); + return (kAUCloseErr); + } + + return (kAUNoErr); +} + +/* + * Same caveats as audit_write(). In addition, this function explicitly + * assumes success; use audit_write_failure() on error. + */ +int +audit_write_success(short event_code, token_t *tok, 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_t *tid) +{ + char *func = "audit_write_success()"; + token_t *subject = NULL; + + /* Tokenize and save subject. */ + subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, + tid); + if (subject == NULL) { + syslog(LOG_ERR, "%s: au_to_subject32() failed", func); + return kAUMakeSubjectTokErr; + } + + return (audit_write(event_code, subject, tok, 0, 0)); +} + +/* + * Same caveats as audit_write(). In addition, this function explicitly + * assumes success; use audit_write_failure_self() on error. + */ +int +audit_write_success_self(short event_code, token_t *tok) +{ + token_t *subject; + char *func = "audit_write_success_self()"; + + if ((subject = au_to_me()) == NULL) { + syslog(LOG_ERR, "%s: au_to_me() failed", func); + return (kAUMakeSubjectTokErr); + } + + return (audit_write(event_code, subject, tok, 0, 0)); +} + +/* + * Same caveats as audit_write(). In addition, this function explicitly + * assumes failure; use audit_write_success() otherwise. + * + * XXX This should let the caller pass an error return value rather than + * hard-coding -1. + */ +int +audit_write_failure(short event_code, char *errmsg, int errcode, 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_t *tid) +{ + char *func = "audit_write_failure()"; + token_t *subject, *errtok; + + subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, tid); + if (subject == NULL) { + syslog(LOG_ERR, "%s: au_to_subject32() failed", func); + return (kAUMakeSubjectTokErr); + } + + /* tokenize and save the error message */ + if ((errtok = au_to_text(errmsg)) == NULL) { + au_free_token(subject); + syslog(LOG_ERR, "%s: au_to_text() failed", func); + return (kAUMakeTextTokErr); + } + + return (audit_write(event_code, subject, errtok, -1, errcode)); +} + +/* + * Same caveats as audit_write(). In addition, this function explicitly + * assumes failure; use audit_write_success_self() otherwise. + * + * XXX This should let the caller pass an error return value rather than + * hard-coding -1. + */ +int +audit_write_failure_self(short event_code, char *errmsg, int errret) +{ + char *func = "audit_write_failure_self()"; + token_t *subject, *errtok; + + if ((subject = au_to_me()) == NULL) { + syslog(LOG_ERR, "%s: au_to_me() failed", func); + return (kAUMakeSubjectTokErr); + } + /* tokenize and save the error message */ + if ((errtok = au_to_text(errmsg)) == NULL) { + au_free_token(subject); + syslog(LOG_ERR, "%s: au_to_text() failed", func); + return (kAUMakeTextTokErr); + } + return (audit_write(event_code, subject, errtok, -1, errret)); +} + +/* + * For auditing errors during login. Such errors are implicitly + * non-attributable (i.e., not ascribable to any user). + * + * Assumes, like all wrapper calls, that the caller has previously checked + * that auditing is enabled via the audit_get_state() call. + */ +int +audit_write_failure_na(short event_code, char *errmsg, int errret, uid_t euid, + uid_t egid, pid_t pid, au_tid_t *tid) +{ + + return (audit_write_failure(event_code, errmsg, errret, -1, euid, + egid, -1, -1, pid, -1, tid)); +} + +/* END OF au_write() WRAPPERS */ + +#ifdef __APPLE__ +void +audit_token_to_au32(audit_token_t atoken, uid_t *auidp, uid_t *euidp, + gid_t *egidp, uid_t *ruidp, gid_t *rgidp, pid_t *pidp, au_asid_t *asidp, + au_tid_t *tidp) +{ + + if (auidp != NULL) + *auidp = (uid_t)atoken.val[0]; + if (euidp != NULL) + *euidp = (uid_t)atoken.val[1]; + if (egidp != NULL) + *egidp = (gid_t)atoken.val[2]; + if (ruidp != NULL) + *ruidp = (uid_t)atoken.val[3]; + if (rgidp != NULL) + *rgidp = (gid_t)atoken.val[4]; + if (pidp != NULL) + *pidp = (pid_t)atoken.val[5]; + if (asidp != NULL) + *asidp = (au_asid_t)atoken.val[6]; + if (tidp != NULL) { + audit_set_terminal_host(&tidp->machine); + tidp->port = (dev_t)atoken.val[7]; + } +} +#endif /* !__APPLE__ */ + +int +audit_get_cond(int *cond) +{ + int ret; + + ret = auditon(A_GETCOND, cond, sizeof(*cond)); +#ifdef A_OLDGETCOND + if ((0 != ret) && EINVAL == errno) { + long lcond = *cond; + + ret = auditon(A_OLDGETCOND, &lcond, sizeof(lcond)); + *cond = (int)lcond; + } +#endif + return (ret); +} + +int +audit_set_cond(int *cond) +{ + int ret; + + ret = auditon(A_SETCOND, cond, sizeof(*cond)); +#ifdef A_OLDSETCOND + if ((0 != ret) && (EINVAL == errno)) { + long lcond = (long)*cond; + + ret = auditon(A_OLDSETCOND, &lcond, sizeof(lcond)); + *cond = (int)lcond; + } +#endif + return (ret); +} + +int +audit_get_policy(int *policy) +{ + int ret; + + ret = auditon(A_GETPOLICY, policy, sizeof(*policy)); +#ifdef A_OLDGETPOLICY + if ((0 != ret) && (EINVAL == errno)){ + long lpolicy = (long)*policy; + + ret = auditon(A_OLDGETPOLICY, &lpolicy, sizeof(lpolicy)); + *policy = (int)lpolicy; + } +#endif + return (ret); +} + +int +audit_set_policy(int *policy) +{ + int ret; + + ret = auditon(A_SETPOLICY, policy, sizeof(*policy)); +#ifdef A_OLDSETPOLICY + if ((0 != ret) && (EINVAL == errno)){ + long lpolicy = (long)*policy; + + ret = auditon(A_OLDSETPOLICY, &lpolicy, sizeof(lpolicy)); + *policy = (int)lpolicy; + } +#endif + return (ret); +} + +int +audit_get_qctrl(au_qctrl_t *qctrl, size_t sz) +{ + int ret; + + if (sizeof(*qctrl) != sz) { + errno = EINVAL; + return (-1); + } + + ret = auditon(A_GETQCTRL, qctrl, sizeof(*qctrl)); +#ifdef A_OLDGETQCTRL + if ((0 != ret) && (EINVAL == errno)){ + struct old_qctrl { + size_t oq_hiwater; + size_t oq_lowater; + size_t oq_bufsz; + clock_t oq_delay; + int oq_minfree; + } oq; + + oq.oq_hiwater = (size_t)qctrl->aq_hiwater; + oq.oq_lowater = (size_t)qctrl->aq_lowater; + oq.oq_bufsz = (size_t)qctrl->aq_bufsz; + oq.oq_delay = (clock_t)qctrl->aq_delay; + oq.oq_minfree = qctrl->aq_minfree; + + ret = auditon(A_OLDGETQCTRL, &oq, sizeof(oq)); + + qctrl->aq_hiwater = (int)oq.oq_hiwater; + qctrl->aq_lowater = (int)oq.oq_lowater; + qctrl->aq_bufsz = (int)oq.oq_bufsz; + qctrl->aq_delay = (int)oq.oq_delay; + qctrl->aq_minfree = oq.oq_minfree; + } +#endif /* A_OLDGETQCTRL */ + return (ret); +} + +int +audit_set_qctrl(au_qctrl_t *qctrl, size_t sz) +{ + int ret; + + if (sizeof(*qctrl) != sz) { + errno = EINVAL; + return (-1); + } + + ret = auditon(A_SETQCTRL, qctrl, sz); +#ifdef A_OLDSETQCTRL + if ((0 != ret) && (EINVAL == errno)) { + struct old_qctrl { + size_t oq_hiwater; + size_t oq_lowater; + size_t oq_bufsz; + clock_t oq_delay; + int oq_minfree; + } oq; + + oq.oq_hiwater = (size_t)qctrl->aq_hiwater; + oq.oq_lowater = (size_t)qctrl->aq_lowater; + oq.oq_bufsz = (size_t)qctrl->aq_bufsz; + oq.oq_delay = (clock_t)qctrl->aq_delay; + oq.oq_minfree = qctrl->aq_minfree; + + ret = auditon(A_OLDSETQCTRL, &oq, sizeof(oq)); + + qctrl->aq_hiwater = (int)oq.oq_hiwater; + qctrl->aq_lowater = (int)oq.oq_lowater; + qctrl->aq_bufsz = (int)oq.oq_bufsz; + qctrl->aq_delay = (int)oq.oq_delay; + qctrl->aq_minfree = oq.oq_minfree; + } +#endif /* A_OLDSETQCTRL */ + return (ret); +} + +int +audit_send_trigger(int *trigger) +{ + + return (auditon(A_SENDTRIGGER, trigger, sizeof(*trigger))); +} + +int +audit_get_kaudit(auditinfo_addr_t *aia, size_t sz) +{ + + if (sizeof(*aia) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETKAUDIT, aia, sz)); +} + +int +audit_set_kaudit(auditinfo_addr_t *aia, size_t sz) +{ + + if (sizeof(*aia) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_SETKAUDIT, aia, sz)); +} + +int +audit_get_class(au_evclass_map_t *evc_map, size_t sz) +{ + + if (sizeof(*evc_map) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETCLASS, evc_map, sz)); +} + +int +audit_set_class(au_evclass_map_t *evc_map, size_t sz) +{ + + if (sizeof(*evc_map) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_SETCLASS, evc_map, sz)); +} + +int +audit_get_kmask(au_mask_t *kmask, size_t sz) +{ + if (sizeof(*kmask) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETKMASK, kmask, sz)); +} + +int +audit_set_kmask(au_mask_t *kmask, size_t sz) +{ + if (sizeof(*kmask) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_SETKMASK, kmask, sz)); +} + +int +audit_get_fsize(au_fstat_t *fstat, size_t sz) +{ + + if (sizeof(*fstat) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETFSIZE, fstat, sz)); +} + +int +audit_set_fsize(au_fstat_t *fstat, size_t sz) +{ + + if (sizeof(*fstat) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_SETFSIZE, fstat, sz)); +} + +int +audit_set_pmask(auditpinfo_t *api, size_t sz) +{ + + if (sizeof(*api) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_SETPMASK, api, sz)); +} + +int +audit_get_pinfo(auditpinfo_t *api, size_t sz) +{ + + if (sizeof(*api) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETPINFO, api, sz)); +} + +int +audit_get_pinfo_addr(auditpinfo_addr_t *apia, size_t sz) +{ + + if (sizeof(*apia) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETPINFO_ADDR, apia, sz)); +} + +int +audit_get_sinfo_addr(auditinfo_addr_t *aia, size_t sz) +{ + + if (sizeof(*aia) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETSINFO_ADDR, aia, sz)); +} + +int +audit_get_stat(au_stat_t *stats, size_t sz) +{ + + if (sizeof(*stats) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETSTAT, stats, sz)); +} + +int +audit_set_stat(au_stat_t *stats, size_t sz) +{ + + if (sizeof(*stats) != sz) { + errno = EINVAL; + return (-1); + } + + return (auditon(A_GETSTAT, stats, sz)); +} + +int +audit_get_cwd(char *path, size_t sz) +{ + + return (auditon(A_GETCWD, path, sz)); +} + +int +audit_get_car(char *path, size_t sz) +{ + + return (auditon(A_GETCAR, path, sz)); +} diff --git a/contrib/openbsm/libbsm/libbsm.3 b/contrib/openbsm/libbsm/libbsm.3 new file mode 100644 index 0000000..d84e774 --- /dev/null +++ b/contrib/openbsm/libbsm/libbsm.3 @@ -0,0 +1,248 @@ +.\"- +.\" Copyright (c) 2005-2007 Robert N. M. Watson +.\" Copyright (c) 2008-2009 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. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd March 5, 2009 +.Dt LIBBSM 3 +.Os +.Sh NAME +.Nm libbsm +.Nd "Basic Security Module (BSM) Audit API" +.Sh LIBRARY +.Lb libbsm +.Sh SYNOPSIS +.In bsm/libbsm.h +.Sh DESCRIPTION +The +.Nm +library routines provide an interface to BSM audit record streams, allowing +both the parsing of existing audit streams, as well as the creation of new +audit records and streams. +.Sh INTERFACES +The +.Nm +library +provides a large number of Audit programming interfaces in several classes: +event stream interfaces, class interfaces, control interfaces, event +interfaces, I/O interfaces, mask interfaces, notification interfaces, token +interfaces, and user interfaces. +These are described respectively in the +.Xr au_class 3 , +.Xr au_control 3 , +.Xr au_event 3 , +.Xr au_mask 3 , +.Xr au_notify 3 , +.Xr au_stream 3 , +.Xr au_token 3 , +and +.Xr au_user 3 +manual pages. +.Ss Audit Event Stream Interfaces +Audit event stream interfaces support interaction with file-backed audit +event streams: +.Xr au_close 3 , +.Xr au_close_buffer 3 , +.Xr au_free_token 3 , +.Xr au_open 3 , +.Xr au_write 3 , +.Xr audit_submit 3 . +.Ss Audit Class Interfaces +Audit class interfaces support the look up of information from the +.Xr audit_class 5 +database: +.Xr endauclass 3 , +.Xr getauclassent 3 , +.Xr getauclassent_r 3 , +.Xr getauclassnam 3 , +.Xr getauclassnam_r 3 , +.Xr setauclass 3 . +.Ss Audit Control Interfaces +Audit control interfaces support the look up of information from the +.Xr audit_control 5 +database: +.Xr endac 3 , +.Xr setac 3 , +.Xr getacdir 3 , +.Xr getacfilesz 3 , +.Xr getacflg 3 , +.Xr getacmin 3 , +.Xr getacna 3 , +.Xr getacpol 3 , +.Xr au_poltostr 3 , +.Xr au_strtopol 3 . +.Ss Audit Event Interfaces +Audit event interfaces support the look up of information from the +.Xr audit_event 5 +database: +.Xr endauevent 3 , +.Xr setauevent 3 , +.Xr getauevent 3 , +.Xr getauevent_r 3 , +.Xr getauevnam 3 , +.Xr getauevnam_r 3 , +.Xr getauevnonam 3 , +.Xr getauevnonam_r 3 , +.Xr getauevnum 3 , +.Xr getauevnum_r 3 . +.Ss Audit I/O Interfaces +Audit I/O interfaces support the processing and printing of tokens, as well +as the reading of audit records: +.Xr au_fetch_tok 3 , +.Xr au_print_tok 3 , +.Xr au_read_rec 3 . +.Ss Audit Mask Interfaces +Audit mask interfaces convert support the conversion between strings and +.Vt au_mask_t +values. +They may also be used to determine if a particular audit event is matched +by a mask: +.Xr au_preselect 3 , +.Xr getauditflagsbin 3 , +.Xr getauditflagschar 3 . +.Ss Audit Notification Interfaces +Audit notification routines track audit state in a form permitting efficient +update, avoiding frequent system calls to check the kernel audit state: +.Xr au_get_state 3 , +.Xr au_notify_initialize 3 , +.Xr au_notify_terminate 3 . +These interfaces are implemented only for Darwin/Mac OS X. +.Ss Audit Token Interface +Audit token interfaces permit the creation of tokens for use in creating +audit records for submission to event streams. +Each interface converts a C type to its +.Vt token_t +representation: +.Xr au_to_arg 3 , +.Xr au_to_arg32 3 , +.Xr au_to_arg64 3 , +.Xr au_to_attr64 3 , +.Xr au_to_data 3 , +.Xr au_to_exec_args 3 , +.Xr au_to_exec_env 3 , +.Xr au_to_exit 3 , +.Xr au_to_file 3 , +.Xr au_to_groups 3 , +.Xr au_to_header32 3 , +.Xr au_to_header64 3 , +.Xr au_to_in_addr 3 , +.Xr au_to_in_addr_ex 3 , +.Xr au_to_ip 3 , +.Xr au_to_ipc 3 , +.Xr au_to_ipc_perm 3 , +.Xr au_to_iport 3 , +.Xr au_to_me 3 , +.Xr au_to_newgroups 3 , +.Xr au_to_opaque 3 , +.Xr au_to_path 3 , +.Xr au_to_process 3 , +.Xr au_to_process32 3 , +.Xr au_to_process64 3 , +.Xr au_to_process_ex 3 , +.Xr au_to_process32_ex 3 , +.Xr au_to_process64_ex 3 , +.Xr au_to_return 3 , +.Xr au_to_return32 3 , +.Xr au_to_return64 3 , +.Xr au_to_seq 3 , +.Xr au_to_sock_inet 3 , +.Xr au_to_sock_inet32 3 , +.Xr au_to_sock_inet128 3 , +.Xr au_to_socket_ex 3 , +.Xr au_to_subject 3 , +.Xr au_to_subject32 3 , +.Xr au_to_subject64 3 , +.Xr au_to_subject_ex 3 , +.Xr au_to_subject32_ex 3 , +.Xr au_to_subject64_ex 3 , +.Xr au_to_text 3 , +.Xr au_to_trailer 3 , +.Xr au_to_zonename 3 . +.Ss Audit User Interfaces +Audit user interfaces support the look up of information from the +.Xr audit_user 5 +database: +.Xr au_user_mask 3 , +.Xr endauuser 3 , +.Xr setauuser 3 , +.Xr getauuserent 3 , +.Xr getauuserent_r 3 , +.Xr getauusernam 3 , +.Xr getauusernam_r 3 , +.Xr getfauditflags 3 . +.Ss Audit Constant Conversion Interfaces +These functions convert between BSM and local constants, including the +.Xr errno 2 +number, socket type, and protocol famil spaces, and must be used to generate +and interpret BSM return and extended socket tokens: +.Xr au_bsm_to_domain 3 , +.Xr au_bsm_to_errno 3 , +.Xr au_bsm_to_fcntl_cmd 3 , +.Xr au_bsm_to_socket_type 3 , +.Xr au_domain_to_bsm 3 , +.Xr au_errno_to_bsm 3 , +.Xr au_fcntl_cmd_to_bsm 3 , +.Xr au_socket_type_to_bsm 3 . +.Sh SEE ALSO +.Xr au_class 3 , +.Xr au_domain 3 , +.Xr au_errno 3 , +.Xr au_mask 3 , +.Xr au_notify 3 , +.Xr au_socket_type 3 , +.Xr au_stream 3 , +.Xr au_token 3 , +.Xr au_user 3 , +.Xr audit_submit 3 , +.Xr audit_class 5 , +.Xr audit_control 5 +.Sh HISTORY +The OpenBSM implementation was created by McAfee Research, the security +division of McAfee Inc., under contract to Apple Computer, Inc., in 2004. +It was subsequently adopted by the TrustedBSD Project as the foundation for +the OpenBSM distribution. +.Sh AUTHORS +.An -nosplit +This software was created by +.An Robert Watson , +.An Wayne Salamon , +and +.An Suresh Krishnaswamy +for McAfee Research, the security research division of McAfee, +Inc., under contract to Apple Computer, Inc. +.Pp +The Basic Security Module (BSM) interface to audit records and audit event +stream format were defined by Sun Microsystems. +.Sh BUGS +Bugs would not be unlikely. +.Pp +The +.Nm +library implementations are generally thread-safe, but not reentrant. +.Pp +The assignment of routines to classes could use some work, as it is +decidely ad hoc. +For example, +.Fn au_read_rec +should probably be considered a stream routine. |