PROJECTVERSION = 2.8
PROJECT_TYPE = Aggregate
-TOOLS = dynamic_pager.tproj ac.tproj accton.tproj arch.tproj at.tproj\
- atrun.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\
- getty.tproj hostinfo.tproj init.tproj iostat.tproj kgmon.tproj\
- ktrace.tproj login.tproj mach_init.tproj makekey.tproj\
- mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\
+TOOLS = ac.tproj accton.tproj arch.tproj at.tproj atrun.tproj\
+ auditd.tproj audit.tproj chkpasswd.tproj chpass.tproj dmesg.tproj\
+ dynamic_pager.tproj getty.tproj hostinfo.tproj init.tproj\
+ iostat.tproj kgmon.tproj ktrace.tproj login.tproj mach_init.tproj\
+ makekey.tproj mkfile.tproj nvram.tproj passwd.tproj pwd_mkdb.tproj\
reboot.tproj shutdown.tproj sync.tproj sysctl.tproj\
update.tproj vipw.tproj zic.tproj zdump.tproj vm_stat.tproj\
zprint.tproj latency.tproj sc_usage.tproj fs_usage.tproj\
- kdump.tproj sadc.tproj sar.tproj
+ kdump.tproj sadc.tproj sar.tproj
LIBRARIES = dp_notify_lib
"PROJECT_HEADERS" = ();
"PUBLIC_HEADERS" = ();
SUBPROJECTS = (
- "dynamic_pager.tproj",
- "dp_notify_lib",
"ac.tproj",
"accton.tproj",
"arch.tproj",
"at.tproj",
- "atrun.tproj",
+ "atrun.tproj",
+ "audit.tproj",
+ "auditd.tproj",
"chkpasswd.tproj",
"chpass.tproj",
"dmesg.tproj",
+ "dp_notify_lib",
+ "dynamic_pager.tproj",
"getty.tproj",
"hostinfo.tproj",
"init.tproj",
"fs_usage.tproj",
"kdump.tproj",
"sadc.tproj",
- "sar.tproj"
- );
+ "sar.tproj" );
};
LANGUAGE = English;
"LOCALIZABLE_FILES" = {};
--- /dev/null
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = audit
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+CFILES = audit.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+ auditd_control.defs audit.1
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /bin
+LIBS =
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+HEADER_PATHS = -I../auditd.tproj
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
--- /dev/null
+###############################################################################
+# Makefile.postamble
+# Copyright 2004, Apple Computer, Inc.
+#
+# Use this makefile, which is imported after all other makefiles, to
+# override attributes for a project's Makefile environment. This allows you
+# to take advantage of the environment set up by the other Makefiles.
+# You can also define custom rules at the end of this file.
+#
+###############################################################################
+#
+# These variables are exported by the standard makefiles and can be
+# used in any customizations you make. They are *outputs* of
+# the Makefiles and should be used, not set.
+#
+# PRODUCTS: products to install. All of these products will be placed in
+# the directory $(DSTROOT)$(INSTALLDIR)
+# GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+# LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+# OFILE_DIR: Directory into which .o object files are generated.
+# DERIVED_SRC_DIR: Directory used for all other derived files
+#
+# ALL_CFLAGS: flags to pass when compiling .c files
+# ALL_MFLAGS: flags to pass when compiling .m files
+# ALL_CCFLAGS: flags to pass when compiling .cc, .cxx, and .C files
+# ALL_MMFLAGS: flags to pass when compiling .mm, .mxx, and .M files
+# ALL_PRECOMPFLAGS: flags to pass when precompiling .h files
+# ALL_LDFLAGS: flags to pass when linking object files
+# ALL_LIBTOOL_FLAGS: flags to pass when libtooling object files
+# ALL_PSWFLAGS: flags to pass when processing .psw and .pswm (pswrap) files
+# ALL_RPCFLAGS: flags to pass when processing .rpc (rpcgen) files
+# ALL_YFLAGS: flags to pass when processing .y (yacc) files
+# ALL_LFLAGS: flags to pass when processing .l (lex) files
+#
+# NAME: name of application, bundle, subproject, palette, etc.
+# LANGUAGES: langages in which the project is written (default "English")
+# English_RESOURCES: localized resources (e.g. nib's, images) of project
+# GLOBAL_RESOURCES: non-localized resources of project
+#
+# SRCROOT: base directory in which to place the new source files
+# SRCPATH: relative path from SRCROOT to present subdirectory
+#
+# INSTALLDIR: Directory the product will be installed into by 'install' target
+# PUBLIC_HDR_INSTALLDIR: where to install public headers. Don't forget
+# to prefix this with DSTROOT when you use it.
+# PRIVATE_HDR_INSTALLDIR: where to install private headers. Don't forget
+# to prefix this with DSTROOT when you use it.
+#
+# EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+# WARNING_CFLAGS: flag used to set warning level (defaults to -Wmost)
+# DEBUG_SYMBOLS_CFLAGS: debug-symbol flag passed to all builds (defaults
+# to -g)
+# DEBUG_BUILD_CFLAGS: flags passed during debug builds (defaults to -DDEBUG)
+# OPTIMIZE_BUILD_CFLAGS: flags passed during optimized builds (defaults
+# to -O)
+# PROFILE_BUILD_CFLAGS: flags passed during profile builds (defaults
+# to -pg -DPROFILE)
+# LOCAL_DIR_INCLUDE_DIRECTIVE: flag used to add current directory to
+# the include path (defaults to -I.)
+# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+# passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+# INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked
+# against the framework will run against the correct version even if
+# the current version of the framework changes. You may override this
+# to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+# development cycle, but be sure to restore it before installing.
+MIGFLAGS =
+MIG = $(NEXT_ROOT)/usr/bin/mig
+
+auditd_control_user.c auditd_control.h: auditd_control.defs
+ cp $(SRCROOT)/auditd.tproj/auditd_control.defs $(SYM_DIR);
+ cd $(SYM_DIR) && \
+ $(MIG) $(MIGFLAGS) -user auditd_control_user.c -header auditd_control.h \
+ -server /dev/null -sheader /dev/null auditd_control.defs
+
+ install-man-page:
+ install -d $(DSTROOT)/usr/share/man/man1
+ install -c -m 444 audit.1 $(DSTROOT)/usr/share/man/man1/audit.1
--- /dev/null
+###############################################################################
+# Makefile.preamble
+# Copyright 2004, Apple Computer, Inc.
+#
+# Use this makefile for configuring the standard application makefiles
+# associated with ProjectBuilder. It is included before the main makefile.
+# In Makefile.preamble you set attributes for a project, so they are available
+# to the project's makefiles. In contrast, you typically write additional rules or
+# override built-in behavior in the Makefile.postamble.
+#
+# Each directory in a project tree (main project plus subprojects) should
+# have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+#
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+BEFORE_BUILD = auditd_control.h auditd_control_user.c
+OTHER_OFILES = auditd_control_user.o
+AFTER_INSTALL += install-man-page
+
--- /dev/null
+{
+ "DYNAMIC_CODE_GEN" = YES;
+ FILESTABLE = {
+ FRAMEWORKS = ();
+ HEADERSEARCH = ("../auditd.tproj");
+ "OTHER_LINKED" = ("audit.c");
+ "OTHER_SOURCES" = (
+ "Makefile.preamble",
+ Makefile,
+ "Makefile.postamble",
+ "auditd_control.defs",
+ "audit.1"
+ );
+ };
+ LANGUAGE = English;
+ MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
+ "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
+ "NEXTSTEP_INSTALLDIR" = "/usr/sbin";
+ "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
+ "PDO_UNIX_BUILDTOOL" = "$NEXT_ROOT/Developer/bin/make";
+ "PDO_UNIX_INSTALLDIR" = "/bin";
+ "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
+ PROJECTNAME = audit;
+ PROJECTTYPE = Tool;
+ PROJECTVERSION = "2.8";
+ "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
+ "WINDOWS_INSTALLDIR" = "/Library/Executables";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
+}
--- /dev/null
+.\" Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
+.\"
+.Dd Jan 24, 2004
+.Dt AUDIT 1
+.Os "Mac OS X"
+.Sh NAME
+.Nm audit
+.Nd audit management utility
+.Sh SYNOPSIS
+.Nm audit
+.Op Fl nst
+.Op Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility controls the state of auditing system. The optional
+.Ar file
+operand specifies the location of the audit control input file (default
+/etc/security/audit_control).
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl n
+Forces the audit system to close the existing audit log file and rotate to
+a new log file in a location specified in the audit control file.
+.It Fl s
+Specifies that the audit system should [re]synchronize its
+configuration from the audit control file. A new log file will be
+created.
+.It Fl t
+Specifies that the audit system should terminate. Log files are closed
+and renamed to indicate the time of the shutdown.
+.El
+.Sh NOTES
+The auditd(8) daemon must already be running.
+.Sh FILES
+.Bl -tag -width "/etc/security/audit_control" -compact
+.It Pa /etc/security/audit_control
+Default audit policy file used to configure the auditing system.
+.El
+.Sh SEE ALSO
+.Xr auditd 8
+.Xr audit_control 5
--- /dev/null
+/*
+ * Program to trigger the audit daemon with a message that is either:
+ * - Open a new audit log file
+ * - Read the audit control file and take action on it
+ * - Close the audit log file and exit
+ *
+ */
+
+#include <mach/mach.h>
+#include <servers/netname.h>
+#include <mach/message.h>
+#include <mach/port.h>
+#include <mach/mach_error.h>
+#include <mach/host_special_ports.h>
+#include <servers/bootstrap.h>
+
+#include <auditd_control.h>
+#include <auditd.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+mach_port_t serverPort;
+mach_port_t bootstrapPort;
+
+void init();
+void process(int flags);
+
+/*
+ * Main routine to process command line options.
+ */
+int main(int argc, char **argv)
+{
+ char ch;
+ int flags = 0;
+ while ((ch = getopt(argc, argv, "nst")) != -1) {
+ switch(ch) {
+
+ case 'n':
+ flags = OPEN_NEW;
+ break;
+
+ case 's':
+ flags = READ_FILE;
+ break;
+
+ case 't':
+ flags = CLOSE_AND_DIE;
+ break;
+
+ case '?':
+ default:
+ (void)fprintf(stderr,
+ "usage: audit -n | -s | -t \n");
+ exit(1);
+ }
+ }
+ init();
+ process(flags);
+ return 0;
+}
+
+/*
+ * Program initialization:
+ * Look up the server port and store it away.
+ */
+void init()
+{
+ if(host_get_audit_control_port(mach_host_self(), &serverPort) != KERN_SUCCESS) {
+ fprintf(stderr, "Cannot get auditd_control\n");
+ exit(1);
+ }
+
+ printf("Server port is %d\n", serverPort);
+}
+
+/*
+ * Do all the real work.
+ * Send a message to the audit daemon and check the return code.
+ */
+void process(int flags)
+{
+ kern_return_t retcode;
+ retcode = auditd_control(serverPort, flags);
+ if(retcode != KERN_SUCCESS) {
+ mach_error("error doing IPC: ", retcode);
+ exit(1);
+ }
+ printf("Client call successful\n");
+}
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License'). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include "../auditd.tproj/auditd_control.defs"
--- /dev/null
+#
+# Generated by the Apple Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = auditd
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Tool
+
+HFILES = auditd.h
+
+CFILES = audit_warn.c auditd.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+ audit_triggers.defs auditd_control.defs auditd.8 rc.audit
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = tool.make
+NEXTSTEP_INSTALLDIR = /usr/sbin
+WINDOWS_INSTALLDIR = /Library/Executables
+PDO_UNIX_INSTALLDIR = /usr/sbin
+LIBS =
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_LDFLAGS = -lbsm
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
--- /dev/null
+###############################################################################
+# Makefile.postamble
+# Copyright 1997, Apple Computer, Inc.
+#
+# Use this makefile, which is imported after all other makefiles, to
+# override attributes for a project's Makefile environment. This allows you
+# to take advantage of the environment set up by the other Makefiles.
+# You can also define custom rules at the end of this file.
+#
+###############################################################################
+#
+# These variables are exported by the standard makefiles and can be
+# used in any customizations you make. They are *outputs* of
+# the Makefiles and should be used, not set.
+#
+# PRODUCTS: products to install. All of these products will be placed in
+# the directory $(DSTROOT)$(INSTALLDIR)
+# GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
+# LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
+# OFILE_DIR: Directory into which .o object files are generated.
+# DERIVED_SRC_DIR: Directory used for all other derived files
+#
+# ALL_CFLAGS: flags to pass when compiling .c files
+# ALL_MFLAGS: flags to pass when compiling .m files
+# ALL_CCFLAGS: flags to pass when compiling .cc, .cxx, and .C files
+# ALL_MMFLAGS: flags to pass when compiling .mm, .mxx, and .M files
+# ALL_PRECOMPFLAGS: flags to pass when precompiling .h files
+# ALL_LDFLAGS: flags to pass when linking object files
+# ALL_LIBTOOL_FLAGS: flags to pass when libtooling object files
+# ALL_PSWFLAGS: flags to pass when processing .psw and .pswm (pswrap) files
+# ALL_RPCFLAGS: flags to pass when processing .rpc (rpcgen) files
+# ALL_YFLAGS: flags to pass when processing .y (yacc) files
+# ALL_LFLAGS: flags to pass when processing .l (lex) files
+#
+# NAME: name of application, bundle, subproject, palette, etc.
+# LANGUAGES: langages in which the project is written (default "English")
+# English_RESOURCES: localized resources (e.g. nib's, images) of project
+# GLOBAL_RESOURCES: non-localized resources of project
+#
+# SRCROOT: base directory in which to place the new source files
+# SRCPATH: relative path from SRCROOT to present subdirectory
+#
+# INSTALLDIR: Directory the product will be installed into by 'install' target
+# PUBLIC_HDR_INSTALLDIR: where to install public headers. Don't forget
+# to prefix this with DSTROOT when you use it.
+# PRIVATE_HDR_INSTALLDIR: where to install private headers. Don't forget
+# to prefix this with DSTROOT when you use it.
+#
+# EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
+#
+###############################################################################
+
+# Some compiler flags can be overridden here for certain build situations.
+#
+# WARNING_CFLAGS: flag used to set warning level (defaults to -Wmost)
+# DEBUG_SYMBOLS_CFLAGS: debug-symbol flag passed to all builds (defaults
+# to -g)
+# DEBUG_BUILD_CFLAGS: flags passed during debug builds (defaults to -DDEBUG)
+# OPTIMIZE_BUILD_CFLAGS: flags passed during optimized builds (defaults
+# to -O)
+# PROFILE_BUILD_CFLAGS: flags passed during profile builds (defaults
+# to -pg -DPROFILE)
+# LOCAL_DIR_INCLUDE_DIRECTIVE: flag used to add current directory to
+# the include path (defaults to -I.)
+# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
+# passed to ld/libtool (defaults to nothing)
+
+
+# Library and Framework projects only:
+# INSTALL_NAME_DIRECTIVE: This directive ensures that executables linked
+# against the framework will run against the correct version even if
+# the current version of the framework changes. You may override this
+# to "" as an alternative to using the DYLD_LIBRARY_PATH during your
+# development cycle, but be sure to restore it before installing.
+
+
+# Ownership and permissions of files installed by 'install' target
+
+#INSTALL_AS_USER = root
+ # User/group ownership
+#INSTALL_AS_GROUP = wheel
+ # (probably want to set both of these)
+#INSTALL_PERMISSIONS =
+ # If set, 'install' chmod's executable to this
+
+
+# Options to strip. Note: -S strips debugging symbols (executables can be stripped
+# down further with -x or, if they load no bundles, with no options at all).
+
+#STRIPFLAGS = -S
+
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here. Include them in
+# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
+#
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where
+# derived files should go.
+#
+ETCDIR = $(DSTROOT)/private/etc
+MIGFLAGS = -no-cpp-precomp -R -untyped -DNO_DIRECT_RPC
+MIG = $(NEXT_ROOT)/usr/bin/mig
+
+auditd_control_server.c : auditd_control.defs
+ cp $(SRCROOT)/auditd.tproj/auditd_control.defs $(SYM_DIR);
+ cd $(SYM_DIR) && \
+ $(MIG) $(MIGFLAGS) -user /dev/null -server auditd_control_server.c -sheader auditd_control_server.h auditd_control.defs
+
+audit_triggers_server.c: audit_triggers.defs
+ cp $(SRCROOT)/auditd.tproj/audit_triggers.defs $(SYM_DIR);
+ cd $(SYM_DIR) && \
+ $(MIG) $(MIGFLAGS) -user /dev/null -server audit_triggers_server.c -sheader audit_triggers_server.h audit_triggers.defs
+
+install-startup:
+ install -d $(ETCDIR)/security
+ install -c -m 400 rc.audit $(ETCDIR)/security/rc.audit
+
+install-man-page:
+ install -d $(DSTROOT)/usr/share/man/man8
+ install -c -m 444 auditd.8 $(DSTROOT)/usr/share/man/man8/auditd.8
--- /dev/null
+###############################################################################
+# Makefile.preamble
+# Copyright 2004, Apple Computer, Inc.
+#
+# Use this makefile for configuring the standard application makefiles
+# associated with ProjectBuilder. It is included before the main makefile.
+# In Makefile.preamble you set attributes for a project, so they are available
+# to the project's makefiles. In contrast, you typically write additional rules or
+# override built-in behavior in the Makefile.postamble.
+#
+# Each directory in a project tree (main project plus subprojects) should
+# have its own Makefile.preamble and Makefile.postamble.
+###############################################################################
+OTHER_GENERATED_OFILES = $(VERS_OFILE)
+BEFORE_BUILD = auditd_control_server.c auditd_control_server.h \
+ audit_triggers_server.c audit_triggers_server.h
+OTHER_OFILES = auditd_control_server.o audit_triggers_server.o
+AFTER_INSTALL += install-startup install-man-page
--- /dev/null
+{
+ "DYNAMIC_CODE_GEN" = YES;
+ FILESTABLE = {
+ FRAMEWORKS = ();
+ "H_FILES" = ("auditd.h");
+ "OTHER_LINKED" = ("audit_warn.c", "auditd.c");
+ "OTHER_SOURCES" = (
+ "Makefile.preamble",
+ Makefile,
+ "Makefile.postamble",
+ "audit_triggers.defs",
+ "auditd_control.defs",
+ "auditd.8",
+ "rc.audit"
+ );
+ "PRECOMPILED_HEADERS" = ();
+ "PROJECT_HEADERS" = ();
+ "PUBLIC_HEADERS" = ();
+ };
+ LANGUAGE = English;
+ MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
+ "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
+ "NEXTSTEP_INSTALLDIR" = "/usr/sbin";
+ "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_LINKEROPTIONS" = "-lbsm";
+ "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
+ "PDO_UNIX_BUILDTOOL" = "$NEXT_ROOT/Developer/bin/make";
+ "PDO_UNIX_INSTALLDIR" = "/bin";
+ "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
+ PROJECTNAME = auditd;
+ PROJECTTYPE = Tool;
+ PROJECTVERSION = "2.8";
+ "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
+ "WINDOWS_INSTALLDIR" = "/Library/Executables";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
+}
--- /dev/null
+#include <mach/audit_triggers.defs>
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License'). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <auditd.h>
+
+/* Write to the audit log. */
+static int auditwarnlog(char *args[])
+{
+ char *loc_args[9];
+ int i;
+ pid_t pid;
+ loc_args[0] = AUDITWARN_SCRIPT;
+ for (i = 0; args[i] != NULL && i < 8; i++) {
+ loc_args[i+1] = args[i];
+ }
+ loc_args[i+1] = NULL;
+
+ pid = fork();
+ if (pid == 0) {
+ return execv(AUDITWARN_SCRIPT, loc_args);
+ /* not reached */
+ exit(1);
+ } else if (pid == -1) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Indicates that the hard limit for all filesystems
+ * has been exceeded count times
+ */
+int audit_warn_allhard(int count)
+{
+ char intstr[12];
+ char *args[3];
+
+ snprintf(intstr, 12, "%d", count);
+
+ args[0] = HARDLIM_ALL_WARN;
+ args[1] = intstr;
+ args[2] = NULL;
+
+ return auditwarnlog(args);
+}
+
+/*
+ * Indicates that the soft limit for all filesystems
+ * has been exceeded
+ */
+int audit_warn_allsoft()
+{
+ char *args[2];
+
+ args[0] = SOFTLIM_ALL_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+}
+
+/*
+ * Indicates that someone other than the audit daemon
+ * turned off auditing
+ * XXX Its not clear at this point how this function will
+ * XXX be invoked
+ */
+int audit_warn_auditoff()
+{
+ char *args[2];
+
+ args[0] = AUDITOFF_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+}
+
+/*
+ * Indicates that the audit deammn is already running
+ */
+int audit_warn_ebusy()
+{
+ char *args[2];
+
+ args[0] = EBUSY_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+
+}
+
+/*
+ * Indicates that there is a problem getting the directory
+ * from audit_control
+ *
+ * XXX Note that we take the filename instead of a count
+ * XXX as the argument here (different from BSM)
+ */
+int audit_warn_getacdir(char *filename)
+{
+ char *args[3];
+
+ args[0] = GETACDIR_WARN;
+ args[1] = filename;
+ args[2] = NULL;
+
+ return auditwarnlog(args);
+}
+
+
+/*
+ * Indicates that the hard limit for this file has been
+ * exceeded
+ */
+int audit_warn_hard(char *filename)
+{
+ char *args[3];
+
+ args[0] = HARDLIM_WARN;
+ args[1] = filename;
+ args[2] = NULL;
+
+ return auditwarnlog(args);
+
+}
+
+/*
+ * Indicates that auditing could not be started
+ */
+int audit_warn_nostart()
+{
+ char *args[2];
+
+ args[0] = NOSTART_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+}
+
+/*
+ * Indicaes that an error occrred during the orderly shutdown
+ * of the audit daemon
+ */
+int audit_warn_postsigterm()
+{
+ char *args[2];
+
+ args[0] = POSTSIGTERM_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+}
+
+/*
+ * Indicates that the soft limit for this file has been
+ * exceeded
+ */
+int audit_warn_soft(char *filename)
+{
+ char *args[3];
+
+ args[0] = SOFTLIM_WARN;
+ args[1] = filename;
+ args[2] = NULL;
+
+ return auditwarnlog(args);
+
+}
+
+/*
+ * Indicates that the temporary audit file already exists
+ * indicating a fatal error
+ */
+int audit_warn_tmpfile()
+{
+ char *args[2];
+
+ args[0] = TMPFILE_WARN;
+ args[1] = NULL;
+
+ return auditwarnlog(args);
+}
--- /dev/null
+.\" Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
+.\"
+.Dd Jan 24, 2004
+.Dt AUDITD 8
+.Os "Mac OS X"
+.Sh NAME
+.Nm auditd
+.Nd audit log management daemon
+.Sh SYNOPSIS
+.Nm auditd
+.Op Fl dhs
+.Sh DESCRIPTION
+The
+.Nm
+daemon responds to requests from the audit(1) utility and notifications
+from the kernel. It manages the resulting audit log files and specified
+log file locations.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Starts the daemon in debug mode - it will not daemonize.
+.It Fl h
+Specifies that if auditing cannot be performed as specified, the system should
+halt (panic). Normally, the system will attempt to proceed - although individual
+processes may be stopped (see the -s option).
+.It Fl s
+Specifies that individual processes should stop rather than perform operations
+that may cause audit records to be lost due to log file full conditions
+.El
+.Sh NOTE
+.Pp
+To assure uninterrupted audit support, the
+.Nm auditd
+daemon should not be started and stopped manually. Instead, the audit(1) command
+should be used to inform the daemon to change state/configuration after altering
+the audit_control file.
+.Pp
+Sending a SIGHUP to a running
+.Nm auditd
+daemon will force it to exit.
+.Sh FILES
+.Bl -tag -width "/var/audit" -compact
+.It Pa /var/audit
+Default directory for storing audit log files.
+.El
+.Sh SEE ALSO
+.Xr audit 1
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License'). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <mach/port.h>
+#include <mach/mach_error.h>
+#include <mach/mach_traps.h>
+#include <mach/mach.h>
+#include <mach/host_special_ports.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <signal.h>
+#include <string.h>
+#include <notify.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_uevents.h>
+#include <bsm/libbsm.h>
+
+#include <auditd.h>
+#include "auditd_control_server.h"
+#include "audit_triggers_server.h"
+#define NA_EVENT_STR_SIZE 25
+
+static int ret, minval;
+static char *lastfile = NULL;
+
+static int allhardcount = 0;
+
+mach_port_t bp = MACH_PORT_NULL;
+mach_port_t control_port = MACH_PORT_NULL;
+mach_port_t signal_port = MACH_PORT_NULL;
+mach_port_t port_set = MACH_PORT_NULL;
+
+#ifndef __BSM_INTERNAL_NOTIFY_KEY
+#define __BSM_INTERNAL_NOTIFY_KEY "com.apple.audit.change"
+#endif /* __BSM_INTERNAL_NOTIFY_KEY */
+
+TAILQ_HEAD(, dir_ent) dir_q;
+
+
+/* Error starting auditd */
+void fail_exit()
+{
+ audit_warn_nostart();
+ exit(1);
+}
+
+/*
+ * Free our local list of directory names
+ */
+void free_dir_q()
+{
+ struct dir_ent *dirent;
+
+ while ((dirent = TAILQ_FIRST(&dir_q))) {
+ TAILQ_REMOVE(&dir_q, dirent, dirs);
+ free(dirent->dirname);
+ free(dirent);
+ }
+}
+
+/*
+ * generate the timestamp string
+ */
+int getTSstr(char *buf, int len)
+{
+ struct timeval ts;
+ struct timezone tzp;
+ time_t tt;
+
+ if(gettimeofday(&ts, &tzp) != 0) {
+ return -1;
+ }
+ tt = (time_t)ts.tv_sec;
+ if(!strftime(buf, len, "%Y%m%d%H%M%S", gmtime(&tt))) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Concat the directory name to the given file name
+ * XXX We should affix the hostname also
+ */
+char *affixdir(char *name, struct dir_ent *dirent)
+{
+ char *fn;
+ char *curdir;
+ const char *sep = "/";
+
+ curdir = dirent->dirname;
+ syslog(LOG_INFO, "dir = %s\n", dirent->dirname);
+
+ fn = (char *) malloc (strlen(curdir) + strlen(sep)
+ + (2 * POSTFIX_LEN) + 1);
+ if(fn == NULL) {
+ return NULL;
+ }
+ strcpy(fn, curdir);
+ strcat(fn, sep);
+ strcat(fn, name);
+
+ return fn;
+}
+
+/* Close the previous audit trail file */
+int close_lastfile(char *TS)
+{
+ char *ptr;
+ char *oldname;
+
+ if(lastfile != NULL) {
+ oldname = (char *)malloc(strlen(lastfile) + 1);
+ if(oldname == NULL) {
+ return -1;
+ }
+ strcpy(oldname, lastfile);
+
+ /* rename the last file -- append timestamp */
+
+ if((ptr = strstr(lastfile, NOT_TERMINATED)) != NULL) {
+ *ptr = '.';
+ strcpy(ptr+1, TS);
+ if(rename(oldname, lastfile) != 0) {
+ syslog(LOG_ERR, "Could not rename %s to %s \n",
+ oldname, lastfile);
+ }
+ else {
+ syslog(LOG_INFO, "renamed %s to %s \n",
+ oldname, lastfile);
+ }
+ }
+
+ free(lastfile);
+ free(oldname);
+
+ lastfile = NULL;
+ }
+
+ return 0;
+}
+
+/*
+ * Create the new file name, swap with existing audit file
+ */
+int swap_audit_file()
+{
+ char timestr[2 * POSTFIX_LEN];
+ char *fn;
+ char TS[POSTFIX_LEN];
+ struct dir_ent *dirent;
+
+ if(getTSstr(TS, POSTFIX_LEN) != 0) {
+ return -1;
+ }
+
+ strcpy(timestr, TS);
+ strcat(timestr, NOT_TERMINATED);
+
+ /* try until we succeed */
+ while((dirent = TAILQ_FIRST(&dir_q))) {
+ if((fn = affixdir(timestr, dirent)) == NULL) {
+ return -1;
+ }
+
+ syslog(LOG_INFO, "New audit file is %s\n", fn);
+ if (open(fn, O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP) < 0) {
+ perror("File open");
+ }
+ else if (auditctl(fn) != 0) {
+ syslog(LOG_ERR, "auditctl failed! : %s\n",
+ strerror(errno));
+ }
+ else {
+ /* Success */
+ close_lastfile(TS);
+ lastfile = fn;
+ return 0;
+ }
+
+ /* Tell the administrator about lack of permissions for dirent */
+ audit_warn_getacdir(dirent->dirname);
+
+ /* Try again with a different directory */
+ TAILQ_REMOVE(&dir_q, dirent, dirs);
+ free(dirent->dirname);
+ free(dirent);
+ }
+ return -1;
+}
+
+/*
+ * Read the audit_control file contents
+ */
+int read_control_file()
+{
+ char cur_dir[MAX_DIR_SIZE];
+ struct dir_ent *dirent;
+ au_qctrl_t qctrl;
+
+ /* Clear old values */
+ free_dir_q();
+ endac(); // force a re-read of the file the next time
+
+ /* Post that the audit config changed */
+ notify_post(__BSM_INTERNAL_NOTIFY_KEY);
+
+ /* Read the list of directories into a local linked list */
+ /* XXX We should use the reentrant interfaces once they are available */
+ while(getacdir(cur_dir, MAX_DIR_SIZE) >= 0) {
+ dirent = (struct dir_ent *) malloc (sizeof(struct dir_ent));
+ if(dirent == NULL) {
+ return -1;
+ }
+
+ dirent->softlim = 0;
+ dirent->dirname = (char *) malloc (MAX_DIR_SIZE);
+ if(dirent->dirname == NULL) {
+ free(dirent);
+ return -1;
+ }
+
+ strcpy(dirent->dirname, cur_dir);
+ TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
+ }
+
+ allhardcount = 0;
+
+ if(swap_audit_file() == -1) {
+ syslog(LOG_ERR, "Could not swap audit file\n");
+ /*
+ * XXX Faulty directory listing? - user should be given
+ * XXX an opportunity to change the audit_control file
+ * XXX switch to a reduced mode of auditing?
+ */
+ return -1;
+ }
+
+ /*
+ * XXX There are synchronization problems here
+ * XXX what should we do if a trigger for the earlier limit
+ * XXX is generated here?
+ */
+ if(0 == (ret = getacmin(&minval))) {
+
+ syslog(LOG_INFO, "min free = %d\n", minval);
+
+ if (auditon(A_GETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
+ syslog(LOG_ERR,
+ "could not get audit queue settings\n");
+ return -1;
+ }
+ qctrl.aq_minfree = minval;
+ if (auditon(A_SETQCTRL, &qctrl, sizeof(qctrl)) != 0) {
+ syslog(LOG_ERR,
+ "could not set audit queue settings\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Close all log files, control files, and tell the audit system.
+ */
+int close_all()
+{
+ int err_ret = 0;
+ char TS[POSTFIX_LEN];
+ int aufd;
+ token_t *tok;
+
+ /* Generate an audit record */
+ if((aufd = au_open()) == -1) {
+ syslog(LOG_ERR, "Could not create audit shutdown event.\n");
+ } else {
+
+ if((tok = au_to_text("auditd::Audit shutdown")) != NULL) {
+ au_write(aufd, tok);
+ }
+
+ if(au_close(aufd, 1, AUE_audit_shutdown) == -1) {
+ syslog(LOG_ERR, "Could not close audit shutdown event.\n");
+ }
+ }
+
+ /* flush contents */
+ err_ret = auditctl(NULL);
+ if (err_ret != 0) {
+ syslog(LOG_ERR, "auditctl failed! : %s\n",
+ strerror(errno));
+ err_ret = 1;
+ }
+ if(getTSstr(TS, POSTFIX_LEN) == 0) {
+ close_lastfile(TS);
+ }
+ if(lastfile != NULL)
+ free(lastfile);
+
+ free_dir_q();
+ if((remove(AUDITD_PIDFILE) == -1) || err_ret) {
+ syslog(LOG_ERR, "Could not unregister\n");
+ audit_warn_postsigterm();
+ return (1);
+ }
+ endac();
+ syslog(LOG_INFO, "Finished.\n");
+ return (0);
+}
+
+/*
+ * When we get a signal, we are often not at a clean point.
+ * So, little can be done in the signal handler itself. Instead,
+ * we send a message to the main servicing loop to do proper
+ * handling from a non-signal-handler context.
+ */
+static void
+relay_signal(int signal)
+{
+ mach_msg_empty_send_t msg;
+
+ msg.header.msgh_id = signal;
+ msg.header.msgh_remote_port = signal_port;
+ msg.header.msgh_local_port = MACH_PORT_NULL;
+ msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+ mach_msg(&(msg.header), MACH_SEND_MSG|MACH_SEND_TIMEOUT, sizeof(msg),
+ 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+}
+
+/* registering the daemon */
+int register_daemon()
+{
+ FILE * pidfile;
+ int fd;
+ pid_t pid;
+
+ /* Set up the signal hander */
+ if (signal(SIGTERM, relay_signal) == SIG_ERR) {
+ fail_exit();
+ }
+ if (signal(SIGCHLD, relay_signal) == SIG_ERR) {
+ fail_exit();
+ }
+
+ if ((pidfile = fopen(AUDITD_PIDFILE, "a")) == NULL) {
+ audit_warn_tmpfile();
+ return -1;
+ }
+
+ /* attempt to lock the pid file; if a lock is present, exit */
+ fd = fileno(pidfile);
+ if(flock(fd, LOCK_EX | LOCK_NB) < 0) {
+ syslog(LOG_ERR, "PID file is locked (is another auditd running?).\n");
+ audit_warn_ebusy();
+ return -1;
+ }
+
+ pid = getpid();
+ ftruncate(fd, 0);
+ if(fprintf(pidfile, "%u\n", pid) < 0) {
+ /* should not start the daemon */
+ fail_exit();
+ }
+
+ fflush(pidfile);
+ return 0;
+}
+
+/*
+ * React to input from the audit tool
+ */
+kern_return_t auditd_control(auditd_port, flags)
+ mach_port_t auditd_port;
+ int flags;
+{
+ int err_ret = 0;
+
+ switch(flags) {
+
+ case OPEN_NEW :
+ /* create a new file and swap with the one being used in kernel */
+ if(swap_audit_file() == -1) {
+ syslog(LOG_ERR, "Error swapping audit file\n");
+ }
+ break;
+
+ case READ_FILE :
+ if(read_control_file() == -1) {
+ syslog(LOG_ERR, "Error in audit control file\n");
+ }
+ break;
+
+ case CLOSE_AND_DIE :
+ err_ret = close_all();
+ exit (err_ret);
+ break;
+
+ default :
+ break;
+ }
+
+ return KERN_SUCCESS;
+}
+
+/*
+ * Suppress duplicate messages within a 30 second interval.
+ * This should be enough to time to rotate log files without
+ * thrashing from soft warnings generated before the log is
+ * actually rotated.
+ */
+#define DUPLICATE_INTERVAL 30
+/*
+ * Implementation of the audit_triggers() MIG routine.
+ */
+kern_return_t audit_triggers(audit_port, flags)
+ mach_port_t audit_port;
+ int flags;
+{
+ static int last_flags;
+ static time_t last_time;
+ struct dir_ent *dirent;
+
+ /*
+ * Suppres duplicate messages from the kernel within the specified interval
+ */
+ struct timeval ts;
+ struct timezone tzp;
+ time_t tt;
+
+ if(gettimeofday(&ts, &tzp) == 0) {
+ tt = (time_t)ts.tv_sec;
+ if ((flags == last_flags) && (tt < (last_time + DUPLICATE_INTERVAL))) {
+ return KERN_SUCCESS;
+ }
+ last_flags = flags;
+ last_time = tt;
+ }
+
+ syslog(LOG_INFO,
+ "audit_triggers() called within auditd with flags = %d\n",
+ flags);
+ /*
+ * XXX Message processing is done here
+ */
+ dirent = TAILQ_FIRST(&dir_q);
+ if(flags == AUDIT_TRIGGER_LOW_SPACE) {
+ if(dirent && (dirent->softlim != 1)) {
+ TAILQ_REMOVE(&dir_q, dirent, dirs);
+ /* add this node to the end of the list */
+ TAILQ_INSERT_TAIL(&dir_q, dirent, dirs);
+ audit_warn_soft(dirent->dirname);
+ dirent->softlim = 1;
+
+ if (TAILQ_NEXT(TAILQ_FIRST(&dir_q), dirs) != NULL && swap_audit_file() == -1) {
+ syslog(LOG_ERR, "Error swapping audit file\n");
+ }
+
+ /*
+ * check if the next dir has already reached its
+ * soft limit
+ */
+ dirent = TAILQ_FIRST(&dir_q);
+ if(dirent->softlim == 1) {
+ /* all dirs have reached their soft limit */
+ audit_warn_allsoft();
+ }
+ }
+ else {
+ /*
+ * Continue auditing to the current file
+ * Also generate an allsoft warning
+ * XXX do we want to do this ?
+ */
+ audit_warn_allsoft();
+ }
+ }
+ else if (flags == AUDIT_TRIGGER_FILE_FULL) {
+
+ /* delete current dir, go on to next */
+ TAILQ_REMOVE(&dir_q, dirent, dirs);
+ audit_warn_hard(dirent->dirname);
+ free(dirent->dirname);
+ free(dirent);
+
+ if(swap_audit_file() == -1) {
+ syslog(LOG_ERR, "Error swapping audit file in response to AUDIT_TRIGGER_FILE_FULL message\n");
+
+ /* Nowhere to write to */
+ audit_warn_allhard(++allhardcount);
+ }
+ }
+ return KERN_SUCCESS;
+}
+
+/*
+ * Reap our children.
+ */
+static void
+reap_children(void)
+{
+ pid_t child;
+ int wstatus;
+
+ while ((child = waitpid(-1, &wstatus, WNOHANG)) > 0) {
+ if (wstatus) {
+ syslog(LOG_INFO, "warn process [pid=%d] %s %d.\n", child,
+ ((WIFEXITED(wstatus)) ?
+ "exited with non-zero status" :
+ "exited as a result of signal"),
+ ((WIFEXITED(wstatus)) ?
+ WEXITSTATUS(wstatus) :
+ WTERMSIG(wstatus)));
+ }
+ }
+}
+
+/*
+ * Handle an RPC call
+ */
+boolean_t auditd_combined_server(
+ mach_msg_header_t *InHeadP,
+ mach_msg_header_t *OutHeadP)
+{
+ mach_port_t local_port = InHeadP->msgh_local_port;
+
+ if (local_port == signal_port) {
+ int signo = InHeadP->msgh_id;
+ int ret;
+
+ if (SIGTERM == signo) {
+ ret = close_all();
+ exit (ret);
+ } else if (SIGCHLD == signo) {
+ reap_children();
+ return TRUE;
+ } else {
+ syslog(LOG_INFO, "Recevied signal %d.\n", signo);
+ return TRUE;
+ }
+ } else if (local_port == control_port) {
+ boolean_t result;
+
+ result = audit_triggers_server(InHeadP, OutHeadP);
+ if (!result)
+ result = auditd_control_server(InHeadP, OutHeadP);
+ return result;
+ }
+ syslog(LOG_INFO, "Recevied msg on bad port 0x%x.\n", local_port);
+ return FALSE;
+}
+
+void wait_on_audit_trigger(port_set)
+ mach_port_t port_set;
+{
+ kern_return_t result;
+ result = mach_msg_server(auditd_combined_server, 4096, port_set, MACH_MSG_OPTION_NONE);
+ syslog(LOG_ERR, "abnormal exit\n");
+}
+
+/*
+ * Configure the audit controls in the kernel: the event to class mapping,
+ * kernel preselection mask, etc.
+ */
+int config_audit_controls(long flags)
+{
+ au_event_ent_t *ev;
+ au_evclass_map_t evc_map;
+ au_mask_t aumask;
+ int ctr = 0;
+ char naeventstr[NA_EVENT_STR_SIZE];
+
+ /* Process the audit event file, obtaining a class mapping for each
+ * event, and send that mapping into the kernel.
+ * XXX There's a risk here that the BSM library will return NULL
+ * for an event when it can't properly map it to a class. In that
+ * case, we will not process any events beyond the one that failed,
+ * but should. We need a way to get a count of the events.
+ */
+
+ setauevent();
+ while((ev = getauevent()) != NULL) {
+ evc_map.ec_number = ev->ae_number;
+ evc_map.ec_class = ev->ae_class;
+ if (auditon(A_SETCLASS, &evc_map, sizeof(au_evclass_map_t)) != 0) {
+ syslog(LOG_ERR,
+ "Failed to register class mapping for event %s",
+ ev->ae_name);
+ } else {
+ ctr++;
+ }
+ free(ev->ae_name);
+ free(ev->ae_desc);
+ free(ev);
+ }
+ endauevent();
+ if (ctr == 0)
+ syslog(LOG_ERR, "No events to class mappings registered.");
+ else
+ syslog(LOG_INFO, "Registered %d event to class mappings.", ctr);
+
+ /* Get the non-attributable event string and set the kernel mask
+ * from that.
+ */
+ if ((getacna(naeventstr, NA_EVENT_STR_SIZE) == 0)
+ && ( getauditflagsbin(naeventstr, &aumask) == 0)) {
+
+ if (auditon(A_SETKMASK, &aumask, sizeof(au_mask_t))){
+ syslog(LOG_ERR,
+ "Failed to register non-attributable event mask.");
+ } else {
+ syslog(LOG_INFO, "Registered non-attributable event mask.");
+ }
+
+ } else {
+ syslog(LOG_ERR,"Failed to obtain non-attributable event mask.");
+ }
+
+ /*
+ * Set the audit policy flags based on passed in parameter values.
+ */
+ if (auditon(A_SETPOLICY, &flags, sizeof(flags))) {
+ syslog(LOG_ERR,
+ "Failed to set audit policy.");
+ }
+
+ return 0;
+}
+
+void setup(long flags)
+{
+ mach_msg_type_name_t poly;
+ int aufd;
+ token_t *tok;
+
+ /* Allocate a port set */
+ if (mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_PORT_SET,
+ &port_set) != KERN_SUCCESS) {
+ syslog(LOG_ERR, "allocation of port set failed\n");
+ fail_exit();
+ }
+
+ /* Allocate a signal reflection port */
+ if (mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE,
+ &signal_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(),
+ signal_port,
+ port_set) != KERN_SUCCESS) {
+ syslog(LOG_ERR, "allocation of signal port failed\n");
+ fail_exit();
+ }
+
+ /* Allocate a trigger port */
+ if (mach_port_allocate(mach_task_self(),
+ MACH_PORT_RIGHT_RECEIVE,
+ &control_port) != KERN_SUCCESS ||
+ mach_port_move_member(mach_task_self(),
+ control_port,
+ port_set) != KERN_SUCCESS) {
+ syslog(LOG_ERR, "allocation of trigger port failed\n");
+ fail_exit();
+ }
+
+ /* create a send right on our trigger port */
+ mach_port_extract_right(mach_task_self(), control_port,
+ MACH_MSG_TYPE_MAKE_SEND, &control_port, &poly);
+
+ TAILQ_INIT(&dir_q);
+
+ /* register the trigger port with the kernel */
+ if(host_set_audit_control_port(mach_host_self(), control_port) != KERN_SUCCESS) {
+ syslog(LOG_ERR, "Cannot set Mach control port\n");
+ fail_exit();
+ }
+ else {
+ syslog(LOG_ERR, "Mach control port registered\n");
+ }
+
+ if(read_control_file() == -1) {
+ syslog(LOG_ERR, "Error reading control file\n");
+ fail_exit();
+ }
+
+ /* Generate an audit record */
+ if((aufd = au_open()) == -1) {
+ syslog(LOG_ERR, "Could not create audit startup event.\n");
+ } else {
+
+ if((tok = au_to_text("auditd::Audit startup")) != NULL) {
+ au_write(aufd, tok);
+ }
+
+ if(au_close(aufd, 1, AUE_audit_startup) == -1) {
+ syslog(LOG_ERR, "Could not close audit startup event.\n");
+ }
+ }
+
+ if (config_audit_controls(flags) == 0)
+ syslog(LOG_INFO, "Initialization successful\n");
+ else
+ syslog(LOG_INFO, "Initialization failed\n");
+}
+
+
+int main(int argc, char **argv)
+{
+ char ch;
+ long flags = AUDIT_CNT;
+ int debug = 0;
+
+ while ((ch = getopt(argc, argv, "dhs")) != -1) {
+ switch(ch) {
+
+ /* debug option */
+ case 'd':
+ debug = 1;
+ break;
+
+ /* fail-stop option */
+ case 's':
+ flags &= ~(AUDIT_CNT);
+ break;
+
+ /* halt-stop option */
+ case 'h':
+ flags |= AUDIT_AHLT;
+ break;
+
+ case '?':
+ default:
+ (void)fprintf(stderr,
+ "usage: auditd [-h | -s]\n");
+ exit(1);
+ }
+ }
+
+ openlog("auditd", LOG_CONS | LOG_PID, LOG_DAEMON);
+ syslog(LOG_INFO, "starting...\n");
+
+ if (debug == 0 && daemon(0, 0) == -1) {
+ syslog(LOG_ERR, "Failed to daemonize\n");
+ exit(1);
+ }
+
+ if(register_daemon() == -1) {
+ syslog(LOG_ERR, "Could not register as daemon\n");
+ exit(1);
+ }
+
+ setup(flags);
+ wait_on_audit_trigger(port_set);
+ syslog(LOG_INFO, "exiting.\n");
+
+ exit(1);
+}
--- /dev/null
+#ifndef _AUDITD_H_
+#define _AUDITD_H_
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <syslog.h>
+
+#define MAX_DIR_SIZE 255
+#define AUDITD_NAME "auditd"
+
+#define POSTFIX_LEN 16
+#define NOT_TERMINATED ".not_terminated"
+
+struct dir_ent {
+ char *dirname;
+ char softlim;
+ TAILQ_ENTRY(dir_ent) dirs;
+};
+
+/* audit utility flags */
+#define OPEN_NEW 0x1
+#define READ_FILE 0x2
+#define CLOSE_AND_DIE 0x4
+
+#define HARDLIM_ALL_WARN "allhard"
+#define SOFTLIM_ALL_WARN "allsoft"
+#define AUDITOFF_WARN "aditoff"
+#define EBUSY_WARN "ebusy"
+#define GETACDIR_WARN "getacdir"
+#define HARDLIM_WARN "hard"
+#define NOSTART_WARN "nostart"
+#define POSTSIGTERM_WARN "postsigterm"
+#define SOFTLIM_WARN "soft"
+#define TMPFILE_WARN "tmpfile"
+
+#define AUDITWARN_SCRIPT "/etc/security/audit_warn"
+#define AUDITD_PIDFILE "/var/run/auditd.pid"
+
+int audit_warn_allhard(int count);
+int audit_warn_allsoft();
+int audit_warn_auditoff();
+int audit_warn_ebusy();
+int audit_warn_getacdir(char *filename);
+int audit_warn_hard(char *filename);
+int audit_warn_nostart();
+int audit_warn_postsigterm();
+int audit_warn_soft(char *filename);
+int audit_warn_tmpfile();
+
+#endif /* !_AUDITD_H_ */
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.0 (the 'License'). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License."
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Exported client calls to the auditd facility.
+ */
+
+subsystem
+ KernelUser
+ auditd_control 456;
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+simpleroutine auditd_control(
+ auditd_port : mach_port_t;
+ in flags : int);
+
--- /dev/null
+##
+# Startup script for Common Criteria Auditing function.
+##
+# Copyright 2004 Apple Computer, Inc.
+##
+
+. /etc/rc.common
+
+##
+# Start the audit daemon (if present)
+##
+if [ "${AUDIT:=-NO-}" == "-YES-" ]; then
+ if [ -f /usr/sbin/auditd ]; then
+ /usr/sbin/auditd
+ fi
+elif [ "${AUDIT:=-NO-}" == "-FAILSTOP-" ]; then
+ if [ -f /usr/sbin/auditd ]; then
+ /usr/sbin/auditd -s
+ fi
+elif [ "${AUDIT:=-NO-}" == "-FAILHALT-" ]; then
+ if [ -f /usr/sbin/auditd ]; then
+ /usr/sbin/auditd -h
+ fi
+
+fi
#
-# Generated by the NeXT Project Builder.
+# Generated by the Apple Project Builder.
#
# NOTE: Do NOT change this file -- Project Builder maintains it.
#
NEXTSTEP_INSTALLDIR = /usr/bin
WINDOWS_INSTALLDIR = /usr/bin
PDO_UNIX_INSTALLDIR = /usr/bin
-LIBS = -lpam -lpam_misc
+LIBS = -lbsm -lpam -lpam_misc
DEBUG_LIBS = $(LIBS)
PROF_LIBS = $(LIBS)
{
DOCICONFILES = ();
FILESTABLE = {
- C_FILES = ();
- H_FILES = (pathnames.h);
- OTHER_LIBS = ();
- OTHER_LINKED = (klogin.c, login.c);
- OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, login.1);
+ "C_FILES" = ();
+ "H_FILES" = ("pathnames.h");
+ "OTHER_LIBS" = (bsm, pam, "pam_misc");
+ "OTHER_LINKED" = ("klogin.c", "login.c");
+ "OTHER_SOURCES" = ("Makefile.preamble", Makefile, "Makefile.postamble", "login.1");
SUBPROJECTS = ();
};
LANGUAGE = English;
- LOCALIZABLE_FILES = {};
- NEXTSTEP_INSTALLDIR = /usr/bin;
- NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
- NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
- PDO_UNIX_INSTALLDIR = /usr/bin;
- PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac";
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
+ "LOCALIZABLE_FILES" = {};
+ "NEXTSTEP_INSTALLDIR" = "/usr/bin";
+ "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
+ "PDO_UNIX_INSTALLDIR" = "/usr/bin";
+ "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac";
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = login;
PROJECTTYPE = Tool;
- PROJECTVERSION = 2.8;
- WINDOWS_INSTALLDIR = /usr/bin;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+ PROJECTVERSION = "2.8";
+ "WINDOWS_INSTALLDIR" = "/usr/bin";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
}
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <unistd.h>
#include <utmp.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
#ifdef USE_PAM
#include <pam/pam_appl.h>
#include <pam/pam_misc.h>
#ifdef KERBEROS
int klogin __P((struct passwd *, char *, char *, char *));
#endif
+void au_success();
+void au_fail(char *, int);
+
extern void login __P((struct utmp *));
int failures;
char term[64], *hostname, *username = NULL, *tty;
+#define NA_EVENT_STR_SIZE 25
+au_tid_t tid;
+
int
main(argc, argv)
int argc;
pid_t pid;
#endif
+ char auditsuccess = 1;
+
(void)signal(SIGALRM, timedout);
(void)alarm(timeout);
(void)signal(SIGQUIT, SIG_IGN);
openlog("login", LOG_ODELAY, LOG_AUTH);
+
/*
* -p is used by getty to tell login not to destroy the environment
* -f is used to skip a second login authentication
else
tty = ttyn;
+ /* Set the terminal id */
+ audit_set_terminal_id(&tid);
+ if (fstat(STDIN_FILENO, &st) < 0) {
+ fprintf(stderr, "login: Unable to stat terminal\n");
+ au_fail("Unable to stat terminal", 1);
+ exit(-1);
+ }
+ if (S_ISCHR(st.st_mode)) {
+ tid.port = st.st_rdev;
+ } else {
+ tid.port = 0;
+ }
+
#ifdef USE_PAM
rval = pam_start("login", username, &conv, &pamh);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_TTY, tty);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_RHOST, hostname);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM Error", 1);
exit(1);
}
rval = pam_set_item(pamh, PAM_USER_PROMPT, "login: ");
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM Error", 1);
exit(1);
}
if( (pwd != NULL) && fflag && ((uid == 0) || (uid == pwd->pw_uid)) ){
rval = 0;
+ auditsuccess = 0; /* we've simply opened a terminal window */
} else {
rval = pam_authenticate(pamh, 0);
(rval == PAM_USER_UNKNOWN) ||
(rval == PAM_CRED_INSUFFICIENT) ||
(rval == PAM_AUTHINFO_UNAVAIL))) {
+ /*
+ * we are not exiting here, but this corresponds to
+ * a failed login event, so set exitstatus to 1
+ */
+ au_fail("Login incorrect", 1);
badlogin(username);
printf("Login incorrect\n");
rootlogin = 0;
pam_get_item(pamh, PAM_USER, (void *)&username);
badlogin(username);
printf("Login incorrect\n");
+ au_fail("Login incorrect", 1);
exit(1);
}
}
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM error", 1);
exit(1);
}
+
}
rval = pam_get_item(pamh, PAM_USER, (void *)&username);
rval = pam_open_session(pamh, 0);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM error", 1);
exit(1);
}
rval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if( rval != PAM_SUCCESS ) {
fprintf(stderr, "login: PAM Error: %s\n", pam_strerror(pamh, rval));
+ au_fail("PAM error", 1);
exit(1);
}
* for nonexistent name (mistyped username).
*/
if (failures && strcmp(tbuf, username)) {
- if (failures > (pwd ? 0 : 1))
+ if (failures > (pwd ? 0 : 1)) {
badlogin(tbuf);
+ }
failures = 0;
}
(void)strcpy(tbuf, username);
syslog(LOG_NOTICE,
"LOGIN %s REFUSED ON TTY %s",
pwd->pw_name, tty);
+ au_fail("Login refused on terminal", 0);
continue;
}
if (++cnt > 3) {
if (cnt >= 10) {
badlogin(username);
+ au_fail("Login incorrect", 1);
sleepexit(1);
}
+ au_fail("Login incorrect", 1);
sleep((u_int)((cnt - 3) * 5));
}
}
if (!rootlogin)
checknologin();
+ /* Audit successful login */
+ if (auditsuccess)
+ au_success();
+
setegid(pwd->pw_gid);
seteuid(rootlogin ? 0 : pwd->pw_uid);
- /* First do a stat in case the homedir is automounted */
-\r stat(pwd->pw_dir,&st);
+ /* First do a stat in case the homedir is automounted */
+ stat(pwd->pw_dir,&st);
if (chdir(pwd->pw_dir) < 0) {
(void)printf("No home directory %s!\n", pwd->pw_dir);
- if (chdir("/"))
+ if (chdir("/")) {
exit(0);
+ }
pwd->pw_dir = "/";
(void)printf("Logging in with home = \"/\".\n");
}
+
seteuid(euid);
setegid(egid);
quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
/* Nothing else left to fail -- really log in. */
+
memset((void *)&utmp, 0, sizeof(utmp));
(void)time(&utmp.ut_time);
(void)strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
else
(void) setuid(pwd->pw_uid);
+
execlp(pwd->pw_shell, tbuf, 0);
err(1, "%s", pwd->pw_shell);
}
#define NBUFSIZ (MAXLOGNAME + 1)
#endif
+/*
+ * The following tokens are included in the audit record for successful login attempts
+ * header
+ * subject
+ * return
+ */
+void au_success()
+{
+ token_t *tok;
+ int aufd;
+ au_mask_t aumask;
+ auditinfo_t auinfo;
+ uid_t uid = pwd->pw_uid;
+ gid_t gid = pwd->pw_gid;
+ pid_t pid = getpid();
+ long au_cond;
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "login: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ /* Compute and Set the user's preselection mask */
+ if(au_user_mask(pwd->pw_name, &aumask) == -1) {
+ fprintf(stderr, "login: Could not set audit mask\n");
+ exit(1);
+ }
+
+ /* Set the audit info for the user */
+ auinfo.ai_auid = uid;
+ auinfo.ai_asid = pid;
+ bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid));
+ bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask));
+ if(setaudit(&auinfo) != 0) {
+ fprintf(stderr, "login: setaudit failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "login: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ /* The subject that is created (euid, egid of the current process) */
+ if((tok = au_to_subject32(uid, geteuid(), getegid(),
+ uid, gid, pid, pid, &tid)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(0, 0)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_login) == -1) {
+ fprintf(stderr, "login: Audit Record was not committed.\n");
+ exit(1);
+ }
+}
+
+/*
+ * The following tokens are included in the audit record for successful login attempts
+ * header
+ * subject
+ * text
+ * return
+ */
+void au_fail(char *errmsg, int na)
+{
+ token_t *tok;
+ int aufd;
+ long au_cond;
+ uid_t uid;
+ gid_t gid;
+ pid_t pid = getpid();
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "login: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "login: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ if(na) {
+ /* Non attributable event */
+ /* Assuming that login is not called within a users' session => auid,asid == -1 */
+ if((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1,
+ pid, -1, &tid)) == NULL) {
+
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ }
+ else {
+ /* we know the subject -- so use its value instead */
+ uid = pwd->pw_uid;
+ gid = pwd->pw_gid;
+ if((tok = au_to_subject32(uid, geteuid(), getegid(),
+ uid, gid, pid, pid, &tid)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ }
+ au_write(aufd, tok);
+
+ /* Include the error message */
+ if((tok = au_to_text(errmsg)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_text() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(1, errno)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_login) == -1) {
+ fprintf(stderr, "login: Audit Error: au_close() was not committed\n");
+ exit(1);
+ }
+}
+
void
getloginname()
{
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
(void)write(fileno(stdout), tbuf, nchars);
+
+ au_fail("No login", 0);
sleepexit(0);
}
}
NEXTSTEP_INSTALLDIR = /sbin
WINDOWS_INSTALLDIR = /sbin
PDO_UNIX_INSTALLDIR = /sbin
-LIBS =
+LIBS = -lbsm
DEBUG_LIBS = $(LIBS)
PROF_LIBS = $(LIBS)
HEADERSEARCH = ();
"H_FILES" = ("bootstrap_internal.h", "error_log.h", "lists.h");
"M_FILES" = ();
- "OTHER_LIBS" = ();
+ "OTHER_LIBS" = (bsm);
"OTHER_LINKED" = ("bootstrap.c", "error_log.c", "lists.c", "rpc_services.c");
"OTHER_SOURCES" = (
"Makefile.preamble",
/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#import <stdio.h>
#import <libc.h>
#import <paths.h>
+#import <pwd.h>
+
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
#import "bootstrap.h"
#define INIT_PATH "/sbin/init" /* default init path */
#endif INIT_PATH
-uid_t inherited_uid;
+uid_t inherited_uid = 0;
+auditinfo_t inherited_audit;
mach_port_t inherited_bootstrap_port = MACH_PORT_NULL;
boolean_t forward_ok = FALSE;
boolean_t shutdown_in_progress = FALSE;
pid = getpid();
if (pid == 1)
{
- close(0);
- freopen("/dev/console", "r", stdin);
- setbuf(stdin, NULL);
- close(1);
- freopen("/dev/console", "w", stdout);
- setbuf(stdout, NULL);
- close(2);
- freopen("/dev/console", "w", stderr);
- setbuf(stderr, NULL);
-
result = mach_port_allocate(
mach_task_self(),
MACH_PORT_RIGHT_RECEIVE,
bootstrap_port);
if (result != KERN_SUCCESS)
kern_fatal(result, "task_get_bootstrap_port");
+
+ close(0);
+ open("/dev/null", O_RDONLY, 0);
+ close(1);
+ open("/dev/null", O_WRONLY, 0);
+ close(2);
+ open("/dev/null", O_WRONLY, 0);
+
} else
init_notify_port = MACH_PORT_NULL;
*/
bootstrap_self = mach_task_self();
inherited_uid = getuid();
+ getaudit(&inherited_audit);
init_lists();
init_ports();
setenv("PATH", _PATH_STDPATH, 1);
init_errlog(pid == 0); /* are we a daemon? */
- notice("Started with uid=%d%s%s%s",
+ notice("Started with uid=%d audit-uid=%d%s%s%s",
inherited_uid,
+ inherited_audit.ai_auid,
(register_self) ? " registered-as=" : "",
(register_self) ? register_name : "",
(debugging) ? " in debug-mode" : "");
argv = argvize(serverp->cmd);
close_errlog();
+ /*
+ * Set up the audit state for the user (if necessesary).
+ */
+ if (inherited_uid == 0 &&
+ (serverp->auinfo.ai_auid != inherited_uid ||
+ serverp->auinfo.ai_asid != inherited_audit.ai_asid)) {
+ struct passwd *pwd = NULL;
+
+ pwd = getpwuid(serverp->auinfo.ai_auid);
+ if (pwd == NULL) {
+ unix_fatal("Disabled server %x bootstrap %x: \"%s\": getpwuid(%d) failed",
+ serverp->port, serverp->bootstrap->bootstrap_port,
+ serverp->cmd, serverp->auinfo.ai_auid);
+
+ } else if (au_user_mask(pwd->pw_name, &serverp->auinfo.ai_mask) != 0) {
+ unix_fatal("Disabled server %x bootstrap %x: \"%s\": au_user_mask(%s) failed",
+ serverp->port, serverp->bootstrap->bootstrap_port,
+ serverp->cmd, pwd->pw_name);
+ } else if (setaudit(&serverp->auinfo) != 0)
+ unix_fatal("Disabled server %x bootstrap %x: \"%s\": setaudit()",
+ serverp->port, serverp->bootstrap->bootstrap_port,
+ serverp->cmd);
+ }
+
if (serverp->uid != inherited_uid)
if (setuid(serverp->uid) < 0)
unix_fatal("Disabled server %x bootstrap %x: \"%s\": setuid(%d)",
/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
server_cmd : cmd_t;
server_uid : integer_t;
on_demand : boolean_t;
- ServerSecToken token : security_token_t;
+ ServerAuditToken token : audit_token_t;
out server_port : mach_port_make_send_t);
/*
/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#import <stdlib.h>
#import <string.h>
+#import <bsm/audit.h>
+
#import "bootstrap_internal.h"
#import "lists.h"
#import "error_log.h"
bootstrap_info_t *bootstrap,
const char *cmd,
int uid,
- servertype_t servertype)
+ servertype_t servertype,
+ auditinfo_t auinfo)
{
server_t *serverp;
serverp->pid = NO_PID;
serverp->task_port = MACH_PORT_NULL;
+
serverp->uid = uid;
+ serverp->auinfo = auinfo;
serverp->port = MACH_PORT_NULL;
serverp->servertype = servertype;
#import <mach/boolean.h>
#import <servers/bootstrap_defs.h>
+#import <bsm/audit.h>
+
#ifndef NULL
#define NULL ((void *)0)
#endif NULL
server_t *next; /* list of all servers */
server_t *prev;
servertype_t servertype;
- cmd_t cmd; /* server command to exec */
- int uid; /* uid to exec server with */
+ int uid; /* uid to exec server with */
+ auditinfo_t auinfo; /* server's audit information */
mach_port_t port; /* server's priv bootstrap port */
mach_port_t task_port; /* server's task port */
pid_t pid; /* server's pid */
int activity; /* count of checkins/registers this instance */
int active_services;/* count of active services */
bootstrap_info_t *bootstrap; /* bootstrap context */
+ cmd_t cmd; /* server command to exec */
};
#define NO_PID (-1)
bootstrap_info_t *bootstrap,
const char *cmd,
int uid,
- servertype_t servertype);
+ servertype_t servertype,
+ auditinfo_t auinfo);
extern service_t *new_service(
bootstrap_info_t *bootstrap,
/*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#import <mach/mach.h>
#import <string.h>
+#import <bsm/audit.h>
+#import <bsm/libbsm.h>
+
#import "bootstrap_internal.h"
#import "error_log.h"
#import "lists.h"
cmd_t server_cmd,
int server_uid,
boolean_t on_demand,
- security_token_t sectoken,
+ audit_token_t client_audit_token,
mach_port_t *server_portp)
{
server_t *serverp;
+ struct auditinfo audit_info;
bootstrap_info_t *bootstrap;
+ uid_t client_euid;
+
bootstrap = lookup_bootstrap_by_port(bootstrap_port);
debug("Server create attempt: \"%s\" bootstrap %x",
server_cmd, bootstrap_port);
return BOOTSTRAP_NOT_PRIVILEGED;
}
- /* only same uid (or root client) */
- if (sectoken.val[0] && sectoken.val[0] != server_uid) {
- notice("Server create: \"%s\": invalid security token (%d != %d)",
- server_cmd, sectoken.val[0], server_uid);
+ /* get the identity of the requestor and set up audit_info of server */
+ audit_token_to_au32(client_audit_token,
+ &audit_info.ai_auid,
+ &client_euid,
+ NULL /* egid */,
+ NULL /* ruid */,
+ NULL /* rgid */,
+ NULL /* pid */,
+ &audit_info.ai_asid,
+ &audit_info.ai_termid);
+
+ if (client_euid != 0 && client_euid != server_uid) {
+ notice("Server create: \"%s\": insufficient privilege for specified uid (euid-%d != requested-%d)",
+ server_cmd, client_euid, server_uid);
return BOOTSTRAP_NOT_PRIVILEGED;
}
+
serverp = new_server(
bootstrap,
server_cmd,
server_uid,
- (on_demand) ? DEMAND : RESTARTABLE);
+ (on_demand) ? DEMAND : RESTARTABLE,
+ audit_info);
setup_server(serverp);
info("New server %x in bootstrap %x: \"%s\"",
#
-# Generated by the NeXT Project Builder.
+# Generated by the Apple Project Builder.
#
# NOTE: Do NOT change this file -- Project Builder maintains it.
#
NEXTSTEP_INSTALLDIR = /sbin
WINDOWS_INSTALLDIR = /sbin
PDO_UNIX_INSTALLDIR = /sbin
-LIBS =
+LIBS = -lbsm
DEBUG_LIBS = $(LIBS)
PROF_LIBS = $(LIBS)
APPCLASS = NSApplication;
FILESTABLE = {
FRAMEWORKS = ();
- H_FILES = (pathnames.h);
- M_FILES = ();
- OTHER_LIBS = ();
- OTHER_LINKED = (shutdown.c);
- OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, Makefile.dist, shutdown.8);
- PRECOMPILED_HEADERS = ();
- PROJECT_HEADERS = ();
- PUBLIC_HEADERS = ();
+ "H_FILES" = ("pathnames.h");
+ "M_FILES" = ();
+ "OTHER_LIBS" = (bsm);
+ "OTHER_LINKED" = ("shutdown.c");
+ "OTHER_SOURCES" = (
+ "Makefile.preamble",
+ Makefile,
+ "Makefile.postamble",
+ "Makefile.dist",
+ "shutdown.8"
+ );
+ "PRECOMPILED_HEADERS" = ();
+ "PROJECT_HEADERS" = ();
+ "PUBLIC_HEADERS" = ();
SUBPROJECTS = ();
};
LANGUAGE = English;
- LOCALIZABLE_FILES = {};
- NEXTSTEP_INSTALLDIR = /sbin;
- NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
- NEXTSTEP_MAINNIB = shutdown;
- NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
- PDO_UNIX_INSTALLDIR = /sbin;
- PDO_UNIX_JAVA_COMPILER = "$(NEXTDEV_BIN)/javac";
- PDO_UNIX_MAINNIB = shutdown;
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
+ "LOCALIZABLE_FILES" = {};
+ "NEXTSTEP_INSTALLDIR" = "/sbin";
+ "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_MAINNIB" = shutdown;
+ "NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
+ "PDO_UNIX_INSTALLDIR" = "/sbin";
+ "PDO_UNIX_JAVA_COMPILER" = "$(NEXTDEV_BIN)/javac";
+ "PDO_UNIX_MAINNIB" = shutdown;
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = shutdown;
PROJECTTYPE = Tool;
- PROJECTVERSION = 2.8;
- WINDOWS_INSTALLDIR = /sbin;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_MAINNIB = shutdown;
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+ PROJECTVERSION = "2.8";
+ "WINDOWS_INSTALLDIR" = "/sbin";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_MAINNIB" = shutdown;
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
}
#include <string.h>
#include <unistd.h>
+#include <errno.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+
#include "pathnames.h"
#ifdef __APPLE__
void timeout(int);
void timewarn(int);
void usage(const char *);
+int audit_shutdown(int);
int
main(argc, argv)
if (!(whom = getlogin()))
whom = (pw = getpwuid(getuid())) ? pw->pw_name : "???";
+
#ifdef DEBUG
+ audit_shutdown(0);
(void)putc('\n', stdout);
#else
(void)setpriority(PRIO_PROCESS, 0, PRIO_MIN);
int forkpid;
forkpid = fork();
- if (forkpid == -1)
+ if (forkpid == -1) {
+ audit_shutdown(1);
err(1, "fork");
- if (forkpid)
+ }
+ if (forkpid) {
errx(0, "[pid %d]", forkpid);
+ }
}
+ audit_shutdown(0);
setsid();
#endif
openlog("shutdown", LOG_CONS, LOG_AUTH);
" time [warning-message ...]\n");
exit(1);
}
+
+/*
+ * The following tokens are included in the audit record for shutdown
+ * header
+ * subject
+ * return
+ */
+int audit_shutdown(int exitstatus)
+{
+ int aufd;
+ token_t *tok;
+ long au_cond;
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "shutdown: Could not determine audit condition\n");
+ return 0;
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return 0;
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "shutdown: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ /* The subject that performed the operation */
+ if((tok = au_to_me()) == NULL) {
+ fprintf(stderr, "shutdown: Audit Error: au_to_me() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ /* success and failure status */
+ if((tok = au_to_return32(exitstatus, errno)) == NULL) {
+ fprintf(stderr, "shutdown: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_shutdown) == -1) {
+ fprintf(stderr, "shutdown: Audit Error: au_close() failed\n");
+ exit(1);
+ }
+ return 1;
+}
+