--- sys/kern/init_main.c	2007/05/28 12:57:17
+++ sys/kern/init_main.c	2007/05/29 15:12:54
@@ -440,8 +440,7 @@
 	p->p_ucred->cr_ruidinfo = uifind(0);
 	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
 #ifdef AUDIT
-	audit_proc_alloc(p);
-	audit_proc_kproc0(p);
+	audit_cred_kproc0(p->p_ucred);
 #endif
 #ifdef MAC
 	mac_create_proc0(p->p_ucred);
@@ -706,7 +705,7 @@
 	mac_create_proc1(newcred);
 #endif
 #ifdef AUDIT
-	audit_proc_init(initproc);
+	audit_cred_proc1(newcred);
 #endif
 	initproc->p_ucred = newcred;
 	PROC_UNLOCK(initproc);
--- sys/kern/kern_exit.c	2007/05/28 12:57:17
+++ sys/kern/kern_exit.c	2007/05/29 15:12:54
@@ -801,9 +801,6 @@
 #ifdef MAC
 			mac_destroy_proc(p);
 #endif
-#ifdef AUDIT
-			audit_proc_free(p);
-#endif
 			KASSERT(FIRST_THREAD_IN_PROC(p),
 			    ("kern_wait: no residual thread!"));
 			uma_zfree(proc_zone, p);
--- sys/kern/kern_fork.c	2007/05/28 12:57:17
+++ sys/kern/kern_fork.c	2007/05/29 15:12:54
@@ -279,9 +279,6 @@
 #ifdef MAC
 	mac_init_proc(newproc);
 #endif
-#ifdef AUDIT
-	audit_proc_alloc(newproc);
-#endif
 	knlist_init(&newproc->p_klist, &newproc->p_mtx, NULL, NULL, NULL);
 	STAILQ_INIT(&newproc->p_ktr);
 
@@ -511,9 +508,6 @@
 
 	mtx_unlock_spin(&sched_lock);
 	td2->td_ucred = crhold(p2->p_ucred);
-#ifdef AUDIT
-	audit_proc_fork(p1, p2);
-#endif
 	pargs_hold(p2->p_args);
 
 	if (flags & RFSIGSHARE) {
@@ -752,9 +746,6 @@
 #ifdef MAC
 	mac_destroy_proc(newproc);
 #endif
-#ifdef AUDIT
-	audit_proc_free(newproc);
-#endif
 	uma_zfree(proc_zone, newproc);
 	if (p1->p_flag & P_HADTHREADS) {
 		PROC_LOCK(p1);
--- sys/kern/kern_prot.c	2007/04/08 13:38:53
+++ sys/kern/kern_prot.c	2007/05/29 14:28:56
@@ -1763,6 +1771,9 @@
 
 	MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK | M_ZERO);
 	refcount_init(&cr->cr_ref, 1);
+#ifdef AUDIT
+	audit_cred_init(cr);
+#endif
 #ifdef MAC
 	mac_init_cred(cr);
 #endif
@@ -1804,6 +1815,9 @@
 		 */
 		if (jailed(cr))
 			prison_free(cr->cr_prison);
+#ifdef AUDIT
+		audit_cred_destroy(cr);
+#endif
 #ifdef MAC
 		mac_destroy_cred(cr);
 #endif
@@ -1836,6 +1850,9 @@
 	uihold(dest->cr_ruidinfo);
 	if (jailed(dest))
 		prison_hold(dest->cr_prison);
+#ifdef AUDIT
+	audit_cred_copy(src, dest);
+#endif
 #ifdef MAC
 	mac_copy_cred(src, dest);
 #endif
--- sys/security/audit/audit.c	2007/05/30 09:33:24
+++ sys/security/audit/audit.c	2007/05/30 09:38:26
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999-2005 Apple Computer, Inc.
- * Copyright (c) 2006 Robert N. M. Watson
+ * Copyright (c) 2006-2007 Robert N. M. Watson
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -71,7 +71,7 @@
 #include <vm/uma.h>
 
 static uma_zone_t	audit_record_zone;
-static MALLOC_DEFINE(M_AUDITPROC, "audit_proc", "Audit process storage");
+static MALLOC_DEFINE(M_AUDITCRED, "audit_cred", "Audit cred storage");
 MALLOC_DEFINE(M_AUDITDATA, "audit_data", "Audit data storage");
 MALLOC_DEFINE(M_AUDITPATH, "audit_path", "Audit path storage");
 MALLOC_DEFINE(M_AUDITTEXT, "audit_text", "Audit text storage");
@@ -178,14 +178,11 @@
 	ar->k_ar.ar_subj_ruid = td->td_ucred->cr_ruid;
 	ar->k_ar.ar_subj_rgid = td->td_ucred->cr_rgid;
 	ar->k_ar.ar_subj_egid = td->td_ucred->cr_groups[0];
-	PROC_LOCK(td->td_proc);
-	ar->k_ar.ar_subj_auid = td->td_proc->p_au->ai_auid;
-	ar->k_ar.ar_subj_asid = td->td_proc->p_au->ai_asid;
+	ar->k_ar.ar_subj_auid = td->td_ucred->cr_audit.ai_auid;
+	ar->k_ar.ar_subj_asid = td->td_ucred->cr_audit.ai_asid;
 	ar->k_ar.ar_subj_pid = td->td_proc->p_pid;
-	ar->k_ar.ar_subj_amask = td->td_proc->p_au->ai_mask;
-	ar->k_ar.ar_subj_term_addr = td->td_proc->p_au->ai_termid;
-	PROC_UNLOCK(td->td_proc);
-
+	ar->k_ar.ar_subj_amask = td->td_ucred->cr_audit.ai_mask;
+	ar->k_ar.ar_subj_term_addr = td->td_ucred->cr_audit.ai_termid;
 	return (0);
 }
 
@@ -480,11 +479,11 @@
 	 * Check which audit mask to use; either the kernel non-attributable
 	 * event mask or the process audit mask.
 	 */
-	auid = td->td_proc->p_au->ai_auid;
+	auid = td->td_ucred->cr_audit.ai_auid;
 	if (auid == AU_DEFAUDITID)
 		aumask = &audit_nae_mask;
 	else
-		aumask = &td->td_proc->p_au->ai_mask;
+		aumask = &td->td_ucred->cr_audit.ai_mask;
 
 	/*
 	 * Allocate an audit record, if preselection allows it, and store
@@ -548,88 +547,68 @@
 }
 
 /*
- * Allocate storage for a new process (init, or otherwise).
+ * Copy audit state from an existing credential to a new credential.
  */
 void
-audit_proc_alloc(struct proc *p)
+audit_cred_copy(struct ucred *src, struct ucred *dest)
 {
 
-	KASSERT(p->p_au == NULL, ("audit_proc_alloc: p->p_au != NULL (%d)",
-	    p->p_pid));
-	p->p_au = malloc(sizeof(*(p->p_au)), M_AUDITPROC, M_WAITOK);
+	bcopy(&src->cr_audit, &dest->cr_audit, sizeof(dest->cr_audit));
 }
 
 /*
- * Allocate storage for a new thread.
+ * Free audit state from a credential when the credential is freed.
  */
 void
-audit_thread_alloc(struct thread *td)
+audit_cred_destroy(struct ucred *cred)
 {
 
-	td->td_ar = NULL;
+	bzero(&cred->cr_audit, sizeof(cred->cr_audit));
 }
 
 /*
- * Thread destruction.
+ * Allocate audit state for a new credential.
  */
 void
-audit_thread_free(struct thread *td)
+audit_cred_init(struct ucred *cred)
 {
 
-	KASSERT(td->td_ar == NULL, ("audit_thread_free: td_ar != NULL"));
+	bzero(&cred->cr_audit, sizeof(cred->cr_audit));
 }
 
 /*
  * Initialize audit information for the first kernel process (proc 0) and for
  * the first user process (init).
- *
- * XXX It is not clear what the initial values should be for audit ID,
- * session ID, etc.
  */
 void
-audit_proc_kproc0(struct proc *p)
+audit_cred_kproc0(struct ucred *cred)
 {
 
-	KASSERT(p->p_au != NULL, ("audit_proc_kproc0: p->p_au == NULL (%d)",
-	    p->p_pid));
-	bzero(p->p_au, sizeof(*(p)->p_au));
 }
 
 void
-audit_proc_init(struct proc *p)
+audit_cred_proc1(struct ucred *cred)
 {
 
-	KASSERT(p->p_au != NULL, ("audit_proc_init: p->p_au == NULL (%d)",
-	    p->p_pid));
-	bzero(p->p_au, sizeof(*(p)->p_au));
-	p->p_au->ai_auid = AU_DEFAUDITID;
+	cred->cr_audit.ai_auid = AU_DEFAUDITID;
 }
 
 /*
- * Copy the audit info from the parent process to the child process when
- * a fork takes place.
+ * Allocate storage for a new thread.
  */
 void
-audit_proc_fork(struct proc *parent, struct proc *child)
+audit_thread_alloc(struct thread *td)
 {
 
-	PROC_LOCK_ASSERT(parent, MA_OWNED);
-	PROC_LOCK_ASSERT(child, MA_OWNED);
-	KASSERT(parent->p_au != NULL,
-	    ("audit_proc_fork: parent->p_au == NULL (%d)", parent->p_pid));
-	KASSERT(child->p_au != NULL,
-	    ("audit_proc_fork: child->p_au == NULL (%d)", child->p_pid));
-	bcopy(parent->p_au, child->p_au, sizeof(*child->p_au));
+	td->td_ar = NULL;
 }
 
 /*
- * Free the auditing structure for the process.
+ * Thread destruction.
  */
 void
-audit_proc_free(struct proc *p)
+audit_thread_free(struct thread *td)
 {
 
-	KASSERT(p->p_au != NULL, ("p->p_au == NULL (%d)", p->p_pid));
-	free(p->p_au, M_AUDITPROC);
-	p->p_au = NULL;
+	KASSERT(td->td_ar == NULL, ("audit_thread_free: td_ar != NULL"));
 }
--- sys/security/audit/audit.h	2007/05/30 13:41:06
+++ sys/security/audit/audit.h	2007/05/30 13:41:51
@@ -171,11 +173,11 @@
 void	 audit_arg_argv(char *argv, int argc, int length);
 void	 audit_arg_envv(char *envv, int envc, int length);
 void	 audit_sysclose(struct thread *td, int fd);
-void	 audit_proc_alloc(struct proc *p);
-void	 audit_proc_kproc0(struct proc *p);
-void	 audit_proc_init(struct proc *p);
-void	 audit_proc_fork(struct proc *parent, struct proc *child);
-void	 audit_proc_free(struct proc *p);
+void	 audit_cred_copy(struct ucred *src, struct ucred *dest);
+void	 audit_cred_destroy(struct ucred *cred);
+void	 audit_cred_init(struct ucred *cred);
+void	 audit_cred_kproc0(struct ucred *cred);
+void	 audit_cred_proc1(struct ucred *cred);
 void	 audit_thread_alloc(struct thread *td);
 void	 audit_thread_free(struct thread *td);
 
--- sys/security/audit/audit_arg.c	2007/04/18 10:19:42
+++ sys/security/audit/audit_arg.c	2007/05/30 09:45:06
@@ -365,13 +365,13 @@
 	if (ar == NULL)
 		return;
 
-	ar->k_ar.ar_arg_auid = p->p_au->ai_auid;
+	ar->k_ar.ar_arg_auid = p->p_ucred->cr_audit.ai_auid;
 	ar->k_ar.ar_arg_euid = p->p_ucred->cr_uid;
 	ar->k_ar.ar_arg_egid = p->p_ucred->cr_groups[0];
 	ar->k_ar.ar_arg_ruid = p->p_ucred->cr_ruid;
 	ar->k_ar.ar_arg_rgid = p->p_ucred->cr_rgid;
-	ar->k_ar.ar_arg_asid = p->p_au->ai_asid;
-	ar->k_ar.ar_arg_termid_addr = p->p_au->ai_termid;
+	ar->k_ar.ar_arg_asid = p->p_ucred->cr_audit.ai_asid;
+	ar->k_ar.ar_arg_termid_addr = p->p_ucred->cr_audit.ai_termid;
 	ar->k_ar.ar_arg_pid = p->p_pid;
 	ARG_SET_VALID(ar, ARG_AUID | ARG_EUID | ARG_EGID | ARG_RUID |
 	    ARG_RGID | ARG_ASID | ARG_TERMID_ADDR | ARG_PID | ARG_PROCESS);
--- sys/security/audit/audit_syscalls.c	2007/05/30 13:41:06
+++ sys/security/audit/audit_syscalls.c	2007/05/30 14:04:10
@@ -156,6 +167,7 @@
 int
 auditon(struct thread *td, struct auditon_args *uap)
 {
+	struct ucred *newcred, *oldcred;
 	int error;
 	union auditon_udata udata;
 	struct proc *tp;
@@ -313,47 +325,53 @@
 	case A_GETPINFO:
 		if (udata.au_aupinfo.ap_pid < 1)
 			return (EINVAL);
-
 		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
 			return (EINVAL);
 		if (p_cansee(td, tp) != 0) {
 			PROC_UNLOCK(tp);
 			return (EINVAL);
 		}
-
-		if (tp->p_au->ai_termid.at_type == AU_IPv6) {
+		if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) {
 			PROC_UNLOCK(tp);
 			return (EINVAL);
 		}
-		udata.au_aupinfo.ap_auid = tp->p_au->ai_auid;
+		udata.au_aupinfo.ap_auid =
+		    tp->p_ucred->cr_audit.ai_auid;
 		udata.au_aupinfo.ap_mask.am_success =
-		    tp->p_au->ai_mask.am_success;
+		    tp->p_ucred->cr_audit.ai_mask.am_success;
 		udata.au_aupinfo.ap_mask.am_failure =
-		    tp->p_au->ai_mask.am_failure;
+		    tp->p_ucred->cr_audit.ai_mask.am_failure;
 		udata.au_aupinfo.ap_termid.machine =
-		    tp->p_au->ai_termid.at_addr[0];
+		    tp->p_ucred->cr_audit.ai_termid.at_addr[0];
 		udata.au_aupinfo.ap_termid.port =
-		    (dev_t)tp->p_au->ai_termid.at_port;
-		udata.au_aupinfo.ap_asid = tp->p_au->ai_asid;
+		    (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port;
+		udata.au_aupinfo.ap_asid =
+		    tp->p_ucred->cr_audit.ai_asid;
 		PROC_UNLOCK(tp);
 		break;
 
 	case A_SETPMASK:
 		if (udata.au_aupinfo.ap_pid < 1)
 			return (EINVAL);
-
-		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL)
+		newcred = crget();
+		if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) {
+			crfree(newcred);
 			return (EINVAL);
+		}
 		if (p_cansee(td, tp) != 0) {
 			PROC_UNLOCK(tp);
+			crfree(newcred);
 			return (EINVAL);
 		}
-
-		tp->p_au->ai_mask.am_success =
+		oldcred = tp->p_ucred;
+		crcopy(newcred, oldcred);
+		newcred->cr_audit.ai_mask.am_success =
 		    udata.au_aupinfo.ap_mask.am_success;
-		tp->p_au->ai_mask.am_failure =
+		newcred->cr_audit.ai_mask.am_failure =
 		    udata.au_aupinfo.ap_mask.am_failure;
+		td->td_proc->p_ucred = newcred;
 		PROC_UNLOCK(tp);
+		crfree(oldcred);
 		break;
 
 	case A_SETFSIZE:
@@ -373,13 +391,16 @@
 			return (EINVAL);
 		if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL)
 			return (EINVAL);
-		udata.au_aupinfo_addr.ap_auid = tp->p_au->ai_auid;
+		udata.au_aupinfo_addr.ap_auid =
+		    tp->p_ucred->cr_audit.ai_auid;
 		udata.au_aupinfo_addr.ap_mask.am_success =
-		    tp->p_au->ai_mask.am_success;
+		    tp->p_ucred->cr_audit.ai_mask.am_success;
 		udata.au_aupinfo_addr.ap_mask.am_failure =
-		    tp->p_au->ai_mask.am_failure;
-		udata.au_aupinfo_addr.ap_termid = tp->p_au->ai_termid;
-		udata.au_aupinfo_addr.ap_asid = tp->p_au->ai_asid;
+		    tp->p_ucred->cr_audit.ai_mask.am_failure;
+		udata.au_aupinfo_addr.ap_termid =
+		    tp->p_ucred->cr_audit.ai_termid;
+		udata.au_aupinfo_addr.ap_asid =
+		    tp->p_ucred->cr_audit.ai_asid;
 		PROC_UNLOCK(tp);
 		break;
 
@@ -431,64 +452,51 @@
 getauid(struct thread *td, struct getauid_args *uap)
 {
 	int error;
-	au_id_t id;
 
 	if (jailed(td->td_ucred))
 		return (ENOSYS);
 	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
 	if (error)
 		return (error);
-
-	/*
-	 * XXX: Integer read on static pointer dereference: doesn't need
-	 * locking?
-	 */
-	PROC_LOCK(td->td_proc);
-	id = td->td_proc->p_au->ai_auid;
-	PROC_UNLOCK(td->td_proc);
-	return copyout(&id, uap->auid, sizeof(id));
+	return (copyout(&td->td_ucred->cr_audit.ai_auid, uap->auid,
+	    sizeof(td->td_ucred->cr_audit.ai_auid)));
 }
 
 /* ARGSUSED */
 int
 setauid(struct thread *td, struct setauid_args *uap)
 {
+	struct ucred *newcred, *oldcred;
+	au_id_t id;
 	int error;
-	au_id_t id;
 
 	if (jailed(td->td_ucred))
 		return (ENOSYS);
-	error = priv_check(td, PRIV_AUDIT_SETAUDIT);
-	if (error)
-		return (error);
-
 	error = copyin(uap->auid, &id, sizeof(id));
 	if (error)
 		return (error);
-
 	audit_arg_auid(id);
-
+	newcred = crget();
+	PROC_LOCK(td->td_proc);
+	oldcred = td->td_proc->p_ucred;
+	crcopy(newcred, oldcred);
 #ifdef MAC
-	error = mac_check_proc_setauid(td->td_ucred, id);
+	error = mac_check_proc_setauid(oldcred, id);
 	if (error)
-		return (error);
+		goto fail;
 #endif
-
-	/*
-	 * XXX: Integer write on static pointer dereference: doesn't need
-	 * locking?
-	 *
-	 * XXXAUDIT: Might need locking to serialize audit events in the same
-	 * order as change events?  Or maybe that's an under-solveable
-	 * problem.
-	 *
-	 * XXXRW: Test privilege while holding the proc lock?
-	 */
-	PROC_LOCK(td->td_proc);
-	td->td_proc->p_au->ai_auid = id;
+	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
+	if (error)
+		goto fail;
+	newcred->cr_audit.ai_auid = id;
+	td->td_proc->p_ucred = newcred;
 	PROC_UNLOCK(td->td_proc);
-
+	crfree(oldcred);
 	return (0);
+fail:
+	PROC_UNLOCK(td->td_proc);
+	crfree(newcred);
+	return (error);
 }
 
 /*
@@ -506,108 +514,108 @@
 	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
 	if (error)
 		return (error);
-
-	PROC_LOCK(td->td_proc);
-	if (td->td_proc->p_au->ai_termid.at_type == AU_IPv6) {
-		PROC_UNLOCK(td->td_proc);
-		return (E2BIG);
-	}
 	bzero(&ai, sizeof(ai));
-	ai.ai_auid = td->td_proc->p_au->ai_auid;
-	ai.ai_mask = td->td_proc->p_au->ai_mask;
-	ai.ai_asid = td->td_proc->p_au->ai_asid;
-	ai.ai_termid.machine = td->td_proc->p_au->ai_termid.at_addr[0];
-	ai.ai_termid.port = td->td_proc->p_au->ai_termid.at_port;
-	PROC_UNLOCK(td->td_proc);
-
-	return (copyout(&ai, uap->auditinfo, sizeof(ai)));
+	ai.ai_auid = td->td_ucred->cr_audit.ai_auid;
+	ai.ai_mask = td->td_ucred->cr_audit.ai_mask;
+	ai.ai_asid = td->td_ucred->cr_audit.ai_asid;
+	ai.ai_termid.machine = td->td_ucred->cr_audit.ai_termid.at_addr[0];
+	ai.ai_termid.port = td->td_ucred->cr_audit.ai_termid.at_port;
+	return (copyout(&ai, uap->auditinfo, sizeof(&ai)));
 }
 
 /* ARGSUSED */
 int
 setaudit(struct thread *td, struct setaudit_args *uap)
 {
+	struct ucred *newcred, *oldcred;
 	struct auditinfo ai;
 	int error;
 
 	if (jailed(td->td_ucred))
 		return (ENOSYS);
-	error = priv_check(td, PRIV_AUDIT_SETAUDIT);
-	if (error)
-		return (error);
-
 	error = copyin(uap->auditinfo, &ai, sizeof(ai));
 	if (error)
 		return (error);
-
 	audit_arg_auditinfo(&ai);
-
+	newcred = crget();
+	PROC_LOCK(td->td_proc);
+	oldcred = td->td_proc->p_ucred;
+	crcopy(newcred, oldcred);
 #ifdef MAC
-	error = mac_check_proc_setaudit(td->td_ucred, &ai);
+	error = mac_check_proc_setaudit(oldcred, &ai);
 	if (error)
-		return (error);
+		goto fail;
 #endif
-
-	/*
-	 * XXXRW: Test privilege while holding the proc lock?
-	*/
-	PROC_LOCK(td->td_proc);
-	bzero(td->td_proc->p_au, sizeof(struct auditinfo_addr));
-	td->td_proc->p_au->ai_auid = ai.ai_auid;
-	td->td_proc->p_au->ai_mask = ai.ai_mask;
-	td->td_proc->p_au->ai_asid = ai.ai_asid;
-	td->td_proc->p_au->ai_termid.at_addr[0] = ai.ai_termid.machine;
-	td->td_proc->p_au->ai_termid.at_port = ai.ai_termid.port;
-	td->td_proc->p_au->ai_termid.at_type = AU_IPv4;
+	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
+	if (error)
+		goto fail;
+	bzero(&newcred->cr_audit, sizeof(newcred->cr_audit));
+	newcred->cr_audit.ai_auid = ai.ai_auid;
+	newcred->cr_audit.ai_mask = ai.ai_mask;
+	newcred->cr_audit.ai_asid = ai.ai_asid;
+	newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
+	newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
+	newcred->cr_audit.ai_termid.at_type = AU_IPv4;
+	td->td_proc->p_ucred = newcred;
 	PROC_UNLOCK(td->td_proc);
-
+	crfree(oldcred);
 	return (0);
+fail:
+	PROC_UNLOCK(td->td_proc);
+	crfree(newcred);
+	return (error);
 }
 
 /* ARGSUSED */
 int
 getaudit_addr(struct thread *td, struct getaudit_addr_args *uap)
 {
-	struct auditinfo_addr aia;
 	int error;
 
 	if (jailed(td->td_ucred))
 		return (ENOSYS);
+	if (uap->length < sizeof(*uap->auditinfo_addr))
+		return (EOVERFLOW);
 	error = priv_check(td, PRIV_AUDIT_GETAUDIT);
 	if (error)
 		return (error);
-	if (uap->length < sizeof(aia))
-		return (EOVERFLOW);
-	PROC_LOCK(td->td_proc);
-	aia = *td->td_proc->p_au;
-	PROC_UNLOCK(td->td_proc);
-	return (copyout(&aia, uap->auditinfo_addr, sizeof(aia)));
+	return (copyout(&td->td_ucred->cr_audit, uap->auditinfo_addr,
+	    sizeof(*uap->auditinfo_addr)));
 }
 
 /* ARGSUSED */
 int
 setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
 {
+	struct ucred *newcred, *oldcred;
 	struct auditinfo_addr aia;
 	int error;
 
 	if (jailed(td->td_ucred))
 		return (ENOSYS);
-	error = priv_check(td, PRIV_AUDIT_SETAUDIT);
+	error = copyin(uap->auditinfo_addr, &aia, sizeof(aia));
 	if (error)
 		return (error);
-
+	/* XXXRW: Audit argument. */
+	newcred = crget();
+	PROC_LOCK(td->td_proc);	
+	oldcred = td->td_proc->p_ucred;
+	crcopy(newcred, oldcred);
 #ifdef MAC
-	error = mac_check_proc_setaudit(td->td_ucred, NULL);
+	error = mac_check_proc_setaudit(oldcred, NULL);
 	if (error)
-		return (error);
+		goto fail;
 #endif
-	error = copyin(uap->auditinfo_addr, &aia, sizeof(aia));
+	error = priv_check_cred(oldcred, PRIV_AUDIT_SETAUDIT, 0);
 	if (error)
-		return (error);
-	PROC_LOCK(td->td_proc);
-	*td->td_proc->p_au = aia;
+		goto fail;
+	newcred->cr_audit = aia;
+	td->td_proc->p_ucred = newcred;
 	PROC_UNLOCK(td->td_proc);
+	crfree(oldcred);
+	return (0);
+fail:
+	crfree(newcred);
 	return (error);
 }
 
--- sys/sys/proc.h	2007/05/28 12:57:17
+++ sys/sys/proc.h	2007/05/29 15:12:54
@@ -150,7 +150,6 @@
  * either lock is sufficient for read access, but both locks must be held
  * for write access.
  */
-struct auditinfo;
 struct kaudit_record;
 struct td_sched;
 struct nlminfo;
@@ -580,7 +579,6 @@
 	struct p_sched	*p_sched;	/* (*) Scheduler-specific data. */
 	STAILQ_HEAD(, ktr_request)	p_ktr;	/* (o) KTR event queue. */
 	LIST_HEAD(, mqueue_notifier)	p_mqnotifier; /* (c) mqueue notifiers.*/
-	struct auditinfo_addr	*p_au;	/* (c) Process audit properties. */
 };
 
 #define	p_session	p_pgrp->pg_session
--- sys/sys/ucred.h	2007/04/08 13:38:53
+++ sys/sys/ucred.h	2007/05/29 14:28:56
@@ -33,6 +33,8 @@
 #ifndef _SYS_UCRED_H_
 #define	_SYS_UCRED_H_
 
+#include <bsm/audit.h>
+
 /*
  * Credentials.
  *
@@ -55,6 +57,7 @@
 	struct prison	*cr_prison;	/* jail(2) */
 #define	cr_endcopy	cr_label
 	struct label	*cr_label;	/* MAC label */
+	struct auditinfo_addr	cr_audit;	/* Audit properties. */
 };
 #define	NOCRED	((struct ucred *)0)	/* no credential available */
 #define	FSCRED	((struct ucred *)-1)	/* filesystem credential */
