diff -N -u -r linux-2.4.22/arch/alpha/config.in snare-kernel/linux-2.4.22-snare/arch/alpha/config.in
--- linux-2.4.22/arch/alpha/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/alpha/config.in	2003-10-06 14:56:17.000000000 +1000
@@ -298,6 +298,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
diff -N -u -r linux-2.4.22/arch/alpha/defconfig snare-kernel/linux-2.4.22-snare/arch/alpha/defconfig
--- linux-2.4.22/arch/alpha/defconfig	2003-06-14 00:51:29.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/alpha/defconfig	2003-10-06 14:57:43.000000000 +1000
@@ -67,6 +67,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/arm/config.in snare-kernel/linux-2.4.22-snare/arch/arm/config.in
--- linux-2.4.22/arch/arm/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/arm/config.in	2003-10-06 14:56:22.000000000 +1000
@@ -485,6 +485,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 comment 'At least one math emulation must be selected'
 tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
diff -N -u -r linux-2.4.22/arch/arm/defconfig snare-kernel/linux-2.4.22-snare/arch/arm/defconfig
--- linux-2.4.22/arch/arm/defconfig	2001-05-20 10:43:05.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/arm/defconfig	2003-10-06 14:57:46.000000000 +1000
@@ -79,6 +79,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_NWFPE=y
 CONFIG_KCORE_ELF=y
diff -N -u -r linux-2.4.22/arch/cris/config.in snare-kernel/linux-2.4.22-snare/arch/cris/config.in
--- linux-2.4.22/arch/cris/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/cris/config.in	2003-10-06 14:56:28.000000000 +1000
@@ -28,6 +28,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
diff -N -u -r linux-2.4.22/arch/cris/defconfig snare-kernel/linux-2.4.22-snare/arch/cris/defconfig
--- linux-2.4.22/arch/cris/defconfig	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/cris/defconfig	2003-10-06 14:57:51.000000000 +1000
@@ -16,6 +16,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 # CONFIG_SYSCTL is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_ETRAX_KGDB is not set
diff -N -u -r linux-2.4.22/arch/i386/config.in snare-kernel/linux-2.4.22-snare/arch/i386/config.in
--- linux-2.4.22/arch/i386/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/i386/config.in	2003-10-06 14:56:32.000000000 +1000
@@ -314,6 +314,7 @@
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
diff -N -u -r linux-2.4.22/arch/i386/defconfig snare-kernel/linux-2.4.22-snare/arch/i386/defconfig
--- linux-2.4.22/arch/i386/defconfig	2002-11-29 10:53:09.000000000 +1100
+++ snare-kernel/linux-2.4.22-snare/arch/i386/defconfig	2003-10-06 14:57:55.000000000 +1000
@@ -101,6 +101,7 @@
 # CONFIG_HOTPLUG_PCI_ACPI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/ia64/config.in snare-kernel/linux-2.4.22-snare/arch/ia64/config.in
--- linux-2.4.22/arch/ia64/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ia64/config.in	2003-10-06 14:56:36.000000000 +1000
@@ -95,6 +95,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff -N -u -r linux-2.4.22/arch/ia64/defconfig snare-kernel/linux-2.4.22-snare/arch/ia64/defconfig
--- linux-2.4.22/arch/ia64/defconfig	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ia64/defconfig	2003-10-06 14:57:58.000000000 +1000
@@ -57,6 +57,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
diff -N -u -r linux-2.4.22/arch/m68k/config.in snare-kernel/linux-2.4.22-snare/arch/m68k/config.in
--- linux-2.4.22/arch/m68k/config.in	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/m68k/config.in	2003-10-06 14:56:40.000000000 +1000
@@ -91,6 +91,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
diff -N -u -r linux-2.4.22/arch/m68k/defconfig snare-kernel/linux-2.4.22-snare/arch/m68k/defconfig
--- linux-2.4.22/arch/m68k/defconfig	2000-06-20 05:56:08.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/m68k/defconfig	2003-10-06 14:58:02.000000000 +1000
@@ -41,6 +41,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/mips/defconfig snare-kernel/linux-2.4.22-snare/arch/mips/defconfig
--- linux-2.4.22/arch/mips/defconfig	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/mips/defconfig	2003-10-06 14:58:10.000000000 +1000
@@ -127,6 +127,7 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/mips64/defconfig snare-kernel/linux-2.4.22-snare/arch/mips64/defconfig
--- linux-2.4.22/arch/mips64/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/mips64/defconfig	2003-10-06 14:58:06.000000000 +1000
@@ -127,6 +127,7 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/parisc/config.in snare-kernel/linux-2.4.22-snare/arch/parisc/config.in
--- linux-2.4.22/arch/parisc/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/parisc/config.in	2003-10-06 14:56:46.000000000 +1000
@@ -82,6 +82,7 @@
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 define_bool CONFIG_KCORE_ELF y
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
diff -N -u -r linux-2.4.22/arch/parisc/defconfig snare-kernel/linux-2.4.22-snare/arch/parisc/defconfig
--- linux-2.4.22/arch/parisc/defconfig	2003-06-14 00:51:31.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/parisc/defconfig	2003-10-06 14:58:14.000000000 +1000
@@ -53,6 +53,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
diff -N -u -r linux-2.4.22/arch/ppc/config.in snare-kernel/linux-2.4.22-snare/arch/ppc/config.in
--- linux-2.4.22/arch/ppc/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ppc/config.in	2003-10-06 14:56:54.000000000 +1000
@@ -201,6 +201,7 @@
 bool 'Sysctl support' CONFIG_SYSCTL
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 
 # only elf supported, a.out is not -- Cort
 if [ "$CONFIG_PROC_FS" = "y" ]; then
diff -N -u -r linux-2.4.22/arch/ppc/defconfig snare-kernel/linux-2.4.22-snare/arch/ppc/defconfig
--- linux-2.4.22/arch/ppc/defconfig	2003-06-14 00:51:31.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ppc/defconfig	2003-10-06 14:58:20.000000000 +1000
@@ -56,6 +56,7 @@
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
diff -N -u -r linux-2.4.22/arch/ppc64/config.in snare-kernel/linux-2.4.22-snare/arch/ppc64/config.in
--- linux-2.4.22/arch/ppc64/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ppc64/config.in	2003-10-06 14:56:50.000000000 +1000
@@ -72,6 +72,7 @@
 bool 'Sysctl support' CONFIG_SYSCTL
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 
 # only elf supported, a.out is not -- Cort
 if [ "$CONFIG_PROC_FS" = "y" ]; then
diff -N -u -r linux-2.4.22/arch/ppc64/defconfig snare-kernel/linux-2.4.22-snare/arch/ppc64/defconfig
--- linux-2.4.22/arch/ppc64/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/ppc64/defconfig	2003-10-06 14:58:17.000000000 +1000
@@ -51,6 +51,7 @@
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_ELF32=y
diff -N -u -r linux-2.4.22/arch/s390/config.in snare-kernel/linux-2.4.22-snare/arch/s390/config.in
--- linux-2.4.22/arch/s390/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/s390/config.in	2003-10-06 14:56:57.000000000 +1000
@@ -52,6 +52,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 define_bool CONFIG_KCORE_ELF y
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
diff -N -u -r linux-2.4.22/arch/s390/defconfig snare-kernel/linux-2.4.22-snare/arch/s390/defconfig
--- linux-2.4.22/arch/s390/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/s390/defconfig	2003-10-06 14:58:23.000000000 +1000
@@ -40,6 +40,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
diff -N -u -r linux-2.4.22/arch/s390x/config.in snare-kernel/linux-2.4.22-snare/arch/s390x/config.in
--- linux-2.4.22/arch/s390x/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/s390x/config.in	2003-10-06 14:57:03.000000000 +1000
@@ -55,6 +55,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 define_bool CONFIG_KCORE_ELF y
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
diff -N -u -r linux-2.4.22/arch/s390x/defconfig snare-kernel/linux-2.4.22-snare/arch/s390x/defconfig
--- linux-2.4.22/arch/s390x/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/s390x/defconfig	2003-10-06 14:58:31.000000000 +1000
@@ -41,6 +41,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
diff -N -u -r linux-2.4.22/arch/sh/config.in snare-kernel/linux-2.4.22-snare/arch/sh/config.in
--- linux-2.4.22/arch/sh/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sh/config.in	2003-10-06 14:57:13.000000000 +1000
@@ -256,6 +256,7 @@
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    choice 'Kernel core (/proc/kcore) format' \
diff -N -u -r linux-2.4.22/arch/sh/defconfig snare-kernel/linux-2.4.22-snare/arch/sh/defconfig
--- linux-2.4.22/arch/sh/defconfig	2001-10-16 06:36:48.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sh/defconfig	2003-10-06 14:58:39.000000000 +1000
@@ -44,6 +44,7 @@
 # CONFIG_PCMCIA is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 # CONFIG_SYSCTL is not set
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/sh64/config.in snare-kernel/linux-2.4.22-snare/arch/sh64/config.in
--- linux-2.4.22/arch/sh64/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sh64/config.in	2003-10-06 14:57:09.000000000 +1000
@@ -142,6 +142,7 @@
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 # bool 'Sysctl support' CONFIG_SYSCTL
 define_bool CONFIG_SYSCTL y
 
diff -N -u -r linux-2.4.22/arch/sh64/defconfig snare-kernel/linux-2.4.22-snare/arch/sh64/defconfig
--- linux-2.4.22/arch/sh64/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sh64/defconfig	2003-10-06 14:58:36.000000000 +1000
@@ -78,6 +78,7 @@
 # CONFIG_PCMCIA is not set
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
diff -N -u -r linux-2.4.22/arch/sparc/config.in snare-kernel/linux-2.4.22-snare/arch/sparc/config.in
--- linux-2.4.22/arch/sparc/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sparc/config.in	2003-10-06 14:57:19.000000000 +1000
@@ -64,6 +64,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
diff -N -u -r linux-2.4.22/arch/sparc/defconfig snare-kernel/linux-2.4.22-snare/arch/sparc/defconfig
--- linux-2.4.22/arch/sparc/defconfig	2002-08-03 10:39:43.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sparc/defconfig	2003-10-06 14:58:48.000000000 +1000
@@ -47,6 +47,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_AOUT=y
diff -N -u -r linux-2.4.22/arch/sparc64/config.in snare-kernel/linux-2.4.22-snare/arch/sparc64/config.in
--- linux-2.4.22/arch/sparc64/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sparc64/config.in	2003-10-06 14:57:16.000000000 +1000
@@ -63,6 +63,7 @@
 bool 'Networking support' CONFIG_NET
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
diff -N -u -r linux-2.4.22/arch/sparc64/defconfig snare-kernel/linux-2.4.22-snare/arch/sparc64/defconfig
--- linux-2.4.22/arch/sparc64/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/sparc64/defconfig	2003-10-06 14:58:44.000000000 +1000
@@ -49,6 +49,7 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_SPARC32_COMPAT=y
diff -N -u -r linux-2.4.22/arch/x86_64/config.in snare-kernel/linux-2.4.22-snare/arch/x86_64/config.in
--- linux-2.4.22/arch/x86_64/config.in	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/x86_64/config.in	2003-10-06 14:57:22.000000000 +1000
@@ -100,6 +100,7 @@
 
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+bool 'SNARE C2 Auditing' CONFIG_C2_AUDIT
 bool 'Sysctl support' CONFIG_SYSCTL
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
diff -N -u -r linux-2.4.22/arch/x86_64/defconfig snare-kernel/linux-2.4.22-snare/arch/x86_64/defconfig
--- linux-2.4.22/arch/x86_64/defconfig	2003-08-25 21:44:40.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/arch/x86_64/defconfig	2003-10-06 14:58:53.000000000 +1000
@@ -59,6 +59,7 @@
 # CONFIG_HOTPLUG_PCI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_C2_AUDIT is not set
 CONFIG_SYSCTL=y
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
diff -N -u -r linux-2.4.22/audit/auditapi.c snare-kernel/linux-2.4.22-snare/audit/auditapi.c
--- linux-2.4.22/audit/auditapi.c	1970-01-01 10:00:00.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/audit/auditapi.c	2003-09-28 05:45:22.000000000 +1000
@@ -0,0 +1,1700 @@
+/* $Id: audit.c, v 0.9.4 2003/09/06 18:14:07$
+ *
+ * audit/auditapi.c
+ *
+ * Copyright 2002-2003 InterSect Alliance Pty Ltd - www.intersectalliance.com
+ */
+
+#include <linux/config.h>
+
+// If CONFIG_C2_AUDIT is not defined, do NOTHING.
+// See also: linux/audit.h - if not configured, all audit_*
+// routines will be optimised out of existance by gcc.
+// (Thanks to Alan Cox for the suggestion).
+#ifdef CONFIG_C2_AUDIT
+
+
+// Total events and lost events not working now do not show
+// Modification By mark.westerman@westcam.com
+#define SHOW_EVENT_COUNTER 0
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/audit.h>
+
+#include <net/sock.h>
+
+#include <asm/unistd.h>
+#include <asm/uaccess.h>
+
+// Function prototypes
+static int info_open(struct inode *inode, struct file *file);
+static ssize_t		info_read(struct file *file, char *ubuf, size_t length, loff_t *ppos);
+static int		info_close(struct inode *inode, struct file *file);
+
+static int		auditproc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+static int		auditproc_open(struct inode *, struct file *);
+static int		auditproc_close(struct inode *, struct file *);
+static ssize_t		auditproc_read(struct file *, char *, size_t, loff_t *);
+
+void			audit_on(int auditnumber);
+void			audit_off(int auditnumber);
+int			audit_active(int auditnumber);
+
+AuditNode *		alloc_event(int token_size);
+void			append_event(AuditNode *nodepointer);
+
+static DECLARE_MUTEX(audit_lock);
+static struct task_struct *auditdaemon_task_struct;        // Daemon interaction
+
+// If we have the audit daemon attached
+static int AUDIT_IS_RUNNING=0;
+
+// How many packets have we lost this session due to low buffer size?
+static int lost_events=0;
+static int total_events=0;
+
+// Linked list of audit events - used as an internal buffer
+// so that we don't slow down the kernel significantly while waiting
+// for the user space audit daemon to catch up.
+AuditNode * list_head=(AuditNode *)NULL;
+AuditNode * list_tail=(AuditNode *)NULL;
+
+// Audit daemon read position
+static void *read_position = (void *)NULL;
+
+// Setup a bitmask to work out which audit events are currently active.
+static unsigned active_events[(MAXAUDIT + sizeof(long)-1) / sizeof(long)];
+
+static struct file_operations file_ops =
+{
+	        read:   auditproc_read,               // read
+	        ioctl:  auditproc_ioctl,              // ioctl
+	        open:   auditproc_open,               // open
+	        release:        auditproc_close,      // release
+};
+
+static struct file_operations info_ops =
+{
+	        read:   info_read,		// read
+	        open:   info_open,
+	        release:        info_close,
+};
+
+struct proc_dir_entry *ProcInfoEntry;
+struct proc_dir_entry *ProcEntry;
+
+wait_queue_head_t proc_audit_queue;
+
+// Initialise our audit environment
+void audit_init(void)
+{
+	// Initialise audit here
+	// - create /proc entries etc.
+	printk("SNARE Audit capability is initialising\n");
+
+	if((ProcInfoEntry = create_proc_entry(AUDITINFO_NAME, S_IRUGO | S_IWUSR, NULL)) == NULL)
+	{
+		printk("Audit: Cannot create /proc/auditinfo");
+		return;
+	}
+	ProcInfoEntry->proc_fops = &info_ops;
+
+	if ((ProcEntry = create_proc_entry(AUDITDEV_NAME, S_IRUSR | S_IWUSR, NULL)) == NULL)
+		return;
+
+	ProcEntry->proc_fops = &file_ops;
+
+	// Initialise the wait queue for blocking read
+	init_waitqueue_head(&proc_audit_queue);
+}
+
+static int info_open(struct inode *inode, struct file *file)
+{
+	enum { DATA_LEN = 150 };
+	char *data;
+	char processid[20];
+
+	down(&audit_lock);
+	if((data = kmalloc(DATA_LEN, GFP_KERNEL)) == NULL)
+		return(0);
+
+	if(auditdaemon_task_struct != NULL) {
+		snprintf(processid, 20, "%d", (int)auditdaemon_task_struct->pid);
+	} else {
+		snprintf(processid, 20, "No Daemon Running");
+	}
+#if SHOW_EVENT_COUNTER 
+	snprintf(data, DATA_LEN,
+		"SNARE Version: %d.%d.%d\n"
+		"Audit Active: %s\n"
+		"Audit Process ID: %s\n"
+		"Events Lost This Session: %d\n"
+	        "Events Processed This Session: %d\n",
+	        SNAREAUDIT_MAJOR_VERSION, SNAREAUDIT_MINOR_VERSION,
+		SNAREAUDIT_PATCH_VERSION, (AUDIT_IS_RUNNING ? "no":"yes"),
+		processid, lost_events, total_events);
+#else
+	snprintf(data, DATA_LEN,
+		"SNARE Version: %d.%d.%d\n"
+		"Audit Active: %s\n"
+		"Audit Process ID: %s\n",
+	        SNAREAUDIT_MAJOR_VERSION, SNAREAUDIT_MINOR_VERSION,
+		SNAREAUDIT_PATCH_VERSION, (AUDIT_IS_RUNNING ? "no":"yes"),
+		processid);
+#endif	
+
+	up(&audit_lock);
+
+	if(data == NULL)
+		return -ENODEV;
+
+	file->private_data = data;
+
+	return(0);
+}
+
+static int info_close(struct inode *inode, struct file *file)
+{
+	kfree(file->private_data);
+	return(0);
+}
+
+static ssize_t info_read(struct file *file, char *ubuf, size_t length, loff_t *ppos)
+{
+	int bytes_to_write=0;
+	int pos = *ppos;
+	char *data = file->private_data;
+
+	// User has asked for a zero-length read?
+	if(length == 0)
+		return(0);
+
+	if ((bytes_to_write = strlen(data) - pos) <= 0)
+                return 0;		// EOF
+        if (bytes_to_write >= length)
+                bytes_to_write = length;
+        if (copy_to_user(ubuf, data + pos, bytes_to_write))
+                return -EFAULT;
+        *ppos = pos + bytes_to_write;
+        return(bytes_to_write);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// This routine handles ioctl messages from the audit daemon.
+////////////////////////////////////////////////////////////////////////////////
+
+int auditproc_ioctl(struct inode* node, struct file*  the_file, unsigned int  command, unsigned long arg)
+{
+	// If the audit facility is running, there is not much point starting again!
+	if((AUDIT_IS_RUNNING) && (command == AUDIT_START))
+		return -EBUSY;
+
+	if(command == AUDIT_START) {
+		down(&audit_lock);
+		AUDIT_IS_RUNNING = 1;
+		up(&audit_lock);
+	} else if(command == AUDIT_STOP) {
+		down(&audit_lock);
+		AUDIT_IS_RUNNING = 0;
+		up(&audit_lock);
+	} else if(command == AUDIT_LOSTEVENTS) {
+		return(lost_events);
+	} else if(command == AUDIT_TOTALEVENTS) {
+		return(total_events);
+	} else if (command == AUDIT_EVENT_ON) {
+		audit_on(arg);
+	} else if (command == AUDIT_EVENT_OFF) {
+		audit_off(arg);
+		// Eg: ioctl(x,SYS_exit);
+	} else if (command == AUDIT_FLUSH) {
+			// Turn off all auditing.
+			// This is generally sent when /etc/audit/audit.conf has been updated
+			// and the user wishes to establish a new audit policy.
+			int counter;
+			for(counter=1; counter<=MAXAUDIT; counter++) {
+				if(audit_active(counter)) audit_off(counter);
+			}		
+
+			// Also reset the lost/total event counters here.
+			lost_events=0;
+			total_events=0;
+	} else {
+		return -ENOSYS;	// Redhat kernel team suggest ENOTTY ? Clarify this.
+	}
+
+	return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Here we give the user the data.
+// NOTE that this module may be executed at any time - even in the middle
+// of the execution of something else. Hence, any variables that are changed
+// by this routine should be surrounded by a kernel lock if they are used
+// elsewhere!
+//
+// In particular:
+//  read_position
+//  list_head
+//  list_tail
+//
+// Let me just repeat this in another way:
+// WARNING: DO NOT CHANGE OR RELY ON THE VARIABLES ABOVE UNLESS YOU ARE
+//		  IN A LOCKED STATE - THEY MAY BE CORRUPTED BY THE
+//		  AUDIT_READ MODULE, WHICH IS CALLED BY SIGNAL/INTERRUPT
+//
+// Unfortunately, we also need lock within this routine also.
+// Otherwise, an interrupt might occur when we were half way through modifying
+// something like read_position - and if the interrupt happens to generate an
+// audit event, then we may be copying data to the wrong location in the array,
+// leading to data corruption.
+// Locking too much code slows down the system unfortunately. I'll try
+// and keep it minimal.
+////////////////////////////////////////////////////////////////////////////////
+
+static ssize_t auditproc_read(struct file *file, char *filebuffer, size_t length, loff_t *ppos)
+{
+	// Number of bytes actually written to the buffer
+	int bytes_avail_to_send=0;
+	int bytes_to_write=0;
+
+	if(length == 0)
+		return(0);	// Only want zero bytes? Here they are.
+
+	if(ppos != &file->f_pos) return -ESPIPE;	// No pread() thanks.
+
+	// Lock the kernel
+	down(&audit_lock);
+
+	// Just in case we have received a terminate request.
+	if(AUDIT_IS_RUNNING == 0 || auditdaemon_task_struct == NULL) {
+		up(&audit_lock);
+		return(0);
+	}
+
+	// Do we have any data?
+	if(list_head == (AuditNode *)NULL) {
+		up(&audit_lock);
+		if(file->f_flags & O_NONBLOCK) {
+			return -EAGAIN;
+		}
+		if(wait_event_interruptible(proc_audit_queue, list_head)) {
+			return -ERESTARTSYS;
+		}
+		down(&audit_lock);
+	}
+
+	if(read_position==(void *)NULL) {
+		// Our first time into this routine, or first time back after all data has been read.
+		read_position=list_head->location;
+	}
+
+	bytes_avail_to_send = (int)(((void *)list_head->location + list_head->size) - (void *)read_position);
+
+	while(bytes_avail_to_send < length) {
+		up(&audit_lock);
+		if(file->f_flags & O_NONBLOCK) {
+			return -EAGAIN;
+		}
+
+		if(wait_event_interruptible(proc_audit_queue,
+			(bytes_avail_to_send =
+			 (int) (list_head->location +
+				list_head->size -
+				read_position)) >=
+			 length)) {
+			return -ERESTARTSYS;
+		}
+		down(&audit_lock);
+	}
+	bytes_to_write = length;
+
+	if(copy_to_user(filebuffer,read_position,bytes_to_write))
+	{
+		up(&audit_lock);
+		return -EFAULT;
+	}
+
+	read_position += bytes_to_write;
+
+	// Have we reached the end of the current nodes data?
+	if((void *)read_position >= ((void *)list_head->location + list_head->size)) {
+		AuditNode *tempnode;
+
+		tempnode = list_head;
+		list_head = list_head->next;
+		
+		// Excellent, we're at the end of the current audit event.
+		// Remove this from the linked list, and set the read_position to the next record.
+		if(list_head != (AuditNode *)NULL) {
+			read_position = list_head->location;
+		} else {
+			read_position = (AuditNode *)NULL;
+		}
+
+		// No events remaining? Set list_tail to null also.
+		if(tempnode->next == (AuditNode *)NULL) {
+			list_tail=(AuditNode *)NULL;
+		}
+	
+		kfree(tempnode->location);
+		kfree(tempnode);
+	}
+	
+	up(&audit_lock);
+
+	return(bytes_to_write);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// open the device
+////////////////////////////////////////////////////////////////////////////////
+static int auditproc_open(struct inode* node, struct file*  the_file)
+{
+	int device_minor = MINOR(node->i_rdev) & 0xf;  // Device minor number
+
+	// We can only have one audit device, and it can only be open once
+	if(device_minor)
+		return -ENODEV;
+	
+	down(&audit_lock);
+	
+	if(auditdaemon_task_struct != NULL) {
+		up(&audit_lock);
+		return -EBUSY;
+	}
+
+	// reset the lost packets indicator
+	lost_events=0;
+	total_events=0;
+	
+	// Fetch the task structure of the process that opened the device
+	auditdaemon_task_struct = current;
+
+	up(&audit_lock);
+	
+	printk("Auditing: Process %d has opened the device\n", auditdaemon_task_struct->pid);
+
+	return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// close the device and release resources
+////////////////////////////////////////////////////////////////////////////////
+static int auditproc_close(struct inode* node, struct file*  the_file)
+{
+	int counter;
+	for(counter=1; counter<=MAXAUDIT; counter++) {
+		audit_off(counter);
+	}		
+
+	down(&audit_lock);
+	AUDIT_IS_RUNNING = 0;
+	
+	auditdaemon_task_struct=NULL;
+
+	printk("AUDIT: Audit daemon has closed /proc/audit.\n");
+#if SHOW_EVENT_COUNTER
+	printk("AUDIT: Events lost due low memory this session: %d\n",lost_events);
+	printk("AUDIT: Total Events processed this session: %d\n",total_events);
+#endif
+	lost_events=0;
+	total_events=0;
+
+	up(&audit_lock);
+	
+	return 0;
+}
+
+void audit_on(int auditnumber)
+{
+	down(&audit_lock);
+	set_bit(auditnumber,active_events);
+	up(&audit_lock);
+}
+
+void audit_off(int auditnumber)
+{
+	down(&audit_lock);
+	clear_bit(auditnumber,active_events);
+	up(&audit_lock);
+}
+
+int audit_active(int auditnumber)
+{
+	return(test_bit(auditnumber,active_events));
+}
+
+
+int audit_mknod(const char * file, int mode, dev_t dev)
+{
+	// If noone has requested MKNOD to be active, return quickly.
+	if(!audit_active(AUDIT_mknod)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	io_class * record;
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=(int)mode;
+	record->t_attributes.createmode=(unsigned long)dev;
+
+	record->t_header.event_id = AUDIT_mknod;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+
+	return(1);
+}
+
+int audit_execve(const char * filename, char **argv)
+{
+	ex_class * record;
+	char tempstring[MAX_PATH];
+	unsigned int delimiter_required=0;
+
+	if(!audit_active(AUDIT_execve)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(ex_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(ex_class *)current->audit_record;
+
+	// Filename.
+	if(filename) {
+		strncpy(record->t_path.path,filename,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_execargs.args[0]='\0';
+	while(argv && *argv) {
+		strncpy_from_user(tempstring,*argv,MAX_PATH-1);
+		tempstring[MAX_PATH]='\0';
+
+		// Allow for the delimiter
+		if((strlen(record->t_execargs.args) + strlen(tempstring) +1) < (MAX_PATH-1)) {
+			if(!delimiter_required) {
+				delimiter_required=1;
+			} else {
+				strcat(record->t_execargs.args," ");
+			}
+			strcat(record->t_execargs.args,tempstring);
+		} else {
+			// If the argument size is greater than MAX_PATH, then
+			// ignore this argument, continue on to the next.
+			argv++;
+			continue;
+		}
+		argv++;
+	}
+
+	record->t_header.event_id = AUDIT_execve;
+	record->t_header.event_class=AUDIT_CLASS_EXEC;
+
+	return(1);
+}
+
+int audit_exit()
+{
+	pc_class * record;
+
+	if(!audit_active(AUDIT_exit)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(pc_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(pc_class *)current->audit_record;
+	record->t_header.event_id = AUDIT_exit;
+	record->t_header.event_class=AUDIT_CLASS_PC;
+
+	return(1);
+}
+
+int audit_fork()
+{
+	pc_class * record;
+
+	if(!audit_active(AUDIT_fork)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(pc_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(pc_class *)current->audit_record;
+	record->t_header.event_id = AUDIT_fork;
+	record->t_header.event_class=AUDIT_CLASS_PC;
+
+	return(1);
+}
+
+int audit_open(const char * file, int flags, int mode)
+{
+	io_class * record;
+
+	// If noone has requests MKNOD to be active, return quickly.
+	if(!audit_active(AUDIT_open)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=flags;
+	record->t_attributes.createmode=mode;
+
+	record->t_header.event_id = AUDIT_open;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+	return(1);
+}
+
+int audit_mkdir(const char * file, int mode)
+{
+	io_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_mkdir)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=0;
+	record->t_attributes.createmode=mode;
+
+	record->t_header.event_id = AUDIT_mkdir;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+	return(1);
+}
+
+int audit_unlink(const char * file)
+{
+	io_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_unlink)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=0;
+	record->t_attributes.createmode=0;
+
+	record->t_header.event_id = AUDIT_unlink;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+	return(1);
+}
+
+int audit_rmdir(const char * file)
+{
+	io_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_rmdir)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=0;
+	record->t_attributes.createmode=0;
+
+	record->t_header.event_id = AUDIT_rmdir;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+	return(1);
+}
+
+int audit_chown(const char * file, uid_t user, gid_t group)
+{
+	ch_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_chown)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(ch_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(ch_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_owner.owner=(int)user;
+	record->t_owner.group=(int)group;
+
+	record->t_header.event_id = AUDIT_chown;
+	record->t_header.event_class=AUDIT_CLASS_CH;
+	return(1);
+}
+
+int audit_chmod(const char * file, mode_t mode)
+{
+	io_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_chmod)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+
+	record->t_attributes.mode=0;
+	record->t_attributes.createmode=(unsigned long)mode;
+
+	record->t_header.event_id = AUDIT_chmod;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+	return(1);
+}
+
+// NOTE: This is a little different, since we need to getname/putname
+// Remember to putname on all exit paths.
+int audit_symlink(const char * from, const char * to)
+{
+	cp_class * record;
+	char * kfrom, *kto;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_symlink)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kfrom=getname(from);
+	error = PTR_ERR(kfrom);
+	if(IS_ERR(kfrom))
+		return(0);
+
+	kto=getname(to);
+	error = PTR_ERR(kto);
+	if(IS_ERR(kto)) {
+		putname(kfrom);
+		return(0);
+	}
+
+	if(current->audit_record) {
+		putname(kfrom);
+		putname(kto);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(cp_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kfrom);
+		putname(kto);
+		return(0);
+	}
+
+	record=(cp_class *)current->audit_record;
+
+	// Filename.
+	if(kfrom) {
+		strncpy(record->t_sourcepath.path,kfrom,MAX_PATH);
+	} else {
+		strncpy(record->t_sourcepath.path,"",MAX_PATH);
+	}
+
+	if(kto) {
+		strncpy(record->t_destpath.path,kto,MAX_PATH);
+	} else {
+		strncpy(record->t_destpath.path,"",MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_symlink;
+	record->t_header.event_class=AUDIT_CLASS_CP;
+
+	putname(kfrom);
+	putname(kto);
+	return(1);
+}
+
+// NOTE: This is a little different, since we need to getname/putname
+// - since link doesn't grab BOTH for us.
+// Remember to putname on all exit paths.
+int audit_link(const char * from, const char * to)
+{
+	cp_class * record;
+	char * kfrom, *kto;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_link)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kfrom=getname(from);
+	error = PTR_ERR(kfrom);
+	if(IS_ERR(kfrom))
+		return(0);
+
+	kto=getname(to);
+	error = PTR_ERR(kto);
+	if(IS_ERR(kto)) {
+		putname(kfrom);
+		return(0);
+	}
+
+	if(current->audit_record) {
+		putname(kfrom);
+		putname(kto);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(cp_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kfrom);
+		putname(kto);
+		return(0);
+	}
+
+	record=(cp_class *)current->audit_record;
+
+	// Filename.
+	if(kfrom) {
+		strncpy(record->t_sourcepath.path,kfrom,MAX_PATH);
+	} else {
+		strncpy(record->t_sourcepath.path,"",MAX_PATH);
+	}
+
+	if(kto) {
+		strncpy(record->t_destpath.path,kto,MAX_PATH);
+	} else {
+		strncpy(record->t_destpath.path,"",MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_link;
+	record->t_header.event_class=AUDIT_CLASS_CP;
+
+	putname(kfrom);
+	putname(kto);
+	return(1);
+}
+
+int audit_rename(const char * from, const char * to)
+{
+	cp_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_rename)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(cp_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(cp_class *)current->audit_record;
+
+	// Filename.
+	if(from) {
+		strncpy(record->t_sourcepath.path,from,MAX_PATH);
+	} else {
+		strncpy(record->t_sourcepath.path,"",MAX_PATH);
+	}
+
+	if(to) {
+		strncpy(record->t_destpath.path,to,MAX_PATH);
+	} else {
+		strncpy(record->t_destpath.path,"",MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_rename;
+	record->t_header.event_class=AUDIT_CLASS_CP;
+
+	return(1);
+}
+
+// Truncate - note that we need to grab the data from userspace.
+int audit_truncate(const char * file, loff_t length)
+{
+	io_class * record;
+	char * kfile;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_truncate)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kfile=getname(file);
+	error = PTR_ERR(kfile);
+	if(IS_ERR(kfile))
+		return(0);
+
+	if(current->audit_record) {
+		putname(kfile);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kfile);
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(kfile) {
+		strncpy(record->t_path.path,kfile,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+	record->t_attributes.createmode=(unsigned long)length;
+
+	record->t_header.event_id = AUDIT_truncate;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+
+	return(1);
+}
+
+// Same as truncate, but we don't need to grab the data from userspace
+int audit_ftruncate(const char * file, loff_t length)
+{
+	io_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_truncate)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(file) {
+		strncpy(record->t_path.path,file,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+	record->t_attributes.createmode=(unsigned long)length;
+
+	record->t_header.event_id = AUDIT_truncate;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+
+	return(1);
+}
+
+int audit_chroot(const char * file)
+{
+	io_class * record;
+	char * kfile;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_chroot)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kfile=getname(file);
+	error = PTR_ERR(kfile);
+	if(IS_ERR(kfile))
+		return(0);
+
+	if(current->audit_record) {
+		putname(kfile);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(io_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kfile);
+		return(0);
+	}
+
+	record=(io_class *)current->audit_record;
+
+	// Filename.
+	if(kfile) {
+		strncpy(record->t_path.path,kfile,MAX_PATH);
+	} else {
+		strncpy(record->t_path.path,"",MAX_PATH);
+	}
+	record->t_attributes.createmode=(unsigned long)0;
+
+	record->t_header.event_id = AUDIT_chroot;
+	record->t_header.event_class=AUDIT_CLASS_IO;
+
+	return(1);
+}
+
+int audit_mount(char *dev_name, char *dir_name, char *type, unsigned long flags, void *data)
+{
+	cp_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_mount)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(cp_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(cp_class *)current->audit_record;
+
+	record->t_sourcepath.path[0]='\0';
+	// dev_name and dir_name have been copied from userspace by sys_mount
+	// so just use regular strncpy here, rather than strncpy_from_user.
+	if(dev_name) {
+		strncpy(record->t_sourcepath.path,dev_name,MAX_PATH);
+	}
+	record->t_destpath.path[0]='\0';
+	if(dir_name) {
+		strncpy(record->t_destpath.path,dir_name,MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_mount;
+	record->t_header.event_class=AUDIT_CLASS_CP;
+
+	return(1);
+}
+
+int audit_umount(char * name, int flags)
+{
+	cp_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_umount)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(cp_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(cp_class *)current->audit_record;
+
+	record->t_sourcepath.path[0]='\0';
+	// Name has not yet been grabbed from userspace by sys_umount
+	// Copy it from userspace here.
+	if(name) {
+		strncpy_from_user(record->t_sourcepath.path,name,MAX_PATH);
+	}
+	record->t_destpath.path[0]='\0';
+
+	record->t_header.event_id = AUDIT_umount;
+	record->t_header.event_class=AUDIT_CLASS_CP;
+
+	return(1);
+}
+
+int audit_setuid(uid_t uid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setuid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=uid;
+
+	record->t_header.event_id = AUDIT_setuid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+int audit_setreuid(uid_t ruid, uid_t euid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setreuid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=euid;
+	record->t_target.rid=ruid;
+
+	record->t_header.event_id = AUDIT_setreuid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+int audit_setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setresuid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=euid;
+	record->t_target.rid=ruid;
+	record->t_target.sid=suid;
+
+	record->t_header.event_id = AUDIT_setresuid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+int audit_setregid(gid_t rgid, gid_t egid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setregid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=egid;
+	record->t_target.rid=rgid;
+
+	record->t_header.event_id = AUDIT_setregid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+int audit_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setresgid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=egid;
+	record->t_target.rid=rgid;
+	record->t_target.sid=sgid;
+
+	record->t_header.event_id = AUDIT_setresgid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+int audit_setgid(gid_t gid)
+{
+	su_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_setgid)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(su_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(su_class *)current->audit_record;
+
+	record->t_target.id=gid;
+
+	record->t_header.event_id = AUDIT_setgid;
+	record->t_header.event_class=AUDIT_CLASS_SU;
+
+	return(1);
+}
+
+// Create module
+int audit_create_module(const char * name_user,size_t size)
+{
+	ad_class * record;
+	char * kname_user;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_create_module)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kname_user=getname(name_user);
+	error = PTR_ERR(kname_user);
+	if(IS_ERR(kname_user))
+		return(0);
+
+	if(current->audit_record) {
+		putname(kname_user);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(ad_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kname_user);
+		return(0);
+	}
+
+	record=(ad_class *)current->audit_record;
+
+	// Module name
+	if(kname_user) {
+		strncpy(record->t_name.path,kname_user,MAX_PATH);
+	} else {
+		strncpy(record->t_name.path,"",MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_create_module;
+	record->t_header.event_class=AUDIT_CLASS_AD;
+
+	return(1);
+}
+
+// Delete module
+int audit_delete_module(const char * name_user)
+{
+	ad_class * record;
+	char * kname_user;
+	int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_delete_module)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+
+	kname_user=getname(name_user);
+	error = PTR_ERR(kname_user);
+	if(IS_ERR(kname_user))
+		return(0);
+
+	if(current->audit_record) {
+		putname(kname_user);
+		return(1);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(ad_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		putname(kname_user);
+		return(0);
+	}
+
+	record=(ad_class *)current->audit_record;
+
+	// Module name
+	if(kname_user) {
+		strncpy(record->t_name.path,kname_user,MAX_PATH);
+	} else {
+		strncpy(record->t_name.path,"",MAX_PATH);
+	}
+
+	record->t_header.event_id = AUDIT_delete_module;
+	record->t_header.event_class=AUDIT_CLASS_AD;
+
+	return(1);
+}
+
+int audit_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
+{
+	pc_class * record;
+	// int error;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_reboot)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(1);
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(pc_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(pc_class *)current->audit_record;
+	record->t_header.event_id = AUDIT_reboot;
+	record->t_header.event_class=AUDIT_CLASS_PC;
+
+	return(1);
+}
+
+int audit_connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
+{
+	nt_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_connect)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(0);
+
+	// If this is not an AF_INET, drop it.
+	if(!serv_addr) {
+		return(0);
+	}
+	if(serv_addr->sa_family != AF_INET) {
+		return(0);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(nt_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(nt_class *)current->audit_record;
+	record->t_header.event_id = AUDIT_connect;
+	record->t_header.event_class=AUDIT_CLASS_NET;
+
+        snprintf(record->t_connection.dst_ip,16,"%u.%u.%u.%u",
+			serv_addr->sa_data[2] & 255,
+			serv_addr->sa_data[3] & 255,
+			serv_addr->sa_data[4] & 255,
+			serv_addr->sa_data[5] & 255);
+	strncpy(record->t_connection.src_ip,"127.0.0.1",16);
+
+	struct sockaddr_in *si;
+	si=(struct sockaddr_in *)serv_addr;
+
+	record->t_connection.src_port=0;
+	record->t_connection.dst_port=ntohs(si->sin_port);
+
+	record->t_connection.protocol=0;
+
+	struct socket *sock;
+	int err;
+	if((sock = sockfd_lookup(sockfd,&err))!=NULL) {
+		record->t_connection.src_port=sock->sk->num;
+		record->t_connection.protocol=sock->sk->protocol;
+	}
+
+	return(1);
+}
+
+int audit_accept(int sockfd, struct sockaddr *peer_addr, int *addrlen)
+{
+	nt_class * record;
+
+	// If noone has requested the system call to be active, return quickly.
+	if(!audit_active(AUDIT_accept)) return(0);
+	if(current == auditdaemon_task_struct || !AUDIT_IS_RUNNING) return(0);
+	if(current->audit_record) return(0);
+
+	// If this is not an AF_INET, drop it.
+	if(!peer_addr) {
+		return(0);
+	}
+	if(peer_addr->sa_family != AF_INET) {
+		return(0);
+	}
+
+	// alloc the audit record
+	current->audit_record = kmalloc(sizeof(nt_class),GFP_KERNEL);
+	if(!current->audit_record) {
+		return(0);
+	}
+
+	record=(nt_class *)current->audit_record;
+	record->t_header.event_id = AUDIT_accept;
+	record->t_header.event_class=AUDIT_CLASS_NET;
+
+        snprintf(record->t_connection.src_ip,16,"%u.%u.%u.%u",
+		peer_addr->sa_data[2] & 255,
+		peer_addr->sa_data[3] & 255,
+		peer_addr->sa_data[4] & 255,
+		peer_addr->sa_data[5] & 255);
+	strncpy(record->t_connection.dst_ip,"127.0.0.1",16);
+
+	struct sockaddr_in *si;
+	si=(struct sockaddr_in *)peer_addr;
+
+	record->t_connection.dst_port=0;
+	record->t_connection.src_port=ntohs(si->sin_port);
+
+	record->t_connection.protocol=0;
+
+	struct socket *sock;
+	int err;
+
+	if((sock = sockfd_lookup(sockfd,&err))!=NULL) {
+		record->t_connection.dst_port=ntohs(sock->sk->sport);
+		record->t_connection.protocol=sock->sk->protocol;
+	}
+
+	return(1);
+}
+
+int audit_return(int returncode)
+{
+	int class;
+	static null_class * any_event;
+	AuditNode *	node=(AuditNode *)NULL;
+	static struct timeval time_temp;
+
+	if(!auditdaemon_task_struct) {
+		goto out;
+	}
+
+	if(current == auditdaemon_task_struct) {
+		return(0);
+	}
+
+	if(!current->audit_record) {
+		goto out;
+	}
+
+	any_event = current->audit_record;
+
+	do_gettimeofday(&time_temp);
+
+	class = any_event->t_header.event_class;
+
+	// Fill out as much of the header structure as we can.
+	any_event->t_header.user_id=current->uid;
+	any_event->t_header.group_id=current->gid;
+	any_event->t_header.euser_id=current->euid;
+	any_event->t_header.egroup_id=current->egid;
+	any_event->t_header.time.tv_sec = time_temp.tv_sec;
+	any_event->t_header.time.tv_usec = time_temp.tv_usec;
+	any_event->t_header.returncode=returncode;
+	strncpy(any_event->t_header.processname,current->comm,MAXCOMMAND);
+	any_event->t_header.pid=current->pid;
+	if(current->p_pptr) {
+		any_event->t_header.ppid=current->p_pptr->pid;
+	} else {
+		any_event->t_header.ppid=0;
+	}
+
+	if(class == AUDIT_CLASS_IO) {
+		io_class *record;
+		char tmp[MAX_PATH];
+		record=(io_class *)current->audit_record;
+
+		// Current PWD - IO CLASS, EXEC, CH, CP
+		// NOTE: This will just tell you the file name the user
+		// tried to access. If it's linked to another file, or
+		// from a mountpoint, it will just show you the filename
+		// used in the system call - not the RESOLVED path.
+		strncpy(record->t_pwd.path,d_path(current->fs->pwd,current->fs->pwdmnt,tmp,MAX_PATH),MAX_PATH);
+
+		record->t_header.event_size = sizeof(io_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(io_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(io_class));
+	} else if(class == AUDIT_CLASS_EXEC) {
+		ex_class *record;
+		char tmp[MAX_PATH];
+		record=(ex_class *)current->audit_record;
+
+		// Current PWD - IO CLASS, EXEC, CH, CP
+		strncpy(record->t_pwd.path,d_path(current->fs->pwd,current->fs->pwdmnt,tmp,MAX_PATH),MAX_PATH);
+
+		record->t_header.event_size = sizeof(ex_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(ex_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(ex_class));
+	} else if(class == AUDIT_CLASS_PC) {
+		pc_class *record;
+		record=(pc_class *)current->audit_record;
+
+		// Current PWD - IO CLASS, EXEC, CH, CP
+		record->t_header.event_size = sizeof(pc_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(pc_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(pc_class));
+	} else if(class == AUDIT_CLASS_CH) {
+		ch_class *record;
+		char tmp[MAX_PATH];
+		record=(ch_class *)current->audit_record;
+
+		// Current PWD - IO CLASS, EXEC, CH, CP
+		strncpy(record->t_pwd.path,d_path(current->fs->pwd,current->fs->pwdmnt,tmp,MAX_PATH),MAX_PATH);
+		record->t_header.event_size = sizeof(ch_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(ch_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(ch_class));
+	} else if(class == AUDIT_CLASS_CP) {
+		cp_class *record;
+		char tmp[MAX_PATH];
+		record=(cp_class *)current->audit_record;
+
+		// Current PWD - IO CLASS, EXEC, CH, CP
+		strncpy(record->t_pwd.path,d_path(current->fs->pwd,current->fs->pwdmnt,tmp,MAX_PATH),MAX_PATH);
+		record->t_header.event_size = sizeof(cp_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(cp_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(cp_class));
+	} else if(class == AUDIT_CLASS_SU) {
+		su_class *record;
+		record=(su_class *)current->audit_record;
+
+		record->t_header.event_size = sizeof(su_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(su_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(su_class));
+	} else if(class == AUDIT_CLASS_AD) {
+		ad_class *record;
+		record=(ad_class *)current->audit_record;
+
+		record->t_header.event_size = sizeof(ad_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(ad_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(ad_class));
+	} else if(class == AUDIT_CLASS_NET) {
+		nt_class *record;
+		record=(nt_class *)current->audit_record;
+
+		record->t_header.event_size = sizeof(nt_class) - sizeof(header_token);
+
+		if((node = alloc_event(sizeof(nt_class))) == NULL) {
+			goto out;
+		}
+		// Copy the current audit record into the new Node.
+		// We need to make a copy, since the current process could
+		// dissapear, taking the allocated audit event with it.
+		memcpy(node->location,record,sizeof(nt_class));
+	}
+
+	kfree(current->audit_record);
+	current->audit_record=NULL;
+
+	// Send the audit record out the door.
+	append_event(node);
+	wake_up_interruptible(&proc_audit_queue);
+
+	return(1);
+
+out:
+	if(current->audit_record) {
+		kfree(current->audit_record);
+		current->audit_record=NULL;
+	}
+
+	if(auditdaemon_task_struct) {
+		down(&audit_lock);
+		lost_events++;
+		up(&audit_lock);
+	}
+	return(0);
+}
+
+void append_event(AuditNode *nodepointer)
+{
+	down(&audit_lock);
+
+	if(list_tail != (AuditNode *)NULL) {
+		list_tail->next=nodepointer;
+	}
+
+	list_tail=nodepointer;
+
+	// Is this the first node in our linked list?
+	if(list_head == (AuditNode *) NULL) {
+		list_head=nodepointer;
+	}
+	up(&audit_lock);
+}
+
+AuditNode *alloc_event(int token_size)
+{
+	void *eventpointer;
+	AuditNode * nodepointer;
+
+	eventpointer=kmalloc(token_size,GFP_KERNEL);
+	if(eventpointer == (void *)NULL) {
+		// Not enough RAM available aparently.
+		return(0);
+	}
+
+	nodepointer=(AuditNode *)kmalloc(sizeof(AuditNode),GFP_KERNEL);
+	if(nodepointer == (AuditNode *)NULL) {
+		// Not enough RAM available aparently.
+		// Free the event pointer if we've got this far.
+		kfree(eventpointer);
+		return(0);
+	}
+
+	nodepointer->location=eventpointer;
+	nodepointer->size=token_size;
+	nodepointer->next=(AuditNode *) NULL;	// This is the end.
+
+	return nodepointer;
+}
+#endif
+
diff -N -u -r linux-2.4.22/audit/Makefile snare-kernel/linux-2.4.22-snare/audit/Makefile
--- linux-2.4.22/audit/Makefile	1970-01-01 10:00:00.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/audit/Makefile	2003-09-28 05:45:22.000000000 +1000
@@ -0,0 +1,17 @@
+#
+# Makefile for the linux audit.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := audit.o
+
+export-objs = auditapi.o
+
+obj-$(CONFIG_C2_AUDIT) += auditapi.o
+obj-y += auditapi.o
+
+include $(TOPDIR)/Rules.make
diff -N -u -r linux-2.4.22/Documentation/Configure.help snare-kernel/linux-2.4.22-snare/Documentation/Configure.help
--- linux-2.4.22/Documentation/Configure.help	2003-08-25 21:44:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/Documentation/Configure.help	2003-10-06 14:52:40.000000000 +1000
@@ -4131,6 +4131,15 @@
   up to the user level program to do useful things with this
   information.  This is generally a good idea, so say Y.
 
+C2-Style Auditing
+CONFIG_C2_AUDIT
+  If you say Y here, a user level program (SNARE) will be able to
+  receive system audit events from the kernel. Many government
+  departments, and organisations that have significant security
+  requirements, will want to turn this feature on. Most normal
+  users will not be interested in reviewing audit reports though,
+  and should answer N here.
+
 Sysctl support
 CONFIG_SYSCTL
   The sysctl interface provides a means of dynamically changing
diff -N -u -r linux-2.4.22/fs/exec.c snare-kernel/linux-2.4.22-snare/fs/exec.c
--- linux-2.4.22/fs/exec.c	2003-08-25 21:44:43.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/fs/exec.c	2003-10-06 14:52:54.000000000 +1000
@@ -35,6 +35,7 @@
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/personality.h>
+#include <linux/audit.h>
 #include <linux/swap.h>
 #include <linux/utsname.h>
 #define __NO_VERSION__
@@ -908,11 +909,15 @@
 	int retval;
 	int i;
 
+	audit_execve(filename, argv);
+
 	file = open_exec(filename);
 
 	retval = PTR_ERR(file);
-	if (IS_ERR(file))
+	if (IS_ERR(file)) {
+		audit_return(retval);
 		return retval;
+	}
 
 	bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
 	memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); 
@@ -925,12 +930,14 @@
 	if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) {
 		allow_write_access(file);
 		fput(file);
+		audit_return(bprm.argc);
 		return bprm.argc;
 	}
 
 	if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) {
 		allow_write_access(file);
 		fput(file);
+		audit_return(bprm.envc);
 		return bprm.envc;
 	}
 
@@ -952,9 +959,11 @@
 		goto out; 
 
 	retval = search_binary_handler(&bprm,regs);
-	if (retval >= 0)
+	if (retval >= 0) {
+		audit_return(retval);
 		/* execve success */
 		return retval;
+	}
 
 out:
 	/* Something went wrong, return the inode and free the argument pages*/
@@ -968,6 +977,7 @@
 			__free_page(page);
 	}
 
+	audit_return(retval);
 	return retval;
 }
 
diff -N -u -r linux-2.4.22/fs/namei.c snare-kernel/linux-2.4.22-snare/fs/namei.c
--- linux-2.4.22/fs/namei.c	2003-08-25 21:44:43.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/fs/namei.c	2003-10-07 22:05:09.000000000 +1000
@@ -22,6 +22,7 @@
 #include <linux/dnotify.h>
 #include <linux/smp_lock.h>
 #include <linux/personality.h>
+#include <linux/audit.h>
 
 #include <asm/namei.h>
 #include <asm/uaccess.h>
@@ -1274,6 +1275,8 @@
 	if (IS_ERR(tmp))
 		return PTR_ERR(tmp);
 
+	audit_mknod(tmp,mode,dev);
+
 	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
 	if (error)
 		goto out;
@@ -1302,6 +1305,7 @@
 out:
 	putname(tmp);
 
+	audit_return(error);
 	return error;
 }
 
@@ -1342,6 +1346,8 @@
 		struct dentry *dentry;
 		struct nameidata nd;
 
+		audit_mkdir(pathname,mode & ~current->fs->umask);
+
 		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
@@ -1358,6 +1364,7 @@
 		putname(tmp);
 	}
 
+	audit_return(error);
 	return error;
 }
 
@@ -1438,6 +1445,8 @@
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
+	audit_rmdir(pathname);
+
 	error = path_lookup(name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
@@ -1465,6 +1474,7 @@
 	path_release(&nd);
 exit:
 	putname(name);
+	audit_return(error);
 	return error;
 }
 
@@ -1506,6 +1516,8 @@
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
+	audit_unlink(pathname);
+
 	error = path_lookup(name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
@@ -1528,7 +1540,7 @@
 	path_release(&nd);
 exit:
 	putname(name);
-
+	audit_return(error);
 	return error;
 
 slashes:
@@ -1568,6 +1580,8 @@
 	char * from;
 	char * to;
 
+	audit_symlink(oldname,newname);
+
 	from = getname(oldname);
 	if(IS_ERR(from))
 		return PTR_ERR(from);
@@ -1592,6 +1606,7 @@
 		putname(to);
 	}
 	putname(from);
+	audit_return(error);
 	return error;
 }
 
@@ -1649,6 +1664,8 @@
 	int error;
 	char * to;
 
+	audit_link(oldname,newname);
+
 	to = getname(newname);
 	error = PTR_ERR(to);
 	if (!IS_ERR(to)) {
@@ -1678,6 +1695,7 @@
 exit:
 		putname(to);
 	}
+	audit_return(error);
 	return error;
 }
 
@@ -1928,7 +1946,9 @@
 	to = getname(newname);
 	error = PTR_ERR(to);
 	if (!IS_ERR(to)) {
+		audit_rename(from,to);
 		error = do_rename(from,to);
+		audit_return(error);
 		putname(to);
 	}
 	putname(from);
diff -N -u -r linux-2.4.22/fs/namespace.c snare-kernel/linux-2.4.22-snare/fs/namespace.c
--- linux-2.4.22/fs/namespace.c	2003-06-14 00:51:37.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/fs/namespace.c	2003-10-06 14:53:12.000000000 +1000
@@ -21,6 +21,8 @@
 #include <linux/seq_file.h>
 #include <linux/namespace.h>
 
+#include <linux/audit.h>
+
 struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
 int do_remount_sb(struct super_block *sb, int flags, void * data);
 void kill_super(struct super_block *sb);
@@ -366,6 +368,8 @@
 	struct nameidata nd;
 	int retval;
 
+	audit_umount(name,flags);
+
 	retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd);
 	if (retval)
 		goto out;
@@ -383,6 +387,7 @@
 dput_and_out:
 	path_release(&nd);
 out:
+	audit_return(retval);
 	return retval;
 }
 
@@ -849,10 +854,13 @@
 	if (retval < 0)
 		goto out3;
 
+	audit_mount(dev_name,dir_name,type,flags,data);
+
 	lock_kernel();
 	retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
 			  flags, (void*)data_page);
 	unlock_kernel();
+	audit_return(retval);
 	free_page(data_page);
 
 out3:
diff -N -u -r linux-2.4.22/fs/open.c snare-kernel/linux-2.4.22-snare/fs/open.c
--- linux-2.4.22/fs/open.c	2003-08-25 21:44:43.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/fs/open.c	2003-10-06 14:53:21.000000000 +1000
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/iobuf.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 
@@ -121,6 +122,8 @@
 	struct inode * inode;
 	int error;
 
+	audit_truncate(path,length);
+
 	error = -EINVAL;
 	if (length < 0)	/* sorry, but loff_t says... */
 		goto out;
@@ -172,6 +175,7 @@
 dput_and_out:
 	path_release(&nd);
 out:
+	audit_return(error);
 	return error;
 }
 
@@ -202,6 +206,9 @@
 
 	dentry = file->f_dentry;
 	inode = dentry->d_inode;
+
+	audit_ftruncate(file->f_dentry->d_name.name,length);
+
 	error = -EINVAL;
 	if (!S_ISREG(inode->i_mode) || !(file->f_mode & FMODE_WRITE))
 		goto out_putf;
@@ -221,6 +228,7 @@
 out_putf:
 	fput(file);
 out:
+	audit_return(error);
 	return error;
 }
 
@@ -439,6 +447,8 @@
 	int error;
 	struct nameidata nd;
 
+	audit_chroot(filename);
+
 	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
 	if (error)
@@ -458,6 +468,7 @@
 dput_and_out:
 	path_release(&nd);
 out:
+	audit_return(error);
 	return error;
 }
 
@@ -473,6 +484,8 @@
 	if (!file)
 		goto out;
 
+	audit_chmod(file->f_dentry->d_name.name, mode);
+
 	dentry = file->f_dentry;
 	inode = dentry->d_inode;
 
@@ -490,6 +503,7 @@
 
 out_putf:
 	fput(file);
+	audit_return(err);
 out:
 	return err;
 }
@@ -501,6 +515,8 @@
 	int error;
 	struct iattr newattrs;
 
+	audit_chmod(filename,mode);
+
 	error = user_path_walk(filename, &nd);
 	if (error)
 		goto out;
@@ -523,6 +539,7 @@
 dput_and_out:
 	path_release(&nd);
 out:
+	audit_return(error);
 	return error;
 }
 
@@ -591,11 +608,14 @@
 	struct nameidata nd;
 	int error;
 
+	audit_chown(filename,user,group);
+
 	error = user_path_walk(filename, &nd);
 	if (!error) {
 		error = chown_common(nd.dentry, user, group);
 		path_release(&nd);
 	}
+	audit_return(error);
 	return error;
 }
 
@@ -604,11 +624,14 @@
 	struct nameidata nd;
 	int error;
 
+	audit_chown(filename,user,group);
+
 	error = user_path_walk_link(filename, &nd);
 	if (!error) {
 		error = chown_common(nd.dentry, user, group);
 		path_release(&nd);
 	}
+	audit_return(error);
 	return error;
 }
 
@@ -620,8 +643,10 @@
 
 	file = fget(fd);
 	if (file) {
+		audit_chown(file->f_dentry->d_name.name,user,group);
 		error = chown_common(file->f_dentry, user, group);
 		fput(file);
+		audit_return(error);
 	}
 	return error;
 }
@@ -793,6 +818,7 @@
 	tmp = getname(filename);
 	fd = PTR_ERR(tmp);
 	if (!IS_ERR(tmp)) {
+		audit_open(tmp,flags,mode);
 		fd = get_unused_fd();
 		if (fd >= 0) {
 			struct file *f = filp_open(tmp, flags, mode);
@@ -804,6 +830,7 @@
 out:
 		putname(tmp);
 	}
+	audit_return(fd);
 	return fd;
 
 out_error:
diff -N -u -r linux-2.4.22/include/linux/audit.h snare-kernel/linux-2.4.22-snare/include/linux/audit.h
--- linux-2.4.22/include/linux/audit.h	1970-01-01 10:00:00.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/include/linux/audit.h	2003-10-06 14:53:41.000000000 +1000
@@ -0,0 +1,291 @@
+/*
+ * linux/audit/audit.h
+ * Copyright (C) 1999-2002 InterSect Alliance Pty Ltd 
+ *                         - http://www.intersectalliance.com/
+ */
+
+// If the user has not turned on C2 Auditing, define all 'public' routines out.
+
+#if defined(CONFIG_C2_AUDIT)
+
+// I was going to use __NR_xxx, but we need audit events for events that
+// may NOT be system calls specifically (eg: login, connect/accept)
+#define AUDIT_open		1
+#define AUDIT_mkdir		2
+#define AUDIT_unlink		3
+#define AUDIT_rmdir		4
+#define AUDIT_chown		5
+#define AUDIT_chmod		6
+#define AUDIT_symlink		7
+#define AUDIT_link		8
+#define AUDIT_rename		9
+#define AUDIT_mknod		10
+#define AUDIT_truncate		11
+#define AUDIT_ftruncate		12
+#define AUDIT_chroot		13
+#define AUDIT_execve		14
+#define AUDIT_exit		15
+#define AUDIT_setuid		16
+#define AUDIT_setreuid		17
+#define AUDIT_setresuid		18
+#define AUDIT_setgid		19
+#define AUDIT_setregid		20
+#define AUDIT_setresgid		21
+#define AUDIT_create_module	22
+#define AUDIT_delete_module	23
+#define AUDIT_reboot		24
+#define AUDIT_connect		25
+#define AUDIT_accept		26
+#define AUDIT_mount		27
+#define AUDIT_umount		28
+#define AUDIT_fork		29
+
+// Size of the bitmask array that we need to store the information
+// associated with whether an audit event is currently turned on.
+#define MAXAUDIT			AUDIT_fork
+
+int audit_mknod(const char * file, int mode, dev_t dev);
+int audit_execve(const char * filename, char **argv);
+int audit_exit(void);
+int audit_fork(void);
+int audit_open(const char * file, int flags, int mode);
+int audit_mkdir(const char * file, int mode);
+int audit_unlink(const char * file);
+int audit_rmdir(const char * file);
+int audit_chown(const char * file, uid_t user, gid_t group);
+int audit_chmod(const char * file, mode_t mode);
+int audit_symlink(const char * from, const char * to);
+int audit_link(const char * from, const char * to);
+int audit_rename(const char * from, const char * to);
+int audit_truncate(const char * file, loff_t length);
+int audit_ftruncate(const char * file, loff_t length);
+int audit_chroot(const char * file);
+int audit_setuid(uid_t uid);
+int audit_setreuid(uid_t ruid, uid_t euid);
+int audit_setresuid(uid_t ruid, uid_t euid, uid_t suid);
+int audit_setgid(gid_t gid);
+int audit_setregid(gid_t rgid, gid_t egid);
+int audit_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+int audit_create_module(const char * name_user,size_t size);
+int audit_delete_module(const char * name_user);
+int audit_reboot(int magic1, int magic2, unsigned int cmd, void * arg);
+int audit_connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
+int audit_accept(int sockfd, struct sockaddr *serv_addr, int *addrlen);
+int audit_mount(char *dev_name, char *dir_name, char *type, unsigned long flags, void *data);
+int audit_umount(char *name, int flags);
+int audit_return(int returncode);
+void audit_init(void);
+
+// ioctl modes - note that '1' doesnt seem to work. Added 10.
+#define AUDIT_STOP			10  // stop auditing
+#define AUDIT_START			11  // start auditing
+#define AUDIT_INFO			12  // Give me a list of events
+					    // currently active, and other
+					    // info such as the process ID
+#define AUDIT_LOSTEVENTS		13
+#define AUDIT_FLUSH			14  // Stop all events.
+#define AUDIT_EVENT_ON			15  // Turn on a selected event
+#define AUDIT_EVENT_OFF			16  // Turn off a selected event
+#define AUDIT_DELIVERY 			17  // Do we want to guarantee audit event delivery
+#define AUDIT_TOTALEVENTS		18  // How many events have been received this session?
+
+
+#define AUDIT_CLASS_NONE	0
+#define AUDIT_CLASS_IO		1	// Input/output (file opens)
+#define AUDIT_CLASS_PC		2	// Process Control
+#define AUDIT_CLASS_EXEC	3	// Execution
+#define AUDIT_CLASS_NET		4	// Network related
+#define AUDIT_CLASS_ADMIN	5	// Administrative events
+#define AUDIT_CLASS_CH		6	// CHMOD event. Might not use this for anything else.
+#define AUDIT_CLASS_CP		7	// Where more than one pathname is required
+#define AUDIT_CLASS_SU		8	// SetUID
+#define AUDIT_CLASS_AD		9	// Admin such as create/delete module
+
+#define SNAREAUDIT_MAJOR_VERSION 0
+#define SNAREAUDIT_MINOR_VERSION 9
+#define SNAREAUDIT_PATCH_VERSION 3
+
+
+// /proc entry
+#define AUDITDEV_NAME  "audit"			// device name in /dev and /proc/devices
+#define AUDITINFO_NAME	"auditinfo"		// Information about the process
+#define AUDITDEV_FILE  "/proc/audit"		// full file name
+#define AUDITINFO_FILE "/proc/auditinfo"	// Information about the process.
+#define MAX_PATH   512				// NOTE: will migrgate this to PATH_MAX eventually
+#define MAXCOMMAND 16
+
+// This contains the details that are common to ALL audit events.
+typedef struct
+{
+	unsigned short event_class;		// event class. Each class has a predictable format for tokens.
+	unsigned short event_id;		// number of the event
+	unsigned short event_size;		// size of the event struct - don't include header
+						// since it's always the same
+	struct timeval time;			// time
+
+	int user_id;				// User ID
+	int euser_id;				// Effective User ID
+	int group_id;				// Group ID
+	int egroup_id;				// Effective Group ID
+
+	int returncode;				// Make sure that this is big enough to contain the largest returncode.
+
+	pid_t pid;				// process ID.
+	pid_t ppid;				// Parent process ID.
+	char processname[MAXCOMMAND];	// Same as in /usr/include/linux/sched.h for current->comm
+} header_token;
+
+typedef struct
+{
+	char path[MAX_PATH];
+} path_token;
+
+typedef struct
+{
+	int mode;			// How the file was attempted to be opened or created
+	unsigned long	createmode;	// Flags associated with the file creation. Ulong for mknod.
+} attributes_token;
+
+typedef struct
+{
+	int owner;			// new owner of a file - was uid_t, but these are different between kernel and user.
+	int group;			// new group of a file
+} owner_token;
+
+typedef struct
+{
+	char args[MAX_PATH];		// Should really allocate more here. Whats is the max command line size?
+} execargs_token;
+
+// System calls like setuid
+typedef struct
+{
+	int id;		// uid/gid/euid depending on the call
+	int rid;	// ruid/rgid
+	int sid;	// suid/sgid
+} target_token;
+
+// Network connections
+typedef struct
+{
+	char src_ip[40];	// String containing source dotted ip address - 40 bytes, for IPv6
+	int src_port;		// Source port
+	char dst_ip[40];	// String containing destination dotted ip address - 40 bytes, for IPv6
+	int dst_port;		// Destination port
+	int protocol;		// Protocol type - IPPROTO_UDP or IPPROTO_TCP
+} connection_token;
+
+
+
+// Now for the audit event classes
+
+// Just a bare class with the minimal data
+// note that this will mean that EVERY class must start with header_token
+typedef struct
+{
+	header_token	t_header;
+} null_class;
+	
+
+// NOTE: ANY CLASS STRUCTURE SHOULD HAVE THE RETURN TOKEN AS THE SECOND ELEMENT.
+// SEE AUDITD FOR MORE INFO.
+// io - reads/writes
+typedef struct
+{
+	header_token		t_header;
+	path_token		t_path;
+	path_token		t_pwd;	// Working directory
+	attributes_token	t_attributes;
+} io_class;
+
+typedef struct
+{
+	header_token		t_header;
+	path_token		t_path;
+	path_token		t_pwd;	// Working directory
+	owner_token		t_owner;
+} ch_class;
+
+typedef struct
+{
+	header_token		t_header;
+	path_token		t_path;
+	path_token		t_pwd;	// Working directory
+	execargs_token		t_execargs;
+	// environment variables too?
+} ex_class;
+
+typedef struct
+{
+	header_token		t_header;
+} pc_class;
+
+// copy one file to another (amongst others - eg: symlink)
+typedef struct
+{
+	header_token		t_header;
+	path_token		t_sourcepath;
+	path_token		t_pwd;	// Working directory
+	path_token		t_destpath;
+} cp_class;
+
+typedef struct
+{
+	header_token		t_header;
+	target_token		t_target;	// target UID or GID.. I really only need a single value here.
+} su_class;
+
+typedef struct
+{
+	header_token		t_header;
+	connection_token	t_connection;	
+} nt_class;	// Network
+
+typedef struct
+{
+	header_token		t_header;
+	path_token		t_name;		// Name of the module loaded / removed
+} ad_class;	// General Administrative
+
+struct _auditnode
+{
+	void * location;	// Location in RAM of the allocated chunk
+	int size;		// Size of the chunk
+	struct _auditnode *next;	// Next node in the series.
+};
+
+typedef struct _auditnode AuditNode;
+
+#else	// CONFIG_C2_AUDIT
+
+#define audit_mknod(file,mode,dev)		do { } while(0)
+#define audit_execve(filename,argv)		do { } while(0)
+#define audit_exit()				do { } while(0)
+#define audit_fork()				do { } while(0)
+#define audit_open(file,flags,mode)		do { } while(0)
+#define audit_mkdir(file,mode)			do { } while(0)
+#define audit_unlink(file)			do { } while(0)
+#define audit_rmdir(file)			do { } while(0)
+#define audit_chown(file,user,group)		do { } while(0)
+#define audit_chmod(file,mode)			do { } while(0)
+#define audit_symlink(from,to)			do { } while(0)
+#define audit_link(from,to)			do { } while(0)
+#define audit_rename(from,to)			do { } while(0)
+#define audit_truncate(file,length)		do { } while(0)
+#define audit_ftruncate(file,length)		do { } while(0)
+#define audit_chroot(file)			do { } while(0)
+#define audit_setuid(uid)			do { } while(0)
+#define audit_setreuid(ruid,euid)		do { } while(0)
+#define audit_setresuid(ruid,euid,suid)		do { } while(0)
+#define audit_setgid(gid)			do { } while(0)
+#define audit_setregid(rgid,egid)		do { } while(0)
+#define audit_setresgid(rgid,egid,sgid)		do { } while(0)
+#define audit_create_module(name_user,size)	do { } while(0)
+#define audit_delete_module(name_user)		do { } while(0)
+#define audit_reboot(magic,magic2,flag,arg)	do { } while(0)
+#define audit_connect(sockfd,serv_addr,addrlen)	do { } while(0)
+#define audit_accept(sockfd,serv_addr,addrlen)	do { } while(0)
+#define audit_mount(dev_name,dir_name,type,flags,data)	do { } while(0)
+#define audit_umount(name,flags)		do { } while(0)
+#define audit_return(x)				x
+#endif
diff -N -u -r linux-2.4.22/include/linux/sched.h snare-kernel/linux-2.4.22-snare/include/linux/sched.h
--- linux-2.4.22/include/linux/sched.h	2003-06-14 00:51:39.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/include/linux/sched.h	2003-10-06 14:53:48.000000000 +1000
@@ -415,6 +415,11 @@
 
 /* journalling filesystem info */
 	void *journal_info;
+
+#ifdef CONFIG_C2_AUDIT
+/* Audit record pointer */
+       void *audit_record;
+#endif
 };
 
 /*
diff -N -u -r linux-2.4.22/init/main.c snare-kernel/linux-2.4.22-snare/init/main.c
--- linux-2.4.22/init/main.c	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/init/main.c	2003-10-06 14:54:01.000000000 +1000
@@ -27,6 +27,7 @@
 #include <linux/iobuf.h>
 #include <linux/bootmem.h>
 #include <linux/tty.h>
+#include <linux/audit.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -427,6 +428,9 @@
 #if defined(CONFIG_SYSVIPC)
 	ipc_init();
 #endif
+#if defined(CONFIG_C2_AUDIT)
+	audit_init();
+#endif
 	check_bugs();
 	printk("POSIX conformance testing by UNIFIX\n");
 
diff -N -u -r linux-2.4.22/kernel/exit.c snare-kernel/linux-2.4.22-snare/kernel/exit.c
--- linux-2.4.22/kernel/exit.c	2002-11-29 10:53:15.000000000 +1100
+++ snare-kernel/linux-2.4.22-snare/kernel/exit.c	2003-10-06 14:54:12.000000000 +1000
@@ -13,6 +13,7 @@
 #include <linux/personality.h>
 #include <linux/tty.h>
 #include <linux/namespace.h>
+#include <linux/audit.h>
 #ifdef CONFIG_BSD_PROCESS_ACCT
 #include <linux/acct.h>
 #endif
@@ -486,6 +487,8 @@
 
 asmlinkage long sys_exit(int error_code)
 {
+	audit_exit();
+	audit_return(error_code);
 	do_exit((error_code&0xff)<<8);
 }
 
diff -N -u -r linux-2.4.22/kernel/fork.c snare-kernel/linux-2.4.22-snare/kernel/fork.c
--- linux-2.4.22/kernel/fork.c	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/kernel/fork.c	2003-10-06 14:54:20.000000000 +1000
@@ -22,6 +22,7 @@
 #include <linux/namespace.h>
 #include <linux/personality.h>
 #include <linux/compiler.h>
+#include <linux/audit.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -635,15 +636,18 @@
 int do_fork(unsigned long clone_flags, unsigned long stack_start,
 	    struct pt_regs *regs, unsigned long stack_size)
 {
-	int retval;
+	int retval,auditretval;
 	struct task_struct *p;
 	struct completion vfork;
 
-	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
+	audit_fork();
+	auditretval = -1;
+	
+	if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) {
+		audit_return(-1);
 		return -EINVAL;
-
+	}
 	retval = -EPERM;
-
 	/* 
 	 * CLONE_PID is only allowed for the initial SMP swapper
 	 * calls
@@ -655,10 +659,13 @@
 
 	retval = -ENOMEM;
 	p = alloc_task_struct();
-	if (!p)
+	if (!p) 
 		goto fork_out;
 
 	*p = *current;
+#ifdef CONFIG_C2_AUDIT
+       p->audit_record = NULL;
+#endif
 
 	retval = -EAGAIN;
 	/*
@@ -813,8 +820,13 @@
 	++total_forks;
 	if (clone_flags & CLONE_VFORK)
 		wait_for_completion(&vfork);
+	auditretval = 0;
 
 fork_out:
+	if (auditretval == -1)
+		audit_return(-1);
+	else
+		audit_return(p->pid);
 	return retval;
 
 bad_fork_cleanup_namespace:
@@ -836,6 +848,7 @@
 	free_uid(p->user);
 bad_fork_free:
 	free_task_struct(p);
+	auditretval = -1;
 	goto fork_out;
 }
 
diff -N -u -r linux-2.4.22/kernel/module.c snare-kernel/linux-2.4.22-snare/kernel/module.c
--- linux-2.4.22/kernel/module.c	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/kernel/module.c	2003-10-06 14:54:32.000000000 +1000
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/seq_file.h>
+#include <linux/audit.h>
 
 /*
  * Originally by Anonymous (as far as I know...)
@@ -296,8 +297,13 @@
 	struct module *mod;
 	unsigned long flags;
 
-	if (!capable(CAP_SYS_MODULE))
+	audit_create_module(name_user,size);
+
+	if (!capable(CAP_SYS_MODULE)) {
+		audit_return(-EPERM);
 		return -EPERM;
+	}
+
 	lock_kernel();
 	if ((namelen = get_mod_name(name_user, &name)) < 0) {
 		error = namelen;
@@ -335,6 +341,7 @@
 	put_mod_name(name);
 err0:
 	unlock_kernel();
+	audit_return(error);
 	return error;
 }
 
@@ -612,8 +619,12 @@
 	long error;
 	int something_changed;
 
-	if (!capable(CAP_SYS_MODULE))
+	audit_delete_module(name_user);
+
+	if (!capable(CAP_SYS_MODULE)) {
+		audit_return(-EPERM);
 		return -EPERM;
+	}
 
 	lock_kernel();
 	if (name_user) {
@@ -678,6 +689,7 @@
 	error = 0;
 out:
 	unlock_kernel();
+	audit_return(error);
 	return error;
 }
 
diff -N -u -r linux-2.4.22/kernel/sys.c snare-kernel/linux-2.4.22-snare/kernel/sys.c
--- linux-2.4.22/kernel/sys.c	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/kernel/sys.c	2003-10-06 14:54:37.000000000 +1000
@@ -14,6 +14,7 @@
 #include <linux/prctl.h>
 #include <linux/init.h>
 #include <linux/highuid.h>
+#include <linux/audit.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -291,15 +292,25 @@
 	char buffer[256];
 
 	/* We only trust the superuser with rebooting the system. */
-	if (!capable(CAP_SYS_BOOT))
+	if (!capable(CAP_SYS_BOOT)) {
+		audit_reboot(magic1,magic2,cmd,arg);
+		audit_return(-EPERM);
 		return -EPERM;
+	}
 
 	/* For safety, we require "magic" arguments. */
 	if (magic1 != LINUX_REBOOT_MAGIC1 ||
 	    (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
-			magic2 != LINUX_REBOOT_MAGIC2B))
+			magic2 != LINUX_REBOOT_MAGIC2B)) {
+		audit_reboot(magic1,magic2,cmd,arg);
+		audit_return(-EINVAL);
 		return -EINVAL;
+	}
 
+	// Try and audit before we go down.
+	audit_reboot(magic1,magic2,cmd,arg);
+	audit_return(0);
+	
 	lock_kernel();
 	switch (cmd) {
 	case LINUX_REBOOT_CMD_RESTART:
@@ -399,13 +410,17 @@
 	int new_rgid = old_rgid;
 	int new_egid = old_egid;
 
+	audit_setregid(rgid,egid);
+	
 	if (rgid != (gid_t) -1) {
 		if ((old_rgid == rgid) ||
 		    (current->egid==rgid) ||
 		    capable(CAP_SETGID))
 			new_rgid = rgid;
-		else
+		else {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 	}
 	if (egid != (gid_t) -1) {
 		if ((old_rgid == egid) ||
@@ -414,6 +429,7 @@
 		    capable(CAP_SETGID))
 			new_egid = egid;
 		else {
+			audit_return(-EPERM);
 			return -EPERM;
 		}
 	}
@@ -428,6 +444,8 @@
 	current->fsgid = new_egid;
 	current->egid = new_egid;
 	current->gid = new_rgid;
+
+	audit_return(0);
 	return 0;
 }
 
@@ -439,9 +457,11 @@
 asmlinkage long sys_setgid(gid_t gid)
 {
 	int old_egid = current->egid;
-
+	
+	audit_setgid(gid);
 	if (capable(CAP_SETGID))
 	{
+		audit_return(0);
 		if(old_egid != gid)
 		{
 			current->mm->dumpable=0;
@@ -451,6 +471,7 @@
 	}
 	else if ((gid == current->gid) || (gid == current->sgid))
 	{
+		audit_return(0);
 		if(old_egid != gid)
 		{
 			current->mm->dumpable=0;
@@ -459,7 +480,10 @@
 		current->egid = current->fsgid = gid;
 	}
 	else
+	{
+		audit_return(-EPERM);
 		return -EPERM;
+	}
 	return 0;
 }
   
@@ -555,6 +579,9 @@
 {
 	int old_ruid, old_euid, old_suid, new_ruid, new_euid;
 
+
+	audit_setreuid(ruid,euid);
+	
 	new_ruid = old_ruid = current->uid;
 	new_euid = old_euid = current->euid;
 	old_suid = current->suid;
@@ -563,8 +590,10 @@
 		new_ruid = ruid;
 		if ((old_ruid != ruid) &&
 		    (current->euid != ruid) &&
-		    !capable(CAP_SETUID))
+		    !capable(CAP_SETUID)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 	}
 
 	if (euid != (uid_t) -1) {
@@ -572,12 +601,18 @@
 		if ((old_ruid != euid) &&
 		    (current->euid != euid) &&
 		    (current->suid != euid) &&
-		    !capable(CAP_SETUID))
+		    !capable(CAP_SETUID)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 	}
 
-	if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
+	if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0) {
+		audit_return(-EAGAIN);
 		return -EAGAIN;
+	}
+
+	audit_return(0);	// Before current->*id is changed
 
 	if (new_euid != old_euid)
 	{
@@ -615,17 +650,25 @@
 	int old_euid = current->euid;
 	int old_ruid, old_suid, new_ruid, new_suid;
 
+	audit_setuid(uid);
+	
 	old_ruid = new_ruid = current->uid;
 	old_suid = current->suid;
 	new_suid = old_suid;
 	
 	if (capable(CAP_SETUID)) {
-		if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
+		if (uid != old_ruid && set_user(uid, old_euid != uid) < 0) {
+			audit_return(-EAGAIN);
 			return -EAGAIN;
+		}
 		new_suid = uid;
-	} else if ((uid != current->uid) && (uid != new_suid))
+	} else if ((uid != current->uid) && (uid != new_suid)) {
+		audit_return(-EPERM);
 		return -EPERM;
-
+	}
+	
+	audit_return(0);        // Before current->*id is changed
+	
 	if (old_euid != uid)
 	{
 		current->mm->dumpable = 0;
@@ -652,21 +695,34 @@
 	int old_euid = current->euid;
 	int old_suid = current->suid;
 
+	audit_setresuid(ruid,euid,suid);
+
 	if (!capable(CAP_SETUID)) {
 		if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
-		    (ruid != current->euid) && (ruid != current->suid))
+		    (ruid != current->euid) && (ruid != current->suid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 		if ((euid != (uid_t) -1) && (euid != current->uid) &&
-		    (euid != current->euid) && (euid != current->suid))
+		    (euid != current->euid) && (euid != current->suid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 		if ((suid != (uid_t) -1) && (suid != current->uid) &&
-		    (suid != current->euid) && (suid != current->suid))
+		    (suid != current->euid) && (suid != current->suid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 	}
 	if (ruid != (uid_t) -1) {
-		if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
+		if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0) {
+			audit_return(-EAGAIN);
 			return -EAGAIN;
+		}
 	}
+	
+	audit_return(0);        // Before current->uids change
+
 	if (euid != (uid_t) -1) {
 		if (euid != current->euid)
 		{
@@ -702,17 +758,27 @@
  */
 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
 {
+	audit_setresgid(rgid,egid,sgid);
 	if (!capable(CAP_SETGID)) {
 		if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
-		    (rgid != current->egid) && (rgid != current->sgid))
+		    (rgid != current->egid) && (rgid != current->sgid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 		if ((egid != (gid_t) -1) && (egid != current->gid) &&
-		    (egid != current->egid) && (egid != current->sgid))
+		    (egid != current->egid) && (egid != current->sgid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 		if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
-		    (sgid != current->egid) && (sgid != current->sgid))
+		    (sgid != current->egid) && (sgid != current->sgid)) {
+			audit_return(-EPERM);
 			return -EPERM;
+		}
 	}
+	
+	audit_return(0);        // Before our current process UIDs change
+	
 	if (egid != (gid_t) -1) {
 		if (egid != current->egid)
 		{
diff -N -u -r linux-2.4.22/Makefile snare-kernel/linux-2.4.22-snare/Makefile
--- linux-2.4.22/Makefile	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/Makefile	2003-10-06 14:54:44.000000000 +1000
@@ -128,7 +128,8 @@
 NETWORKS	=net/network.o
 
 LIBS		=$(TOPDIR)/lib/lib.a
-SUBDIRS		=kernel drivers mm fs net ipc lib crypto
+AUDIT		=audit/audit.o
+SUBDIRS		=kernel drivers mm fs net ipc lib crypto audit
 
 DRIVERS-n :=
 DRIVERS-y :=
@@ -270,7 +271,7 @@
 
 export	CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
 
-export	NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
+export	NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS AUDIT
 
 .S.s:
 	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
@@ -289,6 +290,7 @@
 		$(CORE_FILES) \
 		$(DRIVERS) \
 		$(NETWORKS) \
+		$(AUDIT) \
 		$(LIBS) \
 		--end-group \
 		-o vmlinux
diff -N -u -r linux-2.4.22/net/socket.c snare-kernel/linux-2.4.22-snare/net/socket.c
--- linux-2.4.22/net/socket.c	2003-08-25 21:44:44.000000000 +1000
+++ snare-kernel/linux-2.4.22-snare/net/socket.c	2003-10-06 14:54:53.000000000 +1000
@@ -44,6 +44,7 @@
  *		Tigran Aivazian	:	sys_send(args) calls sys_sendto(args, NULL, 0)
  *		Tigran Aivazian	:	Made listen(2) backlog sanity checks 
  *					protocol-independent
+ *              Leigh Purdie    :       Socketcall auditing.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -74,6 +75,8 @@
 #include <linux/cache.h>
 #include <linux/module.h>
 #include <linux/highmem.h>
+#include <linux/audit.h>
+
 
 #if defined(CONFIG_KMOD) && defined(CONFIG_NET)
 #include <linux/kmod.h>
@@ -1559,12 +1562,16 @@
 			break;
 		case SYS_CONNECT:
 			err = sys_connect(a0, (struct sockaddr *)a1, a[2]);
+			if(audit_connect(a0, (struct sockaddr *)a1, a[2]))
+				audit_return(err);
 			break;
 		case SYS_LISTEN:
 			err = sys_listen(a0,a1);
 			break;
 		case SYS_ACCEPT:
 			err = sys_accept(a0,(struct sockaddr *)a1, (int *)a[2]);
+			if(audit_accept(a0, (struct sockaddr *)a1, (int *)a[2]))
+				audit_return(err);
 			break;
 		case SYS_GETSOCKNAME:
 			err = sys_getsockname(a0,(struct sockaddr *)a1, (int *)a[2]);
