changeset 4307:ce0bb7cc2e46

6528002 enable kernel auditing for PF_POLICY
author pwernau
date Thu, 24 May 2007 09:24:16 -0700
parents 8c27001b19c8
children 854a761722c7
files usr/src/cmd/bsmrecord/audit_record_attr.txt usr/src/lib/libbsm/audit_event.txt usr/src/uts/common/c2/audit.c usr/src/uts/common/c2/audit.h usr/src/uts/common/c2/audit_kevents.h usr/src/uts/common/c2/audit_start.c usr/src/uts/common/inet/ip/spdsock.c usr/src/uts/intel/ia32/ml/modstubs.s usr/src/uts/sparc/ml/modstubs.s
diffstat 9 files changed, 415 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/bsmrecord/audit_record_attr.txt	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/cmd/bsmrecord/audit_record_attr.txt	Thu May 24 09:24:16 2007 -0700
@@ -1956,6 +1956,66 @@
 label=AUE_XSTAT
   skip=Not Used.  xstat() generates AUE_STAT.
 
+label=AUE_PF_POLICY_ADDRULE
+  title=Add IPsec policy rule
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
+label=AUE_PF_POLICY_DELRULE
+  title=Delete IPsec policy rule
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
+label=AUE_PF_POLICY_CLONE
+  title=Clone IPsec policy
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
+label=AUE_PF_POLICY_FLIP
+  title=Flip IPsec policy
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
+label=AUE_PF_POLICY_FLUSH
+  title=Flip IPsec policy rules
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
+label=AUE_PF_POLICY_ALGS
+  title=Update IPsec algorithms
+  see=
+  syscall=none
+  format=arg1:arg2:[zone]3:[text]4
+  comment=Operation applied to active policy (1 is active, 0 is inactive):
+  comment=Operation applied to global policy (1 is global, 0 is tunnel):
+  comment=affected zone:
+  comment=Name of target tunnel
+
 label=AUE_allocate_fail
   program=/usr/sbin/allocate
   title=allocate: allocate-device failure
--- a/usr/src/lib/libbsm/audit_event.txt	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/lib/libbsm/audit_event.txt	Thu May 24 09:24:16 2007 -0700
@@ -338,6 +338,12 @@
 292:AUE_CRYPTOADM:kernel cryptographic framework:as
 293:AUE_CONFIGSSL:configure kernel SSL:as
 294:AUE_BRANDSYS:brandsys(2):ot
+295:AUE_PF_POLICY_ADDRULE:Add IPsec policy rule:as
+296:AUE_PF_POLICY_DELRULE:Delete IPsec policy rule:as
+297:AUE_PF_POLICY_CLONE:Clone IPsec policy:as
+298:AUE_PF_POLICY_FLIP:Flip IPsec policy:as
+299:AUE_PF_POLICY_FLUSH:Flush IPsec policy rules:as
+300:AUE_PF_POLICY_ALGS:Update IPsec algorithms:as
 #
 # user level audit events
 #	2048 -  6143	Reserved
--- a/usr/src/uts/common/c2/audit.c	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/common/c2/audit.c	Thu May 24 09:24:16 2007 -0700
@@ -62,7 +62,9 @@
 #include <sys/disp.h>		/* for servicing_interrupt() */
 #include <sys/devpolicy.h>
 #include <sys/crypto/ioctladmin.h>
+#include <sys/cred_impl.h>
 #include <inet/kssl/kssl.h>
+#include <net/pfpolicy.h>
 
 static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
 
@@ -863,7 +865,7 @@
 	kctx = GET_KCTX_PZ;
 
 	/* kludge for error 0, should use `code==CLD_DUMPED' instead */
-	if (flag = audit_success(kctx, tad, 0)) {
+	if (flag = audit_success(kctx, tad, 0, NULL)) {
 		cred_t *cr = CRED();
 		const auditinfo_addr_t *ainfo = crgetauinfo(cr);
 
@@ -1252,7 +1254,7 @@
 		return;
 
 	/* do preselection on success/failure */
-	if (flag = audit_success(kctx, tad, 0)) {
+	if (flag = audit_success(kctx, tad, 0, NULL)) {
 		/* add a process token */
 
 		cred_t *cr = CRED();
@@ -2078,7 +2080,7 @@
 
 	tad->tad_event = AUE_CRYPTOADM;
 
-	if (audit_success(kctx, tad, error) != AU_OK)
+	if (audit_success(kctx, tad, error, NULL) != AU_OK)
 		return;
 
 	/* Add subject information */
@@ -2223,7 +2225,7 @@
 
 	tad->tad_event = AUE_CONFIGKSSL;
 
-	if (audit_success(kctx, tad, error) != AU_OK)
+	if (audit_success(kctx, tad, error, NULL) != AU_OK)
 		return;
 
 	/* Add subject information */
@@ -2273,6 +2275,144 @@
 }
 
 /*
+ * Audit the kernel PF_POLICY administration commands.  Record command,
+ * zone, policy type (global or tunnel, active or inactive)
+ */
+/*
+ * ROUTINE:	AUDIT_PF_POLICY
+ * PURPOSE:	Records arguments to administrative ioctls on PF_POLICY socket
+ * CALLBY:	SPD_ADDRULE, SPD_DELETERULE, SPD_FLUSH, SPD_UPDATEALGS,
+ *		SPD_CLONE, SPD_FLIP
+ * NOTE:
+ * TODO:
+ * QUESTION:
+ */
+
+void
+audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun,
+    boolean_t active, int error, pid_t pid)
+{
+	const auditinfo_addr_t	*ainfo;
+	t_audit_data_t		*tad;
+	token_t			*ad = NULL;
+	au_kcontext_t		*kctx = GET_KCTX_PZ;
+	char			buf[80];
+	int			flag;
+
+	tad = U2A(u);
+	if (tad == NULL)
+		return;
+
+	ainfo = crgetauinfo((cred != NULL) ? cred : CRED());
+	if (ainfo == NULL)
+		return;
+
+	/*
+	 * Initialize some variables since these are only set
+	 * with system calls.
+	 */
+
+	switch (cmd) {
+	case SPD_ADDRULE: {
+		tad->tad_event = AUE_PF_POLICY_ADDRULE;
+		break;
+	}
+
+	case SPD_DELETERULE: {
+		tad->tad_event = AUE_PF_POLICY_DELRULE;
+		break;
+	}
+
+	case SPD_FLUSH: {
+		tad->tad_event = AUE_PF_POLICY_FLUSH;
+		break;
+	}
+
+	case SPD_UPDATEALGS: {
+		tad->tad_event = AUE_PF_POLICY_ALGS;
+		break;
+	}
+
+	case SPD_CLONE: {
+		tad->tad_event = AUE_PF_POLICY_CLONE;
+		break;
+	}
+
+	case SPD_FLIP: {
+		tad->tad_event = AUE_PF_POLICY_FLIP;
+		break;
+	}
+
+	default:
+		tad->tad_event = AUE_NULL;
+	}
+
+	tad->tad_evmod = 0;
+
+	if (flag = audit_success(kctx, tad, error, cred)) {
+		zone_t *nszone;
+
+		/*
+		 * For now, just audit that an event happened,
+		 * along with the error code.
+		 */
+		au_write((caddr_t *)&ad,
+		    au_to_arg32(1, "Policy Active?", (uint32_t)active));
+		au_write((caddr_t *)&ad,
+		    au_to_arg32(2, "Policy Global?", (uint32_t)(tun == NULL)));
+
+		/* Supplemental data */
+
+		/*
+		 * Generate this zone token if the target zone differs
+		 * from the administrative zone.  If netstacks are expanded
+		 * to something other than a 1-1 relationship with zones,
+		 * the auditing framework should create a new token type
+		 * and audit it as a netstack instead.
+		 * Turn on general zone auditing to get the administrative zone.
+		 */
+
+		nszone = zone_find_by_id(netstackid_to_zoneid(
+		    ns->netstack_stackid));
+		if (strncmp(cred->cr_zone->zone_name, nszone->zone_name,
+		    ZONENAME_MAX) != 0) {
+			token_t *ztoken;
+
+			ztoken = au_to_zonename(0, nszone);
+			au_write((caddr_t *)&ad, ztoken);
+		}
+
+		if (tun != NULL) {
+			/* write tunnel name - tun is bounded */
+			(void) snprintf(buf, sizeof (buf), "tunnel_name:%s",
+			    tun);
+			au_write((caddr_t *)&ad, au_to_text(buf));
+		}
+
+		/* Add subject information */
+		AUDIT_SETSUBJ_GENERIC((caddr_t *)&ad,
+		    ((cred != NULL) ? cred : CRED()), ainfo, kctx, pid);
+
+		/* add a return token */
+		add_return_token((caddr_t *)&ad, 0, error, 0);
+
+		AS_INC(as_generated, 1, kctx);
+		AS_INC(as_kernel, 1, kctx);
+
+	}
+	au_close(kctx, (caddr_t *)&ad, flag, tad->tad_event, 0);
+
+	/*
+	 * clear the ctrl flag so that we don't have spurious collection of
+	 * audit information.
+	 */
+	tad->tad_scid  = 0;
+	tad->tad_event = 0;
+	tad->tad_evmod = 0;
+	tad->tad_ctrl  = 0;
+}
+
+/*
  * ROUTINE:	AUDIT_SEC_ATTRIBUTES
  * PURPOSE:	Add security attributes
  * CALLBY:	AUDIT_ATTRIBUTES
--- a/usr/src/uts/common/c2/audit.h	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/common/c2/audit.h	Thu May 24 09:24:16 2007 -0700
@@ -486,6 +486,7 @@
 #include <netinet/in.h>
 #include <c2/audit_door_infc.h>
 #include <sys/crypto/ioctladmin.h>
+#include <sys/netstack.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -564,7 +565,7 @@
 typedef struct au_kcontext au_kcontext_t;
 #endif
 
-int	audit_success(au_kcontext_t *, struct t_audit_data *, int);
+int	audit_success(au_kcontext_t *, struct t_audit_data *, int, cred_t *);
 int	auditme(au_kcontext_t *, struct t_audit_data *, au_state_t);
 void	audit_fixpath(struct audit_path *, int);
 void	audit_ipc(int, int, void *);
@@ -579,6 +580,8 @@
 void	audit_devpolicy(int, const struct devplcysys *);
 void	audit_update_context(proc_t *, cred_t *);
 void	audit_kssl(int, void *, int);
+void	audit_pf_policy(int, cred_t *, netstack_t *, char *, boolean_t, int,
+    pid_t);
 void	audit_sec_attributes(caddr_t *, struct vnode *);
 
 #endif
--- a/usr/src/uts/common/c2/audit_kevents.h	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/common/c2/audit_kevents.h	Thu May 24 09:24:16 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -331,9 +331,15 @@
 #define	AUE_CRYPTOADM		292	/* =as kernel cryptographic framework */
 #define	AUE_CONFIGKSSL		293	/* =as kernel SSL */
 #define	AUE_BRANDSYS		294	/* =ot */
+#define	AUE_PF_POLICY_ADDRULE	295	/* =as Add IPsec policy rule */
+#define	AUE_PF_POLICY_DELRULE	296	/* =as Delete IPsec policy rule */
+#define	AUE_PF_POLICY_CLONE	297	/* =as Clone IPsec policy */
+#define	AUE_PF_POLICY_FLIP	298	/* =as Flip IPsec policy */
+#define	AUE_PF_POLICY_FLUSH	299	/* =as Flush IPsec policy rules */
+#define	AUE_PF_POLICY_ALGS	300	/* =as Update IPsec algorithms */
 /* NOTE: update MAX_KEVENTS below if events are added. */
 
-#define	MAX_KEVENTS		294
+#define	MAX_KEVENTS		300
 
 
 #ifdef __cplusplus
--- a/usr/src/uts/common/c2/audit_start.c	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/common/c2/audit_start.c	Thu May 24 09:24:16 2007 -0700
@@ -403,7 +403,7 @@
 	if (tad->tad_flag) {
 		tad->tad_flag = 0;
 
-		if (flag = audit_success(kctx, tad, error)) {
+		if (flag = audit_success(kctx, tad, error, NULL)) {
 			unsigned int sy_flags;
 			cred_t *cr = CRED();
 			const auditinfo_addr_t *ainfo = crgetauinfo(cr);
@@ -497,7 +497,8 @@
 }
 
 int
-audit_success(au_kcontext_t *kctx, struct t_audit_data *tad, int error)
+audit_success(au_kcontext_t *kctx, struct t_audit_data *tad, int error,
+    cred_t *cr)
 {
 	au_state_t ess;
 	au_state_t esf;
@@ -521,7 +522,12 @@
 	if (tad->tad_ctrl & PAD_AUDITME)
 		return (AU_OK);
 
-	ainfo = crgetauinfo(CRED());
+	/*
+	 * Used passed cred if available, otherwise use cred from kernel thread
+	 */
+	if (cr == NULL)
+		cr = CRED();
+	ainfo = crgetauinfo(cr);
 	if (ainfo == NULL)
 		return (0);
 	amask = ainfo->ai_mask;
--- a/usr/src/uts/common/inet/ip/spdsock.c	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/common/inet/ip/spdsock.c	Thu May 24 09:24:16 2007 -0700
@@ -66,6 +66,8 @@
 
 #include <sys/isa_defs.h>
 
+#include <c2/audit.h>
+
 /*
  * This is a transport provider for the PF_POLICY IPsec policy
  * management socket, which provides a management interface into the
@@ -185,6 +187,8 @@
 #define	ALL_ACTIVE_POLHEADS ((ipsec_policy_head_t *)-1)
 #define	ALL_INACTIVE_POLHEADS ((ipsec_policy_head_t *)-2)
 
+#define	ITP_NAME(itp) (itp != NULL ? itp->itp_name : NULL)
+
 /* ARGSUSED */
 static int
 spdsock_param_get(q, mp, cp, cr)
@@ -565,7 +569,8 @@
 }
 
 static void
-spdsock_flush(queue_t *q, ipsec_policy_head_t *iph, mblk_t *mp)
+spdsock_flush(queue_t *q, ipsec_policy_head_t *iph, ipsec_tun_pol_t *itp,
+    mblk_t *mp)
 {
 	boolean_t active;
 	spdsock_t *ss = (spdsock_t *)q->q_ptr;
@@ -574,16 +579,29 @@
 
 	if (iph != ALL_ACTIVE_POLHEADS && iph != ALL_INACTIVE_POLHEADS) {
 		spdsock_flush_one(iph, spds->spds_netstack);
+		if (audit_active) {
+			spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+			active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+			audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns,
+			    ITP_NAME(itp), active, 0, DB_CPID(mp));
+		}
 	} else {
 		active = (iph == ALL_ACTIVE_POLHEADS);
 
 		/* First flush the global policy. */
 		spdsock_flush_one(active ? ipsec_system_policy(ns) :
 		    ipsec_inactive_policy(ns), ns);
-
+		if (audit_active) {
+			audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns, NULL,
+			    active, 0, DB_CPID(mp));
+		}
 		/* Then flush every tunnel's appropriate one. */
 		itp_walk(spdsock_flush_node, (void *)active,
 		    spds->spds_netstack);
+		if (audit_active)
+			audit_pf_policy(SPD_FLUSH, DB_CRED(mp), ns,
+			    "all tunnels", active, 0, DB_CPID(mp));
 	}
 
 	spd_echo(q, mp);
@@ -985,6 +1003,14 @@
 
 	if (rule == NULL) {
 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
+		if (audit_active) {
+			spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+			active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+			audit_pf_policy(SPD_ADDRULE, DB_CRED(mp),
+			    spds->spds_netstack, ITP_NAME(itp), active,
+			    SPD_DIAGNOSTIC_NO_RULE_EXT, DB_CPID(mp));
+		}
 		return;
 	}
 
@@ -1084,6 +1110,13 @@
 
 	ipsec_actvec_free(actp, nact);
 	spd_echo(q, mp);
+	if (audit_active) {
+		spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+		active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+		audit_pf_policy(SPD_ADDRULE, DB_CRED(mp), spds->spds_netstack,
+		    ITP_NAME(itp), active, 0, DB_CPID(mp));
+	}
 	return;
 
 fail:
@@ -1099,6 +1132,13 @@
 		mutex_exit(&itp->itp_lock);
 	}
 	spdsock_error(q, mp, error, diag);
+	if (audit_active) {
+		spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+		active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+		audit_pf_policy(SPD_ADDRULE, DB_CRED(mp), spds->spds_netstack,
+		    ITP_NAME(itp), active, error, DB_CPID(mp));
+	}
 }
 
 void
@@ -1113,6 +1153,15 @@
 
 	if (rule == NULL) {
 		spdsock_diag(q, mp, SPD_DIAGNOSTIC_NO_RULE_EXT);
+		if (audit_active) {
+			boolean_t active;
+			spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+			active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+			audit_pf_policy(SPD_DELETERULE, DB_CRED(mp),
+			    spds->spds_netstack, ITP_NAME(itp), active,
+			    SPD_DIAGNOSTIC_NO_RULE_EXT, DB_CPID(mp));
+		}
 		return;
 	}
 
@@ -1164,11 +1213,28 @@
 		mutex_exit(&itp->itp_lock);
 	}
 	spd_echo(q, mp);
+	if (audit_active) {
+		boolean_t active;
+		spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+		active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+		audit_pf_policy(SPD_DELETERULE, DB_CRED(mp),
+		    spds->spds_netstack, ITP_NAME(itp), active, 0, DB_CPID(mp));
+	}
 	return;
 fail:
 	if (itp != NULL)
 		mutex_exit(&itp->itp_lock);
 	spdsock_error(q, mp, err, diag);
+	if (audit_active) {
+		boolean_t active;
+		spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+		active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+		audit_pf_policy(SPD_DELETERULE, DB_CRED(mp),
+		    spds->spds_netstack, ITP_NAME(itp), active, err,
+		    DB_CPID(mp));
+	}
 }
 
 /* Do NOT consume a reference to itp. */
@@ -1195,19 +1261,65 @@
 		if (*tname == '\0') {
 			/* can't fail */
 			ipsec_swap_global_policy(spds->spds_netstack);
+			if (audit_active) {
+				boolean_t active;
+				spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+				active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+				audit_pf_policy(SPD_FLIP, DB_CRED(mp),
+				    spds->spds_netstack, NULL, active, 0,
+				    DB_CPID(mp));
+			}
 			itp_walk(spdsock_flip_node, NULL, spds->spds_netstack);
+			if (audit_active) {
+				boolean_t active;
+				spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+				active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+				audit_pf_policy(SPD_FLIP, DB_CRED(mp),
+				    spds->spds_netstack, "all tunnels", active,
+				    0, DB_CPID(mp));
+			}
 		} else {
 			itp = get_tunnel_policy(tname, spds->spds_netstack);
 			if (itp == NULL) {
 				/* Better idea for "tunnel not found"? */
 				spdsock_error(q, mp, ESRCH, 0);
+				if (audit_active) {
+					boolean_t active;
+					spd_msg_t *spmsg =
+					    (spd_msg_t *)mp->b_rptr;
+
+					active = (spmsg->spd_msg_spdid ==
+					    SPD_ACTIVE);
+					audit_pf_policy(SPD_FLIP, DB_CRED(mp),
+					    spds->spds_netstack, ITP_NAME(itp),
+					    active, ESRCH, DB_CPID(mp));
+				}
 				return;
 			}
 			spdsock_flip_node(itp, NULL, NULL);
+			if (audit_active) {
+				boolean_t active;
+				spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+				active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+				audit_pf_policy(SPD_FLIP, DB_CRED(mp),
+				    spds->spds_netstack, ITP_NAME(itp), active,
+				    0, DB_CPID(mp));
+			}
 			ITP_REFRELE(itp, spds->spds_netstack);
 		}
 	} else {
 		ipsec_swap_global_policy(spds->spds_netstack);	/* can't fail */
+		if (audit_active) {
+			boolean_t active;
+			spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+			active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+			audit_pf_policy(SPD_FLIP, DB_CRED(mp),
+			    spds->spds_netstack, NULL, active, 0, DB_CPID(mp));
+		}
 	}
 	spd_echo(q, mp);
 }
@@ -1937,20 +2049,71 @@
 		tname = (char *)tunname->spd_if_name;
 		if (*tname == '\0') {
 			error = ipsec_clone_system_policy(spds->spds_netstack);
-			if (error == 0)
+			if (audit_active) {
+				boolean_t active;
+				spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+				active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+				audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+				    spds->spds_netstack, NULL, active, error,
+				    DB_CPID(mp));
+			}
+			if (error == 0) {
 				itp_walk(spdsock_clone_node, &error,
 				    spds->spds_netstack);
+				if (audit_active) {
+					boolean_t active;
+					spd_msg_t *spmsg =
+					    (spd_msg_t *)mp->b_rptr;
+
+					active = (spmsg->spd_msg_spdid ==
+					    SPD_ACTIVE);
+					audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+					    spds->spds_netstack,
+					    "all tunnels", active, 0,
+					    DB_CPID(mp));
+				}
+			}
 		} else {
 			itp = get_tunnel_policy(tname, spds->spds_netstack);
 			if (itp == NULL) {
 				spdsock_error(q, mp, ENOENT, 0);
+				if (audit_active) {
+					boolean_t active;
+					spd_msg_t *spmsg =
+					    (spd_msg_t *)mp->b_rptr;
+
+					active = (spmsg->spd_msg_spdid ==
+					    SPD_ACTIVE);
+					audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+					    spds->spds_netstack, ITP_NAME(itp),
+					    active, ENOENT, DB_CPID(mp));
+				}
 				return;
 			}
 			spdsock_clone_node(itp, &error, NULL);
 			ITP_REFRELE(itp, spds->spds_netstack);
+			if (audit_active) {
+				boolean_t active;
+				spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+				active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+				audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+				    spds->spds_netstack, ITP_NAME(itp), active,
+				    error, DB_CPID(mp));
+			}
 		}
 	} else {
 		error = ipsec_clone_system_policy(spds->spds_netstack);
+		if (audit_active) {
+			boolean_t active;
+			spd_msg_t *spmsg = (spd_msg_t *)mp->b_rptr;
+
+			active = (spmsg->spd_msg_spdid == SPD_ACTIVE);
+			audit_pf_policy(SPD_CLONE, DB_CRED(mp),
+			    spds->spds_netstack, NULL, active, error,
+			    DB_CPID(mp));
+		}
 	}
 
 	if (error != 0)
@@ -2495,7 +2658,10 @@
 		spds->spds_mp_algs = mp;
 		spds->spds_algs_pending = B_TRUE;
 		mutex_exit(&spds->spds_alg_lock);
-
+		if (audit_active)
+			audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
+			    spds->spds_netstack, NULL, B_TRUE, EAGAIN,
+			    DB_CPID(mp));
 		spd_echo(q, new_mp);
 	} else {
 		/*
@@ -2506,10 +2672,19 @@
 		mutex_enter(&spds->spds_alg_lock);
 		spdsock_do_updatealg(extv, &diag, spds);
 		mutex_exit(&spds->spds_alg_lock);
-		if (diag == -1)
+		if (diag == -1) {
 			spd_echo(q, mp);
-		else
+		if (audit_active)
+			audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
+			    spds->spds_netstack, NULL, B_TRUE, 0,
+			    DB_CPID(mp));
+		} else {
 			spdsock_diag(q, mp, diag);
+		if (audit_active)
+			audit_pf_policy(SPD_UPDATEALGS, DB_CRED(mp),
+			    spds->spds_netstack, NULL, B_TRUE, diag,
+			    DB_CPID(mp));
+		}
 	}
 }
 
@@ -2812,7 +2987,7 @@
 			mutex_exit(&itp->itp_lock);
 			ITP_REFRELE(itp, ns);
 		}
-		spdsock_flush(q, iph, mp);
+		spdsock_flush(q, iph, itp, mp);
 		return;
 	case SPD_DUMP:
 		if (itp != NULL)
--- a/usr/src/uts/intel/ia32/ml/modstubs.s	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s	Thu May 24 09:24:16 2007 -0700
@@ -937,6 +937,7 @@
 	NO_UNLOAD_STUB(c2audit, audit_cryptoadm,	nomod_zero);
 	NO_UNLOAD_STUB(c2audit, audit_update_context,	nomod_zero);
 	NO_UNLOAD_STUB(c2audit, audit_kssl,		nomod_zero);
+	NO_UNLOAD_STUB(c2audit, audit_pf_policy,	nomod_zero);
 	END_MODULE(c2audit);
 #endif
 
--- a/usr/src/uts/sparc/ml/modstubs.s	Thu May 24 08:54:31 2007 -0700
+++ b/usr/src/uts/sparc/ml/modstubs.s	Thu May 24 09:24:16 2007 -0700
@@ -871,6 +871,7 @@
 	NO_UNLOAD_STUB(c2audit, audit_cryptoadm,	nomod_zero);
 	NO_UNLOAD_STUB(c2audit, audit_update_context,	nomod_zero);
 	NO_UNLOAD_STUB(c2audit, audit_kssl,		nomod_zero);
+	NO_UNLOAD_STUB(c2audit, audit_pf_policy,	nomod_zero);
 	END_MODULE(c2audit);
 #endif