]> git.saurik.com Git - apple/system_cmds.git/commitdiff
system_cmds-279.6.tar.gz mac-os-x-1034 mac-os-x-1035 mac-os-x-1036 mac-os-x-1037 v279.6
authorApple <opensource@apple.com>
Tue, 13 Apr 2004 00:06:30 +0000 (00:06 +0000)
committerApple <opensource@apple.com>
Tue, 13 Apr 2004 00:06:30 +0000 (00:06 +0000)
33 files changed:
Makefile
PB.project
audit.tproj/Makefile [new file with mode: 0644]
audit.tproj/Makefile.postamble [new file with mode: 0644]
audit.tproj/Makefile.preamble [new file with mode: 0644]
audit.tproj/PB.project [new file with mode: 0644]
audit.tproj/audit.1 [new file with mode: 0644]
audit.tproj/audit.c [new file with mode: 0644]
audit.tproj/auditd_control.defs [new file with mode: 0644]
auditd.tproj/Makefile [new file with mode: 0644]
auditd.tproj/Makefile.postamble [new file with mode: 0644]
auditd.tproj/Makefile.preamble [new file with mode: 0644]
auditd.tproj/PB.project [new file with mode: 0644]
auditd.tproj/audit_triggers.defs [new file with mode: 0644]
auditd.tproj/audit_warn.c [new file with mode: 0644]
auditd.tproj/auditd.8 [new file with mode: 0644]
auditd.tproj/auditd.c [new file with mode: 0644]
auditd.tproj/auditd.h [new file with mode: 0644]
auditd.tproj/auditd_control.defs [new file with mode: 0644]
auditd.tproj/rc.audit [new file with mode: 0644]
login.tproj/Makefile
login.tproj/PB.project
login.tproj/login.c
mach_init.tproj/Makefile
mach_init.tproj/PB.project
mach_init.tproj/bootstrap.c
mach_init.tproj/bootstrap.defs
mach_init.tproj/lists.c
mach_init.tproj/lists.h
mach_init.tproj/rpc_services.c
shutdown.tproj/Makefile
shutdown.tproj/PB.project
shutdown.tproj/shutdown.c

index 9d65a8de4e9e5625c5f2ac2a98f2602ea81f0825..49575949e21036bdbe96df450090e022ec7b9e56 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,15 +12,15 @@ NAME = system_cmds
 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
 
index 5d1d3567a733bf4d288ffe079b1ea359bee5cf6e..77f4a66b5cb9e31c4396e7592fa6a7d50ffc35f5 100644 (file)
         "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", 
@@ -53,8 +55,7 @@
             "fs_usage.tproj", 
             "kdump.tproj", 
             "sadc.tproj", 
-            "sar.tproj"
-        ); 
+            "sar.tproj"        ); 
     }; 
     LANGUAGE = English; 
     "LOCALIZABLE_FILES" = {}; 
diff --git a/audit.tproj/Makefile b/audit.tproj/Makefile
new file mode 100644 (file)
index 0000000..3ad050e
--- /dev/null
@@ -0,0 +1,50 @@
+#
+# 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
diff --git a/audit.tproj/Makefile.postamble b/audit.tproj/Makefile.postamble
new file mode 100644 (file)
index 0000000..f093dff
--- /dev/null
@@ -0,0 +1,86 @@
+###############################################################################
+#  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
diff --git a/audit.tproj/Makefile.preamble b/audit.tproj/Makefile.preamble
new file mode 100644 (file)
index 0000000..e196000
--- /dev/null
@@ -0,0 +1,19 @@
+###############################################################################
+#  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
+
diff --git a/audit.tproj/PB.project b/audit.tproj/PB.project
new file mode 100644 (file)
index 0000000..e0c75af
--- /dev/null
@@ -0,0 +1,32 @@
+{
+    "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"; 
+}
diff --git a/audit.tproj/audit.1 b/audit.tproj/audit.1
new file mode 100644 (file)
index 0000000..3b800a8
--- /dev/null
@@ -0,0 +1,43 @@
+.\" 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
diff --git a/audit.tproj/audit.c b/audit.tproj/audit.c
new file mode 100644 (file)
index 0000000..54b251f
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * 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");
+}
diff --git a/audit.tproj/auditd_control.defs b/audit.tproj/auditd_control.defs
new file mode 100644 (file)
index 0000000..a4267ee
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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"
diff --git a/auditd.tproj/Makefile b/auditd.tproj/Makefile
new file mode 100644 (file)
index 0000000..edb12d0
--- /dev/null
@@ -0,0 +1,52 @@
+#
+# 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
diff --git a/auditd.tproj/Makefile.postamble b/auditd.tproj/Makefile.postamble
new file mode 100644 (file)
index 0000000..3b19087
--- /dev/null
@@ -0,0 +1,121 @@
+###############################################################################
+#  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
diff --git a/auditd.tproj/Makefile.preamble b/auditd.tproj/Makefile.preamble
new file mode 100644 (file)
index 0000000..162794a
--- /dev/null
@@ -0,0 +1,18 @@
+###############################################################################
+#  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
diff --git a/auditd.tproj/PB.project b/auditd.tproj/PB.project
new file mode 100644 (file)
index 0000000..f3df43c
--- /dev/null
@@ -0,0 +1,38 @@
+{
+    "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"; 
+}
diff --git a/auditd.tproj/audit_triggers.defs b/auditd.tproj/audit_triggers.defs
new file mode 100644 (file)
index 0000000..9fe2c35
--- /dev/null
@@ -0,0 +1 @@
+#include <mach/audit_triggers.defs>
diff --git a/auditd.tproj/audit_warn.c b/auditd.tproj/audit_warn.c
new file mode 100644 (file)
index 0000000..22657a1
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * 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);
+}
diff --git a/auditd.tproj/auditd.8 b/auditd.tproj/auditd.8
new file mode 100644 (file)
index 0000000..c5a9b15
--- /dev/null
@@ -0,0 +1,48 @@
+.\" 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
diff --git a/auditd.tproj/auditd.c b/auditd.tproj/auditd.c
new file mode 100644 (file)
index 0000000..459bee3
--- /dev/null
@@ -0,0 +1,791 @@
+/*
+ * 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);
+}
diff --git a/auditd.tproj/auditd.h b/auditd.tproj/auditd.h
new file mode 100644 (file)
index 0000000..5866377
--- /dev/null
@@ -0,0 +1,51 @@
+#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_ */
+
diff --git a/auditd.tproj/auditd_control.defs b/auditd.tproj/auditd_control.defs
new file mode 100644 (file)
index 0000000..1cf8346
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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);
+
diff --git a/auditd.tproj/rc.audit b/auditd.tproj/rc.audit
new file mode 100644 (file)
index 0000000..799dc3c
--- /dev/null
@@ -0,0 +1,25 @@
+##
+# 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
index 66d930a81b91a4e18648c7e1b73d45490eefa530..fda2a0c24cfef26b6d62694ae89ef90b5f7c95c5 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Generated by the NeXT Project Builder.
+# Generated by the Apple Project Builder.
 #
 # NOTE: Do NOT change this file -- Project Builder maintains it.
 #
@@ -25,7 +25,7 @@ MAKEFILE = tool.make
 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)
 
index 5ee51ca0de16db40df6c58942c7bfcfccb242a38..dbf43ab669806bef6f1d35130d9a2e8602dfacda 100644 (file)
@@ -1,25 +1,25 @@
 {
     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"; 
 }
index 4bcf731d848f38ff438b636ad1dc4ed3e6986e4e..ebedd0e0014f8783499b52c01f24e1d92f6f6aaf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -87,6 +87,15 @@ static char copyright[] =
 #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>
@@ -107,6 +116,9 @@ void         timedout __P((int));
 #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 *));
 
@@ -129,6 +141,9 @@ struct      passwd *pwd;
 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;
@@ -153,6 +168,8 @@ main(argc, argv)
        pid_t pid;
 #endif
 
+       char auditsuccess = 1;
+
        (void)signal(SIGALRM, timedout);
        (void)alarm(timeout);
        (void)signal(SIGQUIT, SIG_IGN);
@@ -161,6 +178,7 @@ main(argc, argv)
 
        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
@@ -228,27 +246,44 @@ main(argc, argv)
        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);
        }
 
@@ -261,6 +296,7 @@ main(argc, argv)
 
        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);
@@ -268,6 +304,11 @@ main(argc, argv)
                                (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;
@@ -283,6 +324,7 @@ main(argc, argv)
                        pam_get_item(pamh, PAM_USER, (void *)&username);
                        badlogin(username);
                        printf("Login incorrect\n");
+                       au_fail("Login incorrect", 1);
                        exit(1);
                }
 
@@ -292,8 +334,10 @@ main(argc, argv)
                }
                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);
@@ -303,12 +347,14 @@ main(argc, argv)
        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);
        }
 
@@ -336,8 +382,9 @@ main(argc, argv)
                 * 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);
@@ -400,6 +447,7 @@ main(argc, argv)
                                syslog(LOG_NOTICE,
                                    "LOGIN %s REFUSED ON TTY %s",
                                     pwd->pw_name, tty);
+                       au_fail("Login refused on terminal", 0);
                        continue;
                }
 
@@ -412,8 +460,10 @@ main(argc, argv)
                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));
                }
        }
@@ -428,25 +478,32 @@ main(argc, argv)
        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));
@@ -546,6 +603,7 @@ main(argc, argv)
        else
                (void) setuid(pwd->pw_uid);
 
+       
        execlp(pwd->pw_shell, tbuf, 0);
        err(1, "%s", pwd->pw_shell);
 }
@@ -556,6 +614,142 @@ main(argc, argv)
 #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()
 {
@@ -642,6 +836,8 @@ checknologin()
        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);
        }
 }
index 57431ebc3ee901c81f7ce5c4de09c5898ff3318f..6bb2bb1f200811d9762803125acd7dc0e1f78fc3 100644 (file)
@@ -26,7 +26,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /sbin
 WINDOWS_INSTALLDIR = /sbin
 PDO_UNIX_INSTALLDIR = /sbin
-LIBS = 
+LIBS = -lbsm
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
index c09942842326c4590e7429f8e0efd8750249fb9d..0fec5888b8fcd9052f953ef18dd398e3b815f3f1 100644 (file)
@@ -9,7 +9,7 @@
         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", 
index adc03f8c691cbdd445779f59a64430f00f713048..81e49bc666d3ac2049251796fb8ae7ac65ebe106 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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"
 
@@ -74,7 +78,8 @@ const char *program_name;     /* our name for error messages */
 #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;
@@ -202,16 +207,6 @@ main(int argc, char * argv[])
        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,
@@ -274,6 +269,14 @@ main(int argc, char * argv[])
                                                        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;
 
@@ -330,6 +333,7 @@ main(int argc, char * argv[])
         */
        bootstrap_self = mach_task_self();
        inherited_uid = getuid();
+       getaudit(&inherited_audit);
        init_lists();
        init_ports();
 
@@ -406,8 +410,9 @@ main(int argc, char * argv[])
        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" : "");
@@ -791,6 +796,30 @@ exec_server(server_t *serverp)
        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)",
index 55c0b32253f8212c2ea35309862a1b31faa121f7..de1819d91d84cddad1d219fd4c70df4aa8f092a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -140,7 +140,7 @@ routine bootstrap_create_server(
                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);
 
 /*
index 770ba820d6b86b04ad868ea03f25dbd81392a8a3..646fe835f03d809efe7ab8eccada0048c65c88d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,6 +35,8 @@
 #import <stdlib.h>
 #import <string.h>
 
+#import <bsm/audit.h>
+
 #import "bootstrap_internal.h"
 #import "lists.h"
 #import "error_log.h"
@@ -75,7 +77,8 @@ new_server(
        bootstrap_info_t        *bootstrap,
        const char              *cmd,
        int                     uid,
-       servertype_t            servertype)
+       servertype_t            servertype,
+       auditinfo_t             auinfo)
 {
        server_t *serverp;
 
@@ -93,7 +96,9 @@ new_server(
 
                serverp->pid = NO_PID;
                serverp->task_port = MACH_PORT_NULL;
+
                serverp->uid = uid;
+               serverp->auinfo = auinfo;
 
                serverp->port = MACH_PORT_NULL;
                serverp->servertype = servertype;
index f09942e177ddac65d9cddf511e37938c8932f365..23e8ce5b393e355d4154c1396b85aa4d7c829a53 100644 (file)
@@ -34,6 +34,8 @@
 #import <mach/boolean.h>
 #import <servers/bootstrap_defs.h>
 
+#import <bsm/audit.h>
+
 #ifndef NULL
 #define        NULL    ((void *)0)
 #endif NULL
@@ -87,14 +89,15 @@ struct server {
        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)
@@ -105,7 +108,8 @@ extern server_t *new_server(
        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,
index eba0cc25f4c29eef5969a62a533a4b93c676dc0d..69168ef1ec3468eb9e264e434726de45491be116 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -32,6 +32,9 @@
 #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"
@@ -74,12 +77,15 @@ x_bootstrap_create_server(
        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);
@@ -91,17 +97,29 @@ x_bootstrap_create_server(
                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\"",
index 73d25a81540d710a06dfb671e119c8a1044aa919..e402bec41bfaa8ce13f8a4ee97e794187337c703 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Generated by the NeXT Project Builder.
+# Generated by the Apple Project Builder.
 #
 # NOTE: Do NOT change this file -- Project Builder maintains it.
 #
@@ -26,7 +26,7 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /sbin
 WINDOWS_INSTALLDIR = /sbin
 PDO_UNIX_INSTALLDIR = /sbin
-LIBS = 
+LIBS = -lbsm
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
index 87cbc03aff447c420963fb8c9d704da782c0ef8e..920e6633cabef57acb88b8d6ee4c351cae613008 100644 (file)
@@ -2,31 +2,37 @@
     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"; 
 }
index 3b1b795b335fae0d2c5066548fb1178bf1ce7069..2bd40455ee71b9114050fa19c9dd9ff96d9cb037 100644 (file)
@@ -61,6 +61,11 @@ static const char rcsid[] =
 #include <string.h>
 #include <unistd.h>
 
+#include <errno.h>
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
+
 #include "pathnames.h"
 
 #ifdef __APPLE__
@@ -110,6 +115,7 @@ void nolog(void);
 void timeout(int);
 void timewarn(int);
 void usage(const char *);
+int audit_shutdown(int);
 
 int
 main(argc, argv)
@@ -222,7 +228,9 @@ 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);
@@ -230,11 +238,15 @@ main(argc, argv)
                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);
@@ -557,3 +569,50 @@ usage(cp)
            " 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;
+}
+