--- //depot/vendor/freebsd/src/sys/security/audit/audit.c	2008/08/11 20:15:14
+++ //depot/projects/soc2008/snagg-audit/sys/security/audit/audit.c	2008/08/16 17:32:42
@@ -388,7 +388,7 @@
 	if (au_preselect(event, class, aumask, sorf) != 0)
 		ar->k_ar_commit |= AR_PRESELECT_TRAIL;
 	if (audit_pipe_preselect(auid, event, class, sorf,
-	    ar->k_ar_commit & AR_PRESELECT_TRAIL) != 0)
+	    ar->k_ar_commit & AR_PRESELECT_TRAIL, ar->k_ar.ar_subj_pid) != 0)
 		ar->k_ar_commit |= AR_PRESELECT_PIPE;
 	if ((ar->k_ar_commit & (AR_PRESELECT_TRAIL | AR_PRESELECT_PIPE |
 	    AR_PRESELECT_USER_TRAIL | AR_PRESELECT_USER_PIPE)) == 0) {
@@ -494,7 +494,8 @@
 			panic("audit_failing_stop: thread continued");
 		}
 		td->td_ar = audit_new(event, td);
-	} else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0))
+	} else if (audit_pipe_preselect(auid, event, class, AU_PRS_BOTH, 0, 
+			    td->td_proc->p_pid))
 		td->td_ar = audit_new(event, td);
 	else
 		td->td_ar = NULL;
@@ -610,7 +611,8 @@
 		sorf = AU_PRS_SUCCESS;
 	class = au_event_class(AUE_CORE);
 	if (au_preselect(AUE_CORE, class, aumask, sorf) == 0 &&
-	    audit_pipe_preselect(auid, AUE_CORE, class, sorf, 0) == 0)
+	    audit_pipe_preselect(auid, AUE_CORE, class, sorf, 0, 
+		td->td_proc->p_pid) == 0)
 		return;
 	/*
 	 * If we are interested in seeing this audit record, allocate it.

--- //depot/vendor/freebsd/src/sys/security/audit/audit_ioctl.h	2007/04/29 16:23:02
+++ //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_ioctl.h	2008/07/13 23:40:36
@@ -38,7 +38,12 @@
  * structures, add new revised ones to be used by new ioctls, and keep the
  * old structures and ioctls for backwards compatibility.
  */
-struct auditpipe_ioctl_preselect {
+struct auditpipe_ioctl_preselect_proc {
+	int			aipp_flag;
+	pid_t		aipp_pid;
+};
+
+struct auditpipe_ioctl_preselect{
 	au_id_t		aip_auid;
 	au_mask_t	aip_mask;
 };
@@ -48,6 +53,7 @@
  */
 #define	AUDITPIPE_PRESELECT_MODE_TRAIL	1	/* Global audit trail. */
 #define	AUDITPIPE_PRESELECT_MODE_LOCAL	2	/* Local audit trail. */
+#define	AUDITPIPE_PRESELECT_MODE_PROC	3	/* Pid based audit trail. */
 
 /*
  * Ioctls to read and control the behavior of individual audit pipe devices.
@@ -71,6 +77,12 @@
 #define	AUDITPIPE_SET_PRESELECT_MODE	_IOW(AUDITPIPE_IOBASE, 15, int)
 #define	AUDITPIPE_FLUSH			_IO(AUDITPIPE_IOBASE, 16)
 #define	AUDITPIPE_GET_MAXAUDITDATA	_IOR(AUDITPIPE_IOBASE, 17, u_int)
+#define	AUDITPIPE_GET_PRESELECT_PROC	_IOWR(AUDITPIPE_IOBASE, 18,	\
+		    struct auditpipe_ioctl_preselect_proc)
+#define	AUDITPIPE_SET_PRESELECT_PROC	_IOW(AUDITPIPE_IOBASE, 19,	\
+		    struct auditpipe_ioctl_preselect_proc)
+#define	AUDITPIPE_DELETE_PRESELECT_PROC	_IOW(AUDITPIPE_IOBASE, 20, pid_t)
+#define	AUDITPIPE_FLUSH_PRESELECT_PROC	_IO(AUDITPIPE_IOBASE, 21)
 
 /*
  * Ioctls to retrieve audit pipe statistics.
--- //depot/vendor/freebsd/src/sys/security/audit/audit_pipe.c	2008/07/31 10:00:16
+++ //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_pipe.c	2008/08/16 17:28:23
@@ -27,7 +27,13 @@
  */
 
 #include <sys/cdefs.h>
+>>>> ORIGINAL //depot/vendor/freebsd/src/sys/security/audit/audit_pipe.c#15
+__FBSDID("$FreeBSD: src/sys/security/audit/audit_pipe.c,v 1.16 2008/06/11 18:55:19 ed Exp $");
+==== THEIRS //depot/vendor/freebsd/src/sys/security/audit/audit_pipe.c#16
 __FBSDID("$FreeBSD: src/sys/security/audit/audit_pipe.c,v 1.17 2008/07/31 09:54:35 rwatson Exp $");
+==== YOURS //snagg_macosx/sys/security/audit/audit_pipe.c
+__FBSDID("$FreeBSD: src/sys/security/audit/audit_pipe.c,v 1.15 2008/04/13 22:06:56 rwatson Exp $");
+<<<<
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -97,8 +103,10 @@
  * usage patterns for per-auid specifications are clear.
  */
 struct audit_pipe_preselect {
-	au_id_t					 app_auid;
-	au_mask_t				 app_mask;
+	au_id_t		app_auid;
+	au_mask_t	app_mask;
+	pid_t		app_pid;
+	int			app_flag;
 	TAILQ_ENTRY(audit_pipe_preselect)	 app_list;
 };
 
@@ -177,7 +185,7 @@
 
 static struct cdevsw	audit_pipe_cdevsw = {
 	.d_version =	D_VERSION,
-	.d_flags =	D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR,
+	.d_flags =	D_PSEUDO | D_NEEDGIANT,
 	.d_open =	audit_pipe_open,
 	.d_close =	audit_pipe_close,
 	.d_read =	audit_pipe_read,
@@ -215,7 +223,24 @@
 	free(ape->ape_record, M_AUDIT_PIPE_ENTRY);
 	free(ape, M_AUDIT_PIPE_ENTRY);
 }
+			
+/*
+ * Find an audit pipe preselection specification for a pid, if any.
+ */
+static struct audit_pipe_preselect *
+audit_pipe_preselect_find_proc(struct audit_pipe *ap, pid_t app_pid)
+{
+	struct audit_pipe_preselect *app;
+	
+	mtx_assert(&audit_pipe_mtx, MA_OWNED);
 
+	TAILQ_FOREACH(app, &ap->ap_preselect_list, app_list) {
+		if (app->app_pid == app_pid)
+			return (app);
+	}
+	return (NULL);
+}
+
 /*
  * Find an audit pipe preselection specification for an auid, if any.
  */
@@ -255,7 +280,69 @@
 }
 
 /*
- * Set the per-pipe mask for a specific auid.  Add a new entry if needed;
+ * Check if there's an entry for a given pid.
+ */
+static int
+audit_pipe_preselect_get_proc(struct audit_pipe *ap, pid_t pid, 
+	    struct auditpipe_ioctl_preselect_proc *aipp)
+{
+	struct audit_pipe_preselect *app;
+	int error;
+	
+	mtx_lock(&audit_pipe_mtx);
+	app = audit_pipe_preselect_find_proc(ap, pid);
+	if (app != NULL) {
+		aipp->aipp_pid = pid;
+		aipp->aipp_flag = app->app_flag;
+		error = 0;
+	}else
+		error = ENOENT;
+		
+	mtx_unlock(&audit_pipe_mtx);
+	return (error);
+}
+	
+/*
+ * Add a new entry for a specifc event.  Add a new entry if needed;
+ * otherwise, update the current entry.
+ */
+static int
+audit_pipe_preselect_set_proc(struct audit_pipe *ap, 
+	    struct auditpipe_ioctl_preselect_proc *aipp)
+{
+	struct audit_pipe_preselect *app, *app_new;
+
+	if (aipp->aipp_pid < 0)
+		return (EINVAL);
+
+	/*
+	 * Pessimistically assume that the entry for this pid doesn't  exist, 
+	 * and allocate.  We will free it if it is unneeded.
+	 */
+	app_new = malloc(sizeof(*app_new), M_AUDIT_PIPE_PRESELECT, M_WAITOK);
+	mtx_lock(&audit_pipe_mtx);
+
+	/*
+	 * Search for the entry by its pid.
+	 */
+	app = audit_pipe_preselect_find_proc(ap, aipp->aipp_pid);
+	if (app == NULL) {
+		app = app_new;
+		app_new = NULL;
+		app->app_pid = aipp->aipp_pid;
+		app->app_flag = aipp->aipp_flag;
+		TAILQ_INSERT_TAIL(&ap->ap_preselect_list, app, app_list);
+	}
+	
+	mtx_unlock(&audit_pipe_mtx);
+	if (app_new != NULL)
+		free(app_new, M_AUDIT_PIPE_PRESELECT);
+
+	return (0);
+}	
+
+/*
+ * Set the per-pipe mask for a specific event.  Add a new entry if needed;
  * otherwise, update the current entry.
  */
 static void
@@ -283,6 +370,26 @@
 }
 
 /*
+ * Delete a per-pid entry on an audit pipe wiping the whole entry.
+ */
+static int
+audit_pipe_preselect_delete_proc(struct audit_pipe *ap, pid_t pid)
+{
+	struct audit_pipe_preselect *app;
+	
+	mtx_lock(&audit_pipe_mtx);
+	app = audit_pipe_preselect_find_proc(ap, pid);
+	if (app != NULL) {
+		TAILQ_REMOVE(&ap->ap_preselect_list, app, app_list);
+		mtx_unlock(&audit_pipe_mtx);
+		free(app, M_AUDIT_PIPE_PRESELECT);	
+		return (0);
+	} else
+		mtx_unlock(&audit_pipe_mtx);
+	return (ENOENT);
+}
+
+/*
  * Delete a per-auid mask on an audit pipe.
  */
 static int
@@ -341,7 +448,8 @@
  */
 static int
 audit_pipe_preselect_check(struct audit_pipe *ap, au_id_t auid,
-    au_event_t event, au_class_t class, int sorf, int trail_preselect)
+    au_event_t event, au_class_t class, int sorf, int trail_preselect, 
+    pid_t app_pid)
 {
 	struct audit_pipe_preselect *app;
 
@@ -364,6 +472,13 @@
 			return (au_preselect(event, class, &app->app_mask,
 			    sorf));
 
+	case AUDITPIPE_PRESELECT_MODE_PROC:
+		app = audit_pipe_preselect_find_proc(ap, app_pid);
+		if (app != NULL)
+			return (1);
+		else
+			break;
+			
 	default:
 		panic("audit_pipe_preselect_check: mode %d",
 		    ap->ap_preselect_mode);
@@ -378,14 +493,14 @@
  */
 int
 audit_pipe_preselect(au_id_t auid, au_event_t event, au_class_t class,
-    int sorf, int trail_preselect)
+    int sorf, int trail_preselect, pid_t app_pid)
 {
 	struct audit_pipe *ap;
 
 	mtx_lock(&audit_pipe_mtx);
 	TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) {
 		if (audit_pipe_preselect_check(ap, auid, event, class, sorf,
-		    trail_preselect)) {
+		    trail_preselect, app_pid)) {
 			mtx_unlock(&audit_pipe_mtx);
 			return (1);
 		}
@@ -449,7 +564,7 @@
  */
 void
 audit_pipe_submit(au_id_t auid, au_event_t event, au_class_t class, int sorf,
-    int trail_select, void *record, u_int record_len)
+    int trail_select, void *record, u_int record_len, pid_t app_pid)
 {
 	struct audit_pipe *ap;
 
@@ -462,7 +577,7 @@
 	mtx_lock(&audit_pipe_mtx);
 	TAILQ_FOREACH(ap, &audit_pipe_list, ap_list) {
 		if (audit_pipe_preselect_check(ap, auid, event, class, sorf,
-		    trail_select))
+		    trail_select, app_pid))
 			audit_pipe_append(ap, record, record_len);
 	}
 	audit_pipe_records++;
@@ -687,10 +802,12 @@
     struct thread *td)
 {
 	struct auditpipe_ioctl_preselect *aip;
+	struct auditpipe_ioctl_preselect_proc *aip_pid;
 	struct audit_pipe *ap;
 	au_mask_t *maskp;
 	int error, mode;
 	au_id_t auid;
+	pid_t app_pid;
 
 	ap = dev->si_drv1;
 	KASSERT(ap != NULL, ("audit_pipe_ioctl: ap == NULL"));
@@ -809,6 +926,16 @@
 		    &aip->aip_mask);
 		break;
 
+	case AUDITPIPE_GET_PRESELECT_PROC:
+		aip_pid = (struct auditpipe_ioctl_preselect_proc *)data;
+		error = audit_pipe_preselect_get_proc(ap, aip_pid->aipp_pid, aip_pid);
+		break;
+
+	case AUDITPIPE_SET_PRESELECT_PROC:
+		aip_pid = (struct auditpipe_ioctl_preselect_proc *)data;
+		error = audit_pipe_preselect_set_proc(ap, aip_pid);
+		break;
+
 	case AUDITPIPE_SET_PRESELECT_AUID:
 		aip = (struct auditpipe_ioctl_preselect *)data;
 		audit_pipe_preselect_set(ap, aip->aip_auid, aip->aip_mask);
@@ -820,7 +947,13 @@
 		error = audit_pipe_preselect_delete(ap, auid);
 		break;
 
+	case AUDITPIPE_DELETE_PRESELECT_PROC:
+		app_pid = *(pid_t *)data;
+		error = audit_pipe_preselect_delete_proc(ap, app_pid);
+		break;
+
 	case AUDITPIPE_FLUSH_PRESELECT_AUID:
+	case AUDITPIPE_FLUSH_PRESELECT_PROC:
 		audit_pipe_preselect_flush(ap);
 		error = 0;
 		break;
@@ -837,6 +970,8 @@
 		switch (mode) {
 		case AUDITPIPE_PRESELECT_MODE_TRAIL:
 		case AUDITPIPE_PRESELECT_MODE_LOCAL:
+		case AUDITPIPE_PRESELECT_MODE_PROC:
+			audit_pipe_preselect_flush(ap);
 			mtx_lock(&audit_pipe_mtx);
 			ap->ap_preselect_mode = mode;
 			mtx_unlock(&audit_pipe_mtx);
--- //depot/vendor/freebsd/src/sys/security/audit/audit_private.h	2008/07/31 10:00:16
+++ //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_private.h	2008/08/16 17:28:23
@@ -331,9 +331,9 @@
  * Audit pipe functions.
  */
 int	 audit_pipe_preselect(au_id_t auid, au_event_t event,
-	    au_class_t class, int sorf, int trail_select);
+	    au_class_t class, int sorf, int trail_select, pid_t app_pid);
 void	 audit_pipe_submit(au_id_t auid, au_event_t event, au_class_t class,
-	    int sorf, int trail_select, void *record, u_int record_len);
+	    int sorf, int trail_select, void *record, u_int record_len, pid_t app_pid);
 void	 audit_pipe_submit_user(void *record, u_int record_len);
 
 #endif /* ! _SECURITY_AUDIT_PRIVATE_H_ */
--- //depot/vendor/freebsd/src/sys/security/audit/audit_worker.c	2008/07/31 10:00:16
+++ //depot/projects/soc2008/snagg-audit/sys/security/audit/audit_worker.c	2008/08/16 17:28:23
@@ -367,7 +367,7 @@
 	if (ar->k_ar_commit & AR_PRESELECT_PIPE)
 		audit_pipe_submit(auid, event, class, sorf,
 		    ar->k_ar_commit & AR_PRESELECT_TRAIL, bsm->data,
-		    bsm->len);
+		    bsm->len, ar->k_ar.ar_subj_pid);
 
 	kau_free(bsm);
 out:
