? sys/i386/conf/DEBUG
Index: sys/compat/linprocfs/linprocfs_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linprocfs/linprocfs_misc.c,v
retrieving revision 1.19
diff -u -r1.19 linprocfs_misc.c
--- sys/compat/linprocfs/linprocfs_misc.c	2001/02/09 06:08:24	1.19
+++ sys/compat/linprocfs/linprocfs_misc.c	2001/02/17 19:41:47
@@ -44,7 +44,6 @@
 #include <sys/param.h>
 #include <sys/blist.h>
 #include <sys/dkstat.h>
-#include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
@@ -52,6 +51,7 @@
 #include <sys/systm.h>
 #include <sys/tty.h>
 #include <sys/vnode.h>
+#include <sys/jail.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
Index: sys/compat/linux/linux_mib.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_mib.c,v
retrieving revision 1.9
diff -u -r1.9 linux_mib.c
--- sys/compat/linux/linux_mib.c	2001/02/16 16:40:41	1.9
+++ sys/compat/linux/linux_mib.c	2001/02/17 19:41:48
@@ -117,10 +117,11 @@
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	pr = p->p_prison;
-	if (pr == NULL)
+	if (!jailed(p->p_ucred))
 		return (NULL);
 
+	pr = p->p_ucred->cr_prison;
+
 	if (pr->pr_linux == NULL) {
 		MALLOC(lpr, struct linux_prison *, sizeof *lpr,
 		    M_PRISON, M_WAITOK|M_ZERO);
@@ -137,7 +138,7 @@
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	pr = p->p_prison;
+	pr = p->p_ucred->cr_prison;
 	if (pr != NULL && pr->pr_linux != NULL) {
 		lpr = pr->pr_linux;
 		if (lpr->pr_osname[0])
@@ -170,7 +171,7 @@
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	pr = p->p_prison;
+	pr = p->p_ucred->cr_prison;
 	if (pr != NULL && pr->pr_linux != NULL) {
 		lpr = pr->pr_linux;
 		if (lpr->pr_osrelease[0])
@@ -203,7 +204,7 @@
 	register struct prison *pr;
 	register struct linux_prison *lpr;
 
-	pr = p->p_prison;
+	pr = p->p_ucred->cr_prison;
 	if (pr != NULL && pr->pr_linux != NULL) {
 		lpr = pr->pr_linux;
 		if (lpr->pr_oss_version)
Index: sys/compat/svr4/svr4_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.24
diff -u -r1.24 svr4_misc.c
--- sys/compat/svr4/svr4_misc.c	2001/02/09 06:08:30	1.24
+++ sys/compat/svr4/svr4_misc.c	2001/02/17 19:41:49
@@ -1299,15 +1299,6 @@
 				q->p_cred = NULL;
 			}
 
-	                /*
-			 * Destroy empty prisons
-			 */
-			if (q->p_prison && !--q->p_prison->pr_ref) {
-				if (q->p_prison->pr_linux != NULL)
-					FREE(q->p_prison->pr_linux, M_PRISON);
-				FREE(q->p_prison, M_PRISON);
-			}
-
 			/*
 			 * Remove unused arguments
 			 */
Index: sys/kern/init_main.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.156
diff -u -r1.156 init_main.c
--- sys/kern/init_main.c	2001/02/12 00:20:05	1.156
+++ sys/kern/init_main.c	2001/02/17 19:41:57
@@ -324,9 +324,7 @@
 	p->p_ucred = crget();
 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
 	p->p_ucred->cr_uidinfo = uifind(0);
-
-	/* Don't jail it */
-	p->p_prison = 0;
+	p->p_ucred->cr_prison = NULL;	/* Don't jail it. */
 
 	/* Create procsig. */
 	p->p_procsig = &procsig0;
Index: sys/kern/kern_exit.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.117
diff -u -r1.117 kern_exit.c
--- sys/kern/kern_exit.c	2001/02/09 20:51:11	1.117
+++ sys/kern/kern_exit.c	2001/02/17 19:41:58
@@ -528,15 +528,6 @@
 			}
 
 			/*
-			 * Destroy empty prisons
-			 */
-			if (p->p_prison && !--p->p_prison->pr_ref) {
-				if (p->p_prison->pr_linux != NULL)
-					FREE(p->p_prison->pr_linux, M_PRISON);
-				FREE(p->p_prison, M_PRISON);
-			}
-
-			/*
 			 * Remove unused arguments
 			 */
 			if (p->p_args && --p->p_args->ar_ref == 0)
Index: sys/kern/kern_fork.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.98
diff -u -r1.98 kern_fork.c
--- sys/kern/kern_fork.c	2001/02/12 17:59:01	1.98
+++ sys/kern/kern_fork.c	2001/02/17 19:41:58
@@ -394,11 +394,6 @@
 	crhold(p1->p_ucred);
 	uihold(p1->p_cred->p_uidinfo);
 
-	if (p2->p_prison) {
-		p2->p_prison->pr_ref++;
-		p2->p_flag |= P_JAILED;
-	}
-
 	if (p2->p_args)
 		p2->p_args->ar_ref++;
 
Index: sys/kern/kern_jail.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_jail.c,v
retrieving revision 1.9
diff -u -r1.9 kern_jail.c
--- sys/kern/kern_jail.c	2000/12/08 21:50:32	1.9
+++ sys/kern/kern_jail.c	2001/02/17 19:41:58
@@ -46,16 +46,17 @@
 
 int
 jail(p, uap)
-        struct proc *p;
-        struct jail_args /* {
-                syscallarg(struct jail *) jail;
-        } */ *uap;
+	struct proc *p;
+	struct jail_args /* {
+		syscallarg(struct jail *) jail;
+	} */ *uap;
 {
 	int error;
 	struct prison *pr;
 	struct jail j;
 	struct chroot_args ca;
 
+	/* Implicitly fail if already in jail.  */
 	error = suser(p);
 	if (error)
 		return (error);
@@ -75,9 +76,9 @@
 	if (error)
 		goto bail;
 
-	pr->pr_ref++;
-	p->p_prison = pr;
-	p->p_flag |= P_JAILED;
+	p->p_ucred = crcopy(p->p_ucred);
+	p->p_ucred->cr_prison = pr;
+	pr->pr_ref = 1;
 	return (0);
 
 bail:
@@ -85,12 +86,33 @@
 	return (error);
 }
 
+void
+prison_free(struct prison *pr)
+{
+
+	pr->pr_ref--;
+	if (pr->pr_ref == 0) {
+		if (pr->pr_linux != NULL)
+			FREE(pr->pr_linux, M_PRISON);
+		FREE(pr, M_PRISON);
+	}
+	/* XXX */
+}
+
+void
+prison_hold(struct prison *pr)
+{
+
+	pr->pr_ref++;
+	/* XXX */
+}
+
 int
-prison_ip(struct proc *p, int flag, u_int32_t *ip)
+prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
 {
 	u_int32_t tmp;
 
-	if (!p->p_prison)
+	if (!jailed(cred))
 		return (0);
 	if (flag) 
 		tmp = *ip;
@@ -98,22 +120,22 @@
 		tmp = ntohl(*ip);
 	if (tmp == INADDR_ANY) {
 		if (flag) 
-			*ip = p->p_prison->pr_ip;
+			*ip = cred->cr_prison->pr_ip;
 		else
-			*ip = htonl(p->p_prison->pr_ip);
+			*ip = htonl(cred->cr_prison->pr_ip);
 		return (0);
 	}
-	if (p->p_prison->pr_ip != tmp)
+	if (cred->cr_prison->pr_ip != tmp)
 		return (1);
 	return (0);
 }
 
 void
-prison_remote_ip(struct proc *p, int flag, u_int32_t *ip)
+prison_remote_ip(struct ucred *cred, int flag, u_int32_t *ip)
 {
 	u_int32_t tmp;
 
-	if (!p || !p->p_prison)
+	if (!jailed(cred))
 		return;
 	if (flag)
 		tmp = *ip;
@@ -121,16 +143,16 @@
 		tmp = ntohl(*ip);
 	if (tmp == 0x7f000001) {
 		if (flag)
-			*ip = p->p_prison->pr_ip;
+			*ip = cred->cr_prison->pr_ip;
 		else
-			*ip = htonl(p->p_prison->pr_ip);
+			*ip = htonl(cred->cr_prison->pr_ip);
 		return;
 	}
 	return;
 }
 
 int
-prison_if(struct proc *p, struct sockaddr *sa)
+prison_if(struct ucred *cred, struct sockaddr *sa)
 {
 	struct sockaddr_in *sai = (struct sockaddr_in*) sa;
 	int ok;
@@ -139,9 +161,38 @@
 		ok = 1;
 	else if (sai->sin_family != AF_INET)
 		ok = 0;
-	else if (p->p_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
+	else if (cred->cr_prison->pr_ip != ntohl(sai->sin_addr.s_addr))
 		ok = 1;
 	else
 		ok = 0;
 	return (ok);
+}
+
+/*
+ * Return 0 if jails permit p1 to frob p2, otherwise ESRCH.
+ */
+int
+prison_check(cred1, cred2)
+	struct ucred *cred1, *cred2;
+{
+
+	if (jailed(cred1)) {
+		if (!jailed(cred2))
+			return (ESRCH);
+		if (cred2->cr_prison != cred1->cr_prison)
+			return (ESRCH);
+	}
+
+	return (0);
+}
+
+/*
+ * Return 1 if the passed credential is in a jail, otherwise 0.
+ */
+int
+jailed(cred)
+	struct ucred *cred;
+{
+
+	return (cred->cr_prison != NULL);
 }
Index: sys/kern/kern_ktrace.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.48
diff -u -r1.48 kern_ktrace.c
--- sys/kern/kern_ktrace.c	2001/01/08 07:22:06	1.48
+++ sys/kern/kern_ktrace.c	2001/02/17 19:41:59
@@ -48,6 +48,7 @@
 #include <sys/ktrace.h>
 #include <sys/malloc.h>
 #include <sys/syslog.h>
+#include <sys/jail.h>
 
 static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE");
 
@@ -519,6 +520,7 @@
  * so, only root may further change it.
  *
  * XXX: These checks are stronger than for ptrace()
+ * XXX: This check should be p_can(... P_CAN_DEBUG ...);
  *
  * TODO: check groups.  use caller effective gid.
  */
@@ -529,7 +531,7 @@
 	register struct pcred *caller = callp->p_cred;
 	register struct pcred *target = targetp->p_cred;
 
-	if (!PRISON_CHECK(callp, targetp))
+	if (prison_check(callp->p_ucred, targetp->p_ucred))
 		return (0);
 	if ((caller->pc_ucred->cr_uid == target->p_ruid &&
 	     target->p_ruid == target->p_svuid &&
Index: sys/kern/kern_mib.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_mib.c,v
retrieving revision 1.38
diff -u -r1.38 kern_mib.c
--- sys/kern/kern_mib.c	2001/02/12 00:20:06	1.38
+++ sys/kern/kern_mib.c	2001/02/17 19:41:59
@@ -146,12 +146,12 @@
 {
 	int error;
 
-	if (req->p->p_prison) {
+	if (jailed(req->p->p_ucred)) {
 		if (!jail_set_hostname_allowed && req->newptr)
 			return(EPERM);
 		error = sysctl_handle_string(oidp, 
-		    req->p->p_prison->pr_host,
-		    sizeof req->p->p_prison->pr_host, req);
+		    req->p->p_ucred->cr_prison->pr_host,
+		    sizeof req->p->p_ucred->cr_prison->pr_host, req);
 	} else
 		error = sysctl_handle_string(oidp, 
 		    hostname, sizeof hostname, req);
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.86
diff -u -r1.86 kern_proc.c
--- sys/kern/kern_proc.c	2001/02/12 00:20:06	1.86
+++ sys/kern/kern_proc.c	2001/02/17 19:42:00
@@ -49,6 +49,7 @@
 #include <vm/vm_map.h>
 #include <sys/user.h>
 #include <vm/vm_zone.h>
+#include <sys/jail.h>
 
 static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
 MALLOC_DEFINE(M_SESSION, "session", "session header");
@@ -478,6 +479,9 @@
 	kp->ki_xstat = p->p_xstat;
 	kp->ki_acflag = p->p_acflag;
 	kp->ki_flag = p->p_flag;
+	/* If jailed(p->p_ucred), emulate the old P_JAILED flag. */
+	if (jailed(p->p_ucred))
+		kp->ki_flag |= P_JAILED;
 	kp->ki_lock = p->p_lock;
 	PROC_UNLOCK(p);
 	PROCTREE_LOCK(PT_SHARED);
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v
retrieving revision 1.74
diff -u -r1.74 kern_prot.c
--- sys/kern/kern_prot.c	2001/02/14 06:53:57	1.74
+++ sys/kern/kern_prot.c	2001/02/17 19:42:00
@@ -56,6 +56,7 @@
 #include <sys/pioctl.h>
 #include <sys/resourcevar.h>
 #include <sys/sysctl.h>
+#include <sys/jail.h>
 
 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
 
@@ -941,15 +942,15 @@
  */
 int
 suser(p)
-	const struct proc *p;
+	struct proc *p;
 {
 	return suser_xxx(0, p, 0);
 }
 
 int
 suser_xxx(cred, proc, flag)
-	const struct ucred *cred;
-	const struct proc *proc;
+	struct ucred *cred;
+	struct proc *proc;
 	int flag;
 {
 	if (!suser_permitted)
@@ -962,20 +963,21 @@
 		cred = proc->p_ucred;
 	if (cred->cr_uid != 0) 
 		return (EPERM);
-	if (proc && proc->p_prison && !(flag & PRISON_ROOT))
+	if (jailed(cred) && !(flag & PRISON_ROOT))
 		return (EPERM);
 	return (0);
 }
 
 static int
-p_cansee(const struct proc *p1, const struct proc *p2, int *privused)
+p_cansee(struct proc *p1, struct proc *p2, int *privused)
 {
+	int error;
 
 	if (privused != NULL)
 		*privused = 0;
 
-	if (!PRISON_CHECK(p1, p2))
-		return (ESRCH);
+	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
+		return (error);
 
 	if (!ps_showallprocs && p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) {
 		if (suser_xxx(NULL, p1, PRISON_ROOT) == 0) {
@@ -990,8 +992,9 @@
 }
 
 static int
-p_cankill(const struct proc *p1, const struct proc *p2, int *privused)
+p_cankill(struct proc *p1, struct proc *p2, int *privused)
 {
+	int error;
 
 	if (privused != NULL)
 		*privused = 0;
@@ -999,8 +1002,8 @@
 	if (p1 == p2)
 		return (0);
 
-	if (!PRISON_CHECK(p1, p2))
-		return (ESRCH);
+	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
+		return (error);
 
 	if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
 		return (0);
@@ -1033,8 +1036,9 @@
 }
 
 static int
-p_cansched(const struct proc *p1, const struct proc *p2, int *privused)
+p_cansched(struct proc *p1, struct proc *p2, int *privused)
 {
+	int error;
 
 	if (privused != NULL)
 		*privused = 0;
@@ -1042,8 +1046,8 @@
 	if (p1 == p2)
 		return (0);
 
-	if (!PRISON_CHECK(p1, p2))
-		return (ESRCH);
+	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
+		return (error);
 
 	if (p1->p_cred->p_ruid == p2->p_cred->p_ruid)
 		return (0);
@@ -1076,9 +1080,9 @@
 }
 
 static int
-p_candebug(const struct proc *p1, const struct proc *p2, int *privused)
+p_candebug(struct proc *p1, struct proc *p2, int *privused)
 {
-	int	error;
+	int error;
 
 	if (privused != NULL)
 		*privused = 0;
@@ -1087,8 +1091,8 @@
 	if (p1 == p2)
 		return (0);
 
-	if (!PRISON_CHECK(p1, p2))
-		return (ESRCH);
+	if ((error = prison_check(p1->p_ucred, p2->p_ucred)))
+		return (error);
 
 	/* not owned by you, has done setuid (unless you're root) */
 	/* add a CAP_SYS_PTRACE here? */
@@ -1110,7 +1114,7 @@
 }
 
 int
-p_can(const struct proc *p1, const struct proc *p2, int operation,
+p_can(struct proc *p1, struct proc *p2, int operation,
     int *privused)
 {
 
@@ -1180,6 +1184,11 @@
 		 */
 		if (cr->cr_uidinfo != NULL)
 			uifree(cr->cr_uidinfo);
+		/*
+		 * Free a prison, if any.
+		 */
+		if (jailed(cr))
+			prison_free(cr->cr_prison);
 		FREE((caddr_t)cr, M_CRED);
 	} else {
 		mtx_unlock(&cr->cr_mtx);
@@ -1219,6 +1228,8 @@
 	*newcr = *cr;
 	mtx_init(&newcr->cr_mtx, "ucred", MTX_DEF);
 	uihold(newcr->cr_uidinfo);
+	if (jailed(newcr))
+		prison_hold(newcr->cr_prison);
 	newcr->cr_ref = 1;
 	return (newcr);
 }
Index: sys/kern/sysv_msg.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_msg.c,v
retrieving revision 1.29
diff -u -r1.29 sysv_msg.c
--- sys/kern/sysv_msg.c	2001/01/14 18:04:30	1.29
+++ sys/kern/sysv_msg.c	2001/02/17 19:42:01
@@ -278,7 +278,7 @@
 	} */ *uap;
 {
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	if (uap->which >= sizeof(msgcalls)/sizeof(msgcalls[0]))
@@ -334,7 +334,7 @@
 	printf("call to msgctl(%d, %d, 0x%x)\n", msqid, cmd, user_msqptr);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	msqid = IPCID_TO_IX(msqid);
@@ -473,7 +473,7 @@
 	printf("msgget(0x%x, 0%o)\n", key, msgflg);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	if (key != IPC_PRIVATE) {
@@ -588,7 +588,7 @@
 	    msgflg);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	msqid = IPCID_TO_IX(msqid);
@@ -915,7 +915,7 @@
 	    msgsz, msgtyp, msgflg);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	msqid = IPCID_TO_IX(msqid);
Index: sys/kern/sysv_sem.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_sem.c,v
retrieving revision 1.31
diff -u -r1.31 sysv_sem.c
--- sys/kern/sysv_sem.c	2001/01/14 18:04:30	1.31
+++ sys/kern/sysv_sem.c	2001/02/17 19:42:02
@@ -255,7 +255,7 @@
 	} */ *uap;
 {
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	if (uap->which >= sizeof(semcalls)/sizeof(semcalls[0]))
@@ -464,7 +464,7 @@
 	printf("call to semctl(%d, %d, %d, 0x%x)\n", semid, semnum, cmd, arg);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	semid = IPCID_TO_IX(semid);
@@ -627,7 +627,7 @@
 	printf("semget(0x%x, %d, 0%o)\n", key, nsems, semflg);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	if (key != IPC_PRIVATE) {
@@ -748,7 +748,7 @@
 	printf("call to semop(%d, 0x%x, %d)\n", semid, sops, nsops);
 #endif
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	semid = IPCID_TO_IX(semid);	/* Convert back to zero origin */
Index: sys/kern/sysv_shm.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_shm.c,v
retrieving revision 1.52
diff -u -r1.52 sysv_shm.c
--- sys/kern/sysv_shm.c	2001/02/04 20:10:32	1.52
+++ sys/kern/sysv_shm.c	2001/02/17 19:42:02
@@ -229,7 +229,7 @@
 	struct shmmap_state *shmmap_s;
 	int i;
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
@@ -266,7 +266,7 @@
 	vm_size_t size;
 	int rv;
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	shmmap_s = (struct shmmap_state *)p->p_vmspace->vm_shm;
@@ -360,7 +360,7 @@
 	struct shmid_ds *shmseg;
 	struct oshmid_ds outbuf;
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	shmseg = shm_find_segment_by_shmid(uap->shmid);
@@ -411,7 +411,7 @@
 	struct shmid_ds inbuf;
 	struct shmid_ds *shmseg;
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	shmseg = shm_find_segment_by_shmid(uap->shmid);
@@ -590,7 +590,7 @@
 {
 	int segnum, mode, error;
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	mode = uap->shmflg & ACCESSPERMS;
@@ -621,7 +621,7 @@
 	} */ *uap;
 {
 
-	if (!jail_sysvipc_allowed && p->p_prison != NULL)
+	if (!jail_sysvipc_allowed && jailed(p->p_ucred))
 		return (ENOSYS);
 
 	if (uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
Index: sys/kern/tty_pty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.83
diff -u -r1.83 tty_pty.c
--- sys/kern/tty_pty.c	2001/02/15 16:34:07	1.83
+++ sys/kern/tty_pty.c	2001/02/17 19:42:03
@@ -187,7 +187,7 @@
 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
 	} else if (tp->t_state & TS_XCLUDE && suser(p)) {
 		return (EBUSY);
-	} else if (pti->pt_prison != p->p_prison) {
+	} else if (pti->pt_prison != p->p_ucred->cr_prison) {
 		return (EBUSY);
 	}
 	if (tp->t_oproc)			/* Ctrlr still around. */
@@ -348,7 +348,7 @@
 	(void)(*linesw[tp->t_line].l_modem)(tp, 1);
 	tp->t_lflag &= ~EXTPROC;
 	pti = dev->si_drv1;
-	pti->pt_prison = p->p_prison;
+	pti->pt_prison = p->p_ucred->cr_prison;
 	pti->pt_flags = 0;
 	pti->pt_send = 0;
 	pti->pt_ucntl = 0;
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.89
diff -u -r1.89 uipc_socket.c
--- sys/kern/uipc_socket.c	2001/02/15 16:34:07	1.89
+++ sys/kern/uipc_socket.c	2001/02/17 19:42:04
@@ -141,7 +141,7 @@
 	if (prp == 0 || prp->pr_usrreqs->pru_attach == 0)
 		return (EPROTONOSUPPORT);
 
-	if (p->p_prison && jail_socket_unixiproute_only &&
+	if (jailed(p->p_ucred) && jail_socket_unixiproute_only &&
 	    prp->pr_domain->dom_family != PF_LOCAL &&
 	    prp->pr_domain->dom_family != PF_INET &&
 	    prp->pr_domain->dom_family != PF_ROUTE) {
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.62
diff -u -r1.62 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c	2000/12/21 21:43:24	1.62
+++ sys/kern/uipc_usrreq.c	2001/02/17 19:42:05
@@ -54,6 +54,7 @@
 #include <sys/un.h>
 #include <sys/unpcb.h>
 #include <sys/vnode.h>
+#include <sys/jail.h>
 
 #include <vm/vm_zone.h>
 
@@ -725,7 +726,7 @@
 static int
 prison_unpcb(struct proc *p, struct unpcb *unp)
 {
-	if (!p->p_prison)
+	if (!jailed(p->p_ucred))
 		return (0);
 	if (p->p_fd->fd_rdir == unp->unp_rvnode)
 		return (0);
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.177
diff -u -r1.177 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	2001/02/16 14:31:49	1.177
+++ sys/kern/vfs_syscalls.c	2001/02/17 19:42:07
@@ -64,6 +64,7 @@
 #include <sys/proc.h>
 #include <sys/dirent.h>
 #include <sys/extattr.h>
+#include <sys/jail.h>
 
 #include <machine/limits.h>
 #include <miscfs/union/union.h>
@@ -610,7 +611,7 @@
 	int error;
 	struct nameidata nd;
 
-	if (p->p_prison && !prison_quotas)
+	if (jailed(p->p_ucred) && !prison_quotas)
 		return (EPERM);
 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
 	if ((error = namei(&nd)) != 0)
Index: sys/miscfs/procfs/procfs_status.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_status.c,v
retrieving revision 1.26
diff -u -r1.26 procfs_status.c
--- sys/miscfs/procfs/procfs_status.c	2001/02/09 06:10:06	1.26
+++ sys/miscfs/procfs/procfs_status.c	2001/02/17 19:42:08
@@ -163,9 +163,9 @@
 		DOCHECK();
 	}
 
-	if (p->p_prison)
+	if (jailed(p->p_ucred))
 		ps += snprintf(ps, psbuf + sizeof(psbuf) - ps,
-		    " %s", p->p_prison->pr_host);
+		    " %s", p->p_ucred->cr_prison->pr_host);
 	else
 		ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " -");
 	DOCHECK();
Index: sys/net/bpf.c
===================================================================
RCS file: /home/ncvs/src/sys/net/bpf.c,v
retrieving revision 1.76
diff -u -r1.76 bpf.c
--- sys/net/bpf.c	2001/02/16 17:10:28	1.76
+++ sys/net/bpf.c	2001/02/17 19:42:14
@@ -322,9 +322,6 @@
 {
 	struct bpf_d *d;
 
-	if (p->p_prison)
-		return (EPERM);
-
 	mtx_lock(&bpf_mtx);
 	d = dev->si_drv1;
 	/*
Index: sys/net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.102
diff -u -r1.102 if.c
--- sys/net/if.c	2001/02/06 10:11:36	1.102
+++ sys/net/if.c	2001/02/17 19:42:15
@@ -50,6 +50,7 @@
 #include <sys/sockio.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
+#include <sys/jail.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -1080,7 +1081,8 @@
 		for ( ; space > sizeof (ifr) && ifa;
 		    ifa = TAILQ_NEXT(ifa, ifa_link)) {
 			register struct sockaddr *sa = ifa->ifa_addr;
-			if (curproc->p_prison && prison_if(curproc, sa))
+			if (jailed(curproc->p_ucred) &&
+			    prison_if(curproc->p_ucred, sa))
 				continue;
 			addrs++;
 #ifdef COMPAT_43
Index: sys/net/if.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if.h,v
retrieving revision 1.60
diff -u -r1.60 if.h
--- sys/net/if.h	2001/02/06 12:05:28	1.60
+++ sys/net/if.h	2001/02/17 19:42:15
@@ -265,8 +265,6 @@
 #ifdef _KERNEL
 struct proc;
 
-int	prison_if __P((struct proc *p, struct sockaddr *sa));
-
 /* XXX - this should go away soon. */
 #include <net/if_var.h>
 #endif
Index: sys/net/rtsock.c
===================================================================
RCS file: /home/ncvs/src/sys/net/rtsock.c,v
retrieving revision 1.50
diff -u -r1.50 rtsock.c
--- sys/net/rtsock.c	2001/02/04 13:12:57	1.50
+++ sys/net/rtsock.c	2001/02/17 19:42:16
@@ -46,6 +46,7 @@
 #include <sys/socketvar.h>
 #include <sys/domain.h>
 #include <sys/protosw.h>
+#include <sys/jail.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -915,7 +916,8 @@
 		while ((ifa = TAILQ_NEXT(ifa, ifa_link)) != 0) {
 			if (af && af != ifa->ifa_addr->sa_family)
 				continue;
-			if (curproc->p_prison && prison_if(curproc, ifa->ifa_addr))
+			if (jailed(curproc->p_ucred) &&
+			    prison_if(curproc->p_ucred, ifa->ifa_addr))
 				continue;
 			ifaaddr = ifa->ifa_addr;
 			netmask = ifa->ifa_netmask;
Index: sys/netinet/in.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.h,v
retrieving revision 1.52
diff -u -r1.52 in.h
--- sys/netinet/in.h	2001/02/14 13:51:20	1.52
+++ sys/netinet/in.h	2001/02/17 19:42:17
@@ -487,9 +487,6 @@
 char 	*inet_ntoa __P((struct in_addr)); /* in libkern */
 char	*inet_ntoa_r __P((struct in_addr ina, char *buf)); /* in libkern */
 
-int	prison_ip __P((struct proc *p, int flag, u_int32_t *ip));
-void	prison_remote_ip __P((struct proc *p, int flag, u_int32_t *ip));
-
 #endif
 
 #endif
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.75
diff -u -r1.75 in_pcb.c
--- sys/netinet/in_pcb.c	2001/02/04 16:08:12	1.75
+++ sys/netinet/in_pcb.c	2001/02/17 19:42:18
@@ -198,8 +198,13 @@
 		if (sin->sin_family != AF_INET)
 			return (EAFNOSUPPORT);
 #endif
+		/*
+		 * XXX: The following jail() related code uses the process
+		 * credential rather than the socket credential.  It should
+		 * probably use the socket credential.
+		 */
 		if (sin->sin_addr.s_addr != INADDR_ANY)
-			if (prison_ip(p, 0, &sin->sin_addr.s_addr))
+			if (prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr))
 				return(EINVAL);
 		lport = sin->sin_port;
 		if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
@@ -219,12 +224,17 @@
 		}
 		if (lport) {
 			struct inpcb *t;
-
+			/*
+			 * XXX: Some of the access checks below use
+			 * the calling process.  Others use the cached
+			 * socket credential.  The direct cr_uid checks
+			 * below should use suser_xxx().
+			 */
 			/* GROSS */
 			if (ntohs(lport) < IPPORT_RESERVED && p &&
 			    suser_xxx(0, p, PRISON_ROOT))
 				return (EACCES);
-			if (p && p->p_prison)
+			if (p && jailed(p->p_ucred))
 				prison = 1;
 			if (so->so_cred->cr_uid != 0 &&
 			    !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
@@ -273,8 +283,16 @@
 		ushort first, last;
 		int count;
 
+		/*
+		 * XXX: The following jail() related code uses the process
+		 * credential rather than the socket credential.  It should
+		 * probably use the socket credential.
+		 * XXX: Original jail() code dereferences (p) below in
+		 * prison_ip().  Is that OK, or should there be a check for
+		 * NULL (p).
+		 */
 		if (inp->inp_laddr.s_addr != INADDR_ANY)
-			if (prison_ip(p, 0, &inp->inp_laddr.s_addr ))
+			if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr ))
 				return (EINVAL);
 		inp->inp_flags |= INP_ANONPORT;
 
@@ -345,7 +363,12 @@
 		}
 	}
 	inp->inp_lport = lport;
-	if (prison_ip(p, 0, &inp->inp_laddr.s_addr))
+	/*
+	 * XXX: The following jail() related code uses the process
+	 * credential rather than the socket credential.  It should
+	 * probably use the socket credential.
+	 */
+	if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr))
 		return(EINVAL);
 	if (in_pcbinshash(inp) != 0) {
 		inp->inp_laddr.s_addr = INADDR_ANY;
@@ -492,11 +515,13 @@
 	struct sockaddr_in *ifaddr;
 	struct sockaddr_in *sin = (struct sockaddr_in *)nam;
 	struct sockaddr_in sa;
+	struct ucred *cred;
 	int error;
 
-	if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
+	cred = inp->inp_socket->so_cred;
+	if (inp->inp_laddr.s_addr == INADDR_ANY && jailed(cred)) {
 		bzero(&sa, sizeof (sa));
-		sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
+		sa.sin_addr.s_addr = htonl(cred->cr_prison->pr_ip);
 		sa.sin_len=sizeof (sa);
 		sa.sin_family = AF_INET;
 		error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
@@ -1070,9 +1095,9 @@
 int
 prison_xinpcb(struct proc *p, struct inpcb *inp)
 {
-	if (!p->p_prison)
+	if (!jailed(p->p_ucred))
 		return (0);
-	if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip)
+	if (ntohl(inp->inp_laddr.s_addr) == p->p_ucred->cr_prison->pr_ip)
 		return (0);
 	return (1);
 }
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.53
diff -u -r1.53 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c	2001/02/02 18:48:25	1.53
+++ sys/netinet/tcp_usrreq.c	2001/02/17 19:42:19
@@ -49,6 +49,8 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
+#include <sys/proc.h>
+#include <sys/jail.h>
 
 #include <net/if.h>
 #include <net/route.h>
@@ -328,7 +330,8 @@
 		goto out;
 	}
 
-	prison_remote_ip(p, 0, &sinp->sin_addr.s_addr);
+	if (p && jailed(p->p_ucred))
+		prison_remote_ip(p->p_ucred, 0, &sinp->sin_addr.s_addr);
 
 	if ((error = tcp_connect(tp, nam, p)) != 0)
 		goto out;
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.82
diff -u -r1.82 udp_usrreq.c
--- sys/netinet/udp_usrreq.c	2001/02/11 07:39:51	1.82
+++ sys/netinet/udp_usrreq.c	2001/02/17 19:42:19
@@ -49,6 +49,7 @@
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
+#include <sys/jail.h>
 
 #include <vm/vm_zone.h>
 
@@ -656,7 +657,13 @@
 
 	if (addr) {
 		sin = (struct sockaddr_in *)addr;
-		prison_remote_ip(p, 0, &sin->sin_addr.s_addr);
+		/*
+		 * XXX: The following jail() related code uses the process
+		 * credential rather than the socket credential.  It should
+		 * probably use the socket credential.
+		 */
+		if (p && jailed(p->p_ucred))
+			prison_remote_ip(p->p_ucred, 0, &sin->sin_addr.s_addr);
 		laddr = inp->inp_laddr;
 		if (inp->inp_faddr.s_addr != INADDR_ANY) {
 			error = EISCONN;
@@ -829,7 +836,13 @@
 		return EISCONN;
 	s = splnet();
 	sin = (struct sockaddr_in *)nam;
-	prison_remote_ip(p, 0, &sin->sin_addr.s_addr);
+	/*
+	 * XXX: The following jail() related code uses the process
+	 * credential rather than the socket credential.  It should
+	 * probably use the socket credential.
+	 */
+	if (p && jailed(p->p_ucred))
+		prison_remote_ip(p->p_ucred, 0, &sin->sin_addr.s_addr);
 	error = in_pcbconnect(inp, nam, p);
 	splx(s);
 	if (error == 0)
Index: sys/sys/capability.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/capability.h,v
retrieving revision 1.4
diff -u -r1.4 capability.h
--- sys/sys/capability.h	2000/10/13 17:12:58	1.4
+++ sys/sys/capability.h	2001/02/17 19:42:20
@@ -167,7 +167,7 @@
 struct proc;
 struct ucred;
 struct vnode;
-int	cap_check(const struct ucred *, const struct proc *, cap_value_t, int);
+int	cap_check(struct ucred *, struct proc *, cap_value_t, int);
 int	cap_change_on_inherit(struct cap *cap_p);
 int	cap_inherit(struct vnode *vp, struct proc *p);
 void	cap_init_proc0(struct cap *);
Index: sys/sys/jail.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/jail.h,v
retrieving revision 1.10
diff -u -r1.10 jail.h
--- sys/sys/jail.h	2000/10/31 01:34:00	1.10
+++ sys/sys/jail.h	2001/02/17 19:42:20
@@ -32,7 +32,7 @@
 
 /*
  * This structure describes a prison.  It is pointed to by all struct
- * proc's of the inmates.  pr_ref keeps track of them and is used to
+ * ucreds's of the inmates.  pr_ref keeps track of them and is used to
  * delete the struture when the last inmate is dead.
  */
 
@@ -49,6 +49,19 @@
 extern int	jail_set_hostname_allowed;
 extern int	jail_socket_unixiproute_only;
 extern int	jail_sysvipc_allowed;
+
+/*
+ * Kernel support functions for jail().
+ */
+struct ucred;
+struct sockaddr;
+int jailed __P((struct ucred *cred));
+int prison_check __P((struct ucred *cred1, struct ucred *cred2));
+void prison_free __P((struct prison *pr));
+void prison_hold __P((struct prison *pr));
+int prison_if __P((struct ucred *cred, struct sockaddr *sa));
+int prison_ip __P((struct ucred *cred, int flag, u_int32_t *ip));
+void prison_remote_ip __P((struct ucred *cred, int flags, u_int32_t *ip));
 
 #endif /* !_KERNEL */
 #endif /* !_SYS_JAIL_H_ */
Index: sys/sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.149
diff -u -r1.149 proc.h
--- sys/sys/proc.h	2001/02/12 00:20:07	1.149
+++ sys/sys/proc.h	2001/02/17 19:42:21
@@ -259,7 +259,6 @@
 
 	struct 	pgrp *p_pgrp;	/* (e?/c?) Pointer to process group. */
 	struct 	sysentvec *p_sysent; /* (b) System call dispatch information. */
-	struct	prison *p_prison;	/* (b?) jail(4). */
 	struct	pargs *p_args;		/* (b?) Process arguments. */
 
 /* End area that is copied on creation. */
@@ -534,7 +533,7 @@
 int	inferior __P((struct proc *p));
 int	leavepgrp __P((struct proc *p));
 void	mi_switch __P((void));
-int	p_can __P((const struct proc *p1, const struct proc *p2, int operation,
+int	p_can __P((struct proc *p1, struct proc *p2, int operation,
 	    int *privused));
 int	p_trespass __P((struct proc *p1, struct proc *p2));
 void	procinit __P((void));
Index: sys/sys/systm.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/systm.h,v
retrieving revision 1.134
diff -u -r1.134 systm.h
--- sys/sys/systm.h	2001/02/12 00:20:07	1.134
+++ sys/sys/systm.h	2001/02/17 19:42:21
@@ -161,9 +161,8 @@
 /* flags for suser_xxx() */
 #define PRISON_ROOT	1
 
-int	suser __P((const struct proc *));
-int	suser_xxx __P((const struct ucred *cred, const struct proc *proc,
-    int flag));
+int	suser __P((struct proc *));
+int	suser_xxx __P((struct ucred *cred, struct proc *proc, int flag));
 
 char	*getenv __P((char *name));
 int	getenv_int __P((char *name, int *data));
Index: sys/sys/ucred.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ucred.h,v
retrieving revision 1.19
diff -u -r1.19 ucred.h
--- sys/sys/ucred.h	2000/11/30 19:09:47	1.19
+++ sys/sys/ucred.h	2001/02/17 19:42:21
@@ -51,6 +51,7 @@
 	short	cr_ngroups;		/* number of groups */
 	gid_t	cr_groups[NGROUPS];	/* groups */
 	struct	uidinfo *cr_uidinfo;	/* per uid resource consumption */
+	struct	prison *cr_prison;	/* jail(4) */
 	struct	mtx cr_mtx;		/* protect refcount */
 };
 #define cr_gid cr_groups[0]
