Index: contrib/amd/include/am_defs.h
===================================================================
RCS file: /home/ncvs/src/contrib/amd/include/am_defs.h,v
retrieving revision 1.8
diff -u -r1.8 am_defs.h
--- contrib/amd/include/am_defs.h	1999/11/05 11:58:03	1.8
+++ contrib/amd/include/am_defs.h	2000/04/12 17:04:20
@@ -445,6 +445,7 @@
  * Actions to take if <sys/ucred.h> exists.
  */
 #ifdef HAVE_SYS_UCRED_H
+#include <sys/capability.h>
 # include <sys/ucred.h>
 #endif /* HAVE_SYS_UCRED_H */
 
Index: etc/rc
===================================================================
RCS file: /home/ncvs/src/etc/rc,v
retrieving revision 1.244
diff -u -r1.244 rc
--- etc/rc	2000/12/17 08:24:49	1.244
+++ etc/rc	2001/01/05 16:50:06
@@ -204,6 +204,19 @@
 		sh ${diskless_mount}
 fi
 
+case ${extattr_root} in
+[Nn][Oo] | '')
+	;;
+*)
+	echo Starting extended attributes on root file system.
+	/usr/sbin/extattrctl start /
+	cd /.attribute && for file in *
+	do
+		/usr/sbin/extattrctl enable / $file /.attribute/$file
+	done
+	;;
+esac
+
 # Second attempt at reseeding, if needed.
 #
 case ${entropy_reseeded} in
Index: etc/defaults/rc.conf
===================================================================
RCS file: /home/ncvs/src/etc/defaults/rc.conf,v
retrieving revision 1.83
diff -u -r1.83 rc.conf
--- etc/defaults/rc.conf	2000/10/29 19:59:04	1.83
+++ etc/defaults/rc.conf	2000/11/07 02:25:17
@@ -322,6 +322,7 @@
 update_motd="YES"	# update version info in /etc/motd (or NO)
 start_vinum=""		# set to YES to start vinum
 unaligned_print="YES"	# print unaligned access warnings on the alpha (or NO).
+extattr_root="NO"	# Auto-start extended attributes on / at boot
 entropy_file="/entropy" # Set to NO to disable caching entropy through reboots.
 			# /var/db/entropy is preferred if / is not available.
 
Index: lib/libc/gen/getmntinfo.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getmntinfo.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 getmntinfo.c
--- lib/libc/gen/getmntinfo.c	1994/05/27 04:56:40	1.1.1.1
+++ lib/libc/gen/getmntinfo.c	2000/01/09 07:19:44
@@ -36,6 +36,7 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/mount.h>
 #include <stdlib.h>
Index: lib/libposix1e/Makefile
===================================================================
RCS file: /home/ncvs/src/lib/libposix1e/Makefile,v
retrieving revision 1.9
diff -u -r1.9 Makefile
--- lib/libposix1e/Makefile	2000/10/13 18:24:58	1.9
+++ lib/libposix1e/Makefile	2000/10/23 06:45:16
@@ -1,5 +1,6 @@
 # $FreeBSD: src/lib/libposix1e/Makefile,v 1.9 2000/10/13 18:24:58 rwatson Exp $
 
+CFLAGS+=-g -Wall
 MAINTAINER=	rwatson@FreeBSD.org
 LIB=	posix1e
 SHLIB_MAJOR= 2 
Index: lib/libposix1e/cap.3
===================================================================
RCS file: /home/ncvs/src/lib/libposix1e/cap.3,v
retrieving revision 1.6
diff -u -r1.6 cap.3
--- lib/libposix1e/cap.3	2000/12/14 11:45:20	1.6
+++ lib/libposix1e/cap.3	2001/01/05 16:53:01
@@ -93,7 +93,7 @@
 (more) readable by humans.
 .El
 .Pp
-A number of capabilities exist, each mapping to the ability to violate
+A number of capabilities exist, each mapping to the ability to override
 a particular aspect of the system policy.
 Each capability in a capability set has three flags, indicating the
 status of the capability with respect to the file or process it is
Index: lib/libposix1e/cap_get_proc.3
===================================================================
RCS file: /home/ncvs/src/lib/libposix1e/cap_get_proc.3,v
retrieving revision 1.4
diff -u -r1.4 cap_get_proc.3
--- lib/libposix1e/cap_get_proc.3	2000/12/14 11:45:20	1.4
+++ lib/libposix1e/cap_get_proc.3	2001/01/05 16:53:02
@@ -95,7 +95,3 @@
 and development continues.
 .Sh AUTHORS
 .An Robert N M Watson
-.Sh BUGS
-While libposix1e is fully implemented, supporting kernel code is not
-yet available in the base distribution.
-It is slated for inclusion prior to 5.0-RELEASE.
Index: lib/libposix1e/cap_set_proc.3
===================================================================
RCS file: /home/ncvs/src/lib/libposix1e/cap_set_proc.3,v
retrieving revision 1.4
diff -u -r1.4 cap_set_proc.3
--- lib/libposix1e/cap_set_proc.3	2000/12/14 11:45:20	1.4
+++ lib/libposix1e/cap_set_proc.3	2001/01/05 16:53:02
@@ -102,7 +102,3 @@
 and development continues.
 .Sh AUTHORS
 .An Robert N M Watson
-.Sh BUGS
-While libposix1e is fully implemented, supporting kernel code is not
-yet available in the base distribution.
-It is slated for inclusion prior to 5.0-RELEASE.
Index: sys/coda/coda_namecache.c
===================================================================
RCS file: /home/ncvs/src/sys/coda/coda_namecache.c,v
retrieving revision 1.10
diff -u -r1.10 coda_namecache.c
--- sys/coda/coda_namecache.c	1999/08/28 00:40:53	1.10
+++ sys/coda/coda_namecache.c	2000/04/12 04:43:28
@@ -79,6 +79,7 @@
 #include <sys/param.h>
 #include <sys/errno.h>
 #include <sys/malloc.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/select.h>
 
Index: sys/fs/hpfs/hpfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/hpfs/hpfs_vnops.c,v
retrieving revision 1.8
diff -u -r1.8 hpfs_vnops.c
--- sys/fs/hpfs/hpfs_vnops.c	2000/11/01 17:57:22	1.8
+++ sys/fs/hpfs/hpfs_vnops.c	2000/11/07 02:41:02
@@ -579,7 +579,7 @@
 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
 			return (EROFS);
 		if (cred->cr_uid != hp->h_uid &&
-		    (error = suser_xxx(cred, p, PRISON_ROOT)) &&
+		    (error = cap_check(cred, p, CAP_FOWNER, PRISON_ROOT)) &&
 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
 		    (error = VOP_ACCESS(vp, VWRITE, cred, p))))
 			return (error);
Index: sys/isa/fd.c
===================================================================
RCS file: /home/ncvs/src/sys/isa/fd.c,v
retrieving revision 1.192
diff -u -r1.192 fd.c
--- sys/isa/fd.c	2000/12/08 21:50:26	1.192
+++ sys/isa/fd.c	2000/12/13 05:37:16
@@ -2411,8 +2411,9 @@
 
 	case FD_STYPE:                  /* set drive type */
 		/* this is considered harmful; only allow for superuser */
-		if (suser(p) != 0)
-			return EPERM;
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return (error);
+		suser_used(p);
 		*fd->ft = *(struct fd_type *)addr;
 		break;
 
Index: sys/isofs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/isofs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.81
diff -u -r1.81 cd9660_vfsops.c
--- sys/isofs/cd9660/cd9660_vfsops.c	2000/12/08 21:50:31	1.81
+++ sys/isofs/cd9660/cd9660_vfsops.c	2000/12/13 05:37:18
@@ -223,13 +223,21 @@
 
 	/*       
 	 * Verify that user has necessary permissions on the device,
-	 * or has superuser abilities
+	 * or has superuser abilities.
+	 *
+	 * XXX: Capability check is to see if caller can override
+	 * permissions protecting the device.  Perhaps also should
+	 * be checks for the right to open devices?  Also, what about
+	 * securelevel?
 	 */
 	accessmode = VREAD;
 	vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
 	error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
-	if (error) 
-		error = suser(p);
+	if (error) {
+		error = cap_check(NULL, p, CAP_DAC_READ_SEARCH, 0);
+		if (error == 0)
+			suser_used(p);
+	}
 	if (error) {
 		vput(devvp);
 		return (error);
Index: sys/kern/init_main.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.151
diff -u -r1.151 init_main.c
--- sys/kern/init_main.c	2000/12/13 00:17:00	1.151
+++ sys/kern/init_main.c	2000/12/13 05:37:19
@@ -75,6 +75,7 @@
 #include <vm/vm_map.h>
 #include <sys/user.h>
 #include <sys/copyright.h>
+#include <sys/capability.h>
 
 extern struct linker_set	sysinit_set;	/* XXX */
 
@@ -322,6 +323,10 @@
 	p->p_cred = &cred0;
 	p->p_ucred = crget();
 	p->p_ucred->cr_ngroups = 1;	/* group 0 */
+
+	/* Give all kernel processes many capabilities */
+	cap_init_proc0(&p->p_ucred->cr_cap);
+
 	p->p_ucred->cr_uidinfo = uifind(0);
 
 	/* Don't jail it */
@@ -598,6 +603,12 @@
 		panic("cannot fork init: %d\n", error);
 	initproc->p_flag |= P_INMEM | P_SYSTEM;
 	cpu_set_fork_handler(initproc, start_init, NULL);
+
+	/*
+	 * Give init necessary capabilities to shut the system down and
+	 * avoid a panic when done.
+	 */
+	cap_init_proc1(&initproc->p_ucred->cr_cap);
 }
 SYSINIT(init,SI_SUB_CREATE_INIT, SI_ORDER_FIRST, create_init, NULL)
 
Index: sys/kern/kern_acct.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_acct.c,v
retrieving revision 1.27
diff -u -r1.27 kern_acct.c
--- sys/kern/kern_acct.c	2000/11/27 22:52:29	1.27
+++ sys/kern/kern_acct.c	2000/12/13 05:37:19
@@ -118,9 +118,9 @@
 	int error, flags;
 
 	/* Make sure that the caller is root. */
-	error = suser(p);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_PACCT, 0)) != 0)
 		return (error);
+	suser_used(p);
 
 	/*
 	 * If accounting is to be started to a file, open that file for
Index: sys/kern/kern_cap.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_cap.c,v
retrieving revision 1.5
diff -u -r1.5 kern_cap.c
--- sys/kern/kern_cap.c	2000/10/29 13:56:50	1.5
+++ sys/kern/kern_cap.c	2000/11/07 02:42:40
@@ -31,8 +31,6 @@
 /*
  * Developed by the TrustedBSD Project.
  * Support for POSIX.1e process capabilities.
- *
- * XXX: Currently just syscall stubs.
  */
 
 #include <sys/types.h>
@@ -50,14 +48,340 @@
 
 #include "opt_cap.h"
 
+static void	cap_zero(struct cap *cap_p);
+static int	cap_valid(struct cap *cap_p);
+static int	cap_subset(struct cap *cap1, struct cap *cap2);
+static int	cap_get_vp(struct vnode *vp, int ioflg, struct cap *cap_p,
+			struct proc *p);
+static int	cap_set_vp(struct vnode *vp, int ioflg, struct cap *cap_p,
+			struct proc *p);
+
+
+static int	kern_security_suser_enabled = 1;
+#ifdef CAPABILITIES
+static int	kern_security_capabilities_enabled = 1;
+#endif
+
+SYSCTL_NODE(_kern, OID_AUTO, security, CTLFLAG_RD, 0, "Kernel Security MIB");
+SYSCTL_INT(_kern_security, OID_AUTO, suser_permitted, CTLFLAG_RW,
+    &kern_security_suser_enabled, 0, "Super-user Enabled");
+#ifdef CAPABILITIES
+SYSCTL_INT(_kern_security, OID_AUTO, capabilities_enabled, CTLFLAG_RW,
+    &kern_security_capabilities_enabled, 0, "POSIX.1e Capabilities Enabled");
+#endif
+
+/*
+ * Return a capability set to a state where it has no flags enabled.
+ */
+static void
+cap_zero(struct cap *cap_p)
+{
+
+	bzero(cap_p, sizeof(*cap_p));
+}
+
+/*
+ * Check the validity of a capability set -- 0 on success, EINVAL otherwise
+ */
+static int
+cap_valid(struct cap *cap_p)
+{
+
+	/*
+	 * Effective cannot contain anything not in permitted.
+	 */
+	if ((cap_p->c_permitted | cap_p->c_effective) != cap_p->c_permitted)
+		return (EINVAL);
+	return (0);
+}
+
+/*
+ * Check whether cap2 is a strict subset of cap1, from the perspective
+ * of setting a new capability set for a process without appropriate
+ * privilege.
+ */
+static int
+cap_subset(struct cap *cap1, struct cap *cap2)
+{
+
+	/*
+	 * New permitted set must be a subset of the old permitted set.
+	 */
+	if ((cap2->c_permitted | cap1->c_permitted) !=
+	    cap1->c_permitted)
+		return (EPERM);
+
+	/*
+	 * New effective set must be a subset of the new permitted set.
+	 */
+	if ((cap2->c_effective | cap2->c_permitted) !=
+	    cap2->c_permitted)
+		return (EPERM);
+
+	/*
+	 * New inheritable set must be a subset of the old permitted set.
+	 */
+	if ((cap2->c_inheritable | cap1->c_permitted) !=
+	    cap1->c_permitted)
+		return (EPERM);
+	return (0);
+}
+
+/*
+ * cap_proc0: initialize capabilities for kernel processes
+ *
+ * XXX for now, give them all capabilities, as kernel processes may
+ * need to do all kinds of things.
+ */
+void
+cap_init_proc0(struct cap *cap_p)
+{
+
+	/* All available rights. */
+	cap_p->c_effective = ~0;
+	cap_p->c_permitted = ~0;
+	cap_p->c_inheritable = ~0;
+}
+
+/*
+ * cap_init: initialize capabilities for init
+ * 
+ * XXX init requires CAP_KILL in order to shut the system
+ * down successfully, as well as CAP_SYS_BOOT.
+ */
+void
+cap_init_proc1(struct cap *cap_p)
+{
+
+	bzero(cap_p, sizeof(struct cap));
+
+	/*
+	 * Give init(8) all rights, as it will need to pass them on
+	 * to startup processes during the system boot.  For safety,
+	 * default to non-inheritable for all of the capabilities,
+	 * allowing a legacy init(8) to operate safely on a
+	 * capabilities environment.
+	 *
+	 * XXX we may need to setsugid() init, so would require
+	 * a proc pointer, not just the cap pointer here.
+	 */
+	cap_p->c_effective = ~0;
+	cap_p->c_permitted = ~0;
+	cap_p->c_inheritable = 0;
+
+	/*
+	 * For reference, the following rights are the ones required for
+	 * normal system operation of init(8), leaving aside the
+	 * requirement that programs executed by init(8) might require
+	 * privilege.
+	 *
+	 * cap_p->c_effective = cap_p->c_permitted = cap_p->c_inheritable = 0;
+	 * SET_CAPABILITY(cap_p->c_permitted, CAP_KILL);
+	 * SET_CAPABILITY(cap_p->c_effective, CAP_KILL);
+	 * SET_CAPABILITY(cap_p->c_permitted, CAP_SYS_BOOT);
+	 * SET_CAPABILITY(cap_p->c_effective, CAP_SYS_BOOT);
+	 */
+}
+
 /*
+ * Perform capability inheritence on p, with optional vnode for a file
+ * from which to gain/mask new capabilities.  To not use a vnode, set
+ * vp to NULL.
+ *
+ * POSIX.1e defines the following inheritence:
+ *   pI` = pI
+ *   pP` = (fP & X) | (fI & pI)
+ *   pE` = (fE & pP`)
+ *
+ * We currently don't implement X, but will soon implement a per-process
+ * inherited bounding set to support jail().
+ * Linux currently uses: X = fB & (~pB) where fB is a per-fs bound, and
+ * pB is the inherited process bound.
+ *
+ * If capabilities have been disabled using the sysctl, new programs
+ * running are not permitted to acquire and capabilities regardless of
+ * their on-disk state, or inherited capabilities.
+ *
+ * If any capabilities are set on the process, i.e, requiring protection,
+ * then return (1), otherwise (0).  This allows the caller to determine
+ * what protection is appropriate.
+ */
+int
+cap_inherit(struct vnode *vp, struct proc *p)
+{
+	struct cap	cap_file;
+	struct cap	cap_new;
+	struct cap	*cap_p_proc;
+#ifdef CAPABILITIES
+	int	len;
+#endif
+	int	error;
+
+	/*
+	 * XXX have to do this, since we don't know if capabilities will
+	 * change.  This should be fixed to not crcopy if the capabilities
+	 * have not changed.
+	 */
+	p->p_ucred = crcopy(p->p_ucred);
+	cap_p_proc = &p->p_ucred->cr_cap;
+
+#ifdef CAPABILITIES
+	if (kern_security_capabilities_enabled == 1) {
+		len = sizeof(cap_file);
+		error =	cap_get_vp(vp, 0, &cap_file, p);
+		if (error) {
+			printf("cap_inherit: error retrieving capability\n");
+			printf("error: %d\n", error);
+		}
+	} else
+#endif
+		error = 1;	/* force zero'ing of capabilities */
+
+	if (error == 0) {
+		cap_new.c_inheritable = cap_p_proc->c_inheritable;
+		cap_new.c_permitted = cap_file.c_permitted |
+		    (cap_file.c_inheritable & cap_p_proc->c_inheritable);
+		cap_new.c_effective = cap_file.c_effective &
+		    cap_new.c_permitted;
+	} else {
+		cap_new.c_inheritable = 0;
+		cap_new.c_permitted = 0;
+		cap_new.c_effective = 0;
+	}
+	*cap_p_proc = cap_new;
+ 
+	/*
+	 * Currently, we protect a process only if some of its capability
+	 * bits end up being turned on.  Is this correct?
+	 */
+	if (cap_p_proc->c_permitted || cap_p_proc->c_effective)
+		return (1);
+	return (0);
+}
+
+/*
+ * cap_check: perform an authorization check to see if the given process
+ * appropriate privilege.  Flags model those of suser_xxx.
+ */
+int
+cap_check(const struct ucred *cred, const struct proc *proc,
+    cap_value_t cap, int flags)
+{
+
+	if (!cred && !proc) {
+		printf("cap_check(): THINK!\n");
+		return (EPERM);
+	}
+	if (!cred)
+		cred = proc->p_ucred;
+	/*
+	 * Disqualify processes in jail(), if flags indicate that jail()'d
+	 * processes cannot user privilege with this call.
+	 *
+	 * XXX: Right now, this only works if the process structure is
+	 * passed as an argument.
+	 * XXX: Eventually, jail(8) support will be implemented using
+	 * inherited capability bounds, meaning the flags can go away.
+	 */
+	if (proc && proc->p_prison && !(flags & PRISON_ROOT))
+		return (EPERM);
+#ifdef CAPABILITIES
+	/*
+	 * If capabilities are enabled, try to gain privilege through the
+	 * appropriate capability flag in the credential.
+	 */
+	if (kern_security_capabilities_enabled &&
+	    (cred->cr_cap.c_effective & cap))
+		return (0);
+#endif
+	/*
+	 * If the super-user is enabled, try to gain privilege through an
+	 * effective uid of 0.
+	 */
+	if (kern_security_suser_enabled &&
+	    (cred->cr_uid == 0))
+		return (0);
+	/*
+	 * Return failure, as no form of privilege was available to
+	 * authorize the request.
+	 */
+	return (EPERM);
+}
+
+/*
+ * Internal function to retrieve the capability block from a
+ * vnode.  Will always fill in the cap set, possibly by zero'ing it
+ * if the file doesn't have a capability, or if it is invalid.
+ */
+static int
+cap_get_vp(struct vnode *vp, int ioflg, struct cap *cap_p, struct proc *p)
+{
+	int	len, error;
+
+	/*
+	 * XXX: Check to see if this file system has capability support
+	 * enabled.
+	 */
+
+	len = sizeof(*cap_p);
+	error = vn_extattr_get(vp, ioflg, POSIX1E_CAPABILITY_EXTATTR_NAME,
+	    &len, (char *) cap_p, p);
+        /*
+         * XXX should check for ENOATTR and convert to null capability it
+         * received, not ENOENT
+         */
+	if (error == ENOENT || error == EOPNOTSUPP) {
+		/*
+		 * Coerce no capability attribute to a null capability set
+		 */
+		error = 0;
+		cap_zero(cap_p);
+	} else if (error == 0 && len != sizeof(*cap_p)) {
+		printf("__cap_get_file: invalid capability on file\n");
+		cap_zero(cap_p);
+	}
+	return (error);
+}
+
+/*
+ * Internal function to set the capability set for a vnode.
+ * Partial writes of extended attributes may be a problem if the
+ * underlying implementation doesn't properly return failure
+ * information.  A partial write *should* result in an invalid
+ * capability, which cap_get_vp will convert into a NULL capability
+ * set.  Let vn_extattr_set() handle locking.
+ */
+static int
+cap_set_vp(struct vnode *vp, int ioflg, struct cap *cap_p,
+    struct proc *p)
+{
+	int	len, error;
+
+	/*
+	 * XXX: Check to see if this file system has capability support
+	 * enabled.
+	 */
+
+	if ((error = cap_check(NULL, p, CAP_SETFCAP, PRISON_ROOT)))
+		return (error);
+
+	/* XXX Audit privilege here. */
+
+	len = sizeof(*cap_p);
+	error = vn_extattr_set(vp, ioflg, POSIX1E_CAPABILITY_EXTATTR_NAME,
+	    len, (char *) cap_p, p);
+	return (error);
+}
+
+/*
  * Syscall to allow a process to get it's currently capability set
  */
 int
 __cap_get_proc(struct proc *p, struct __cap_get_proc_args *uap)
 {
 
-	return (ENOSYS);
+	return (copyout(&p->p_ucred->cr_cap, (caddr_t)uap->cap_p,
+	    sizeof (struct cap)));
 }
 
 /*
@@ -67,10 +391,38 @@
 int
 __cap_set_proc(struct proc *p, struct __cap_set_proc_args *uap)
 {
+	struct cap	capability;
+	int	error, requires_privilege;
 
-	return (ENOSYS);
+	error = copyin(SCARG(uap, cap_p), &capability, sizeof(struct cap));
+	if (error)
+		return (error);
+
+	if ((error = cap_valid(&capability)))
+		return (error);
+
+	if (cap_subset(&p->p_ucred->cr_cap, &capability) == 0)
+		requires_privilege = 0;
+	else
+		requires_privilege = 1;
+
+	if (requires_privilege) {
+		if ((error = cap_check(NULL, p, CAP_SETPCAP, PRISON_ROOT)) !=
+		    0)
+			return (error);
+		suser_used(p);
+	}
+
+	/*
+	 * XXX: Ideally, this wouldn't be necessary.
+	 */
+	p->p_ucred = crcopy(p->p_ucred);
+	p->p_ucred->cr_cap = capability;
+
+	return (0);
 }
 
+
 /*
  * Syscalls to allow a process to retrieve capabilities associated with
  * files, if permitted.
@@ -78,15 +430,41 @@
 int
 __cap_get_fd(struct proc *p, struct __cap_get_fd_args *uap)
 {
+	struct filedesc	*fdp = p->p_fd;
+	struct file	*fp;
+	struct vnode	*vp;
+	struct cap	cap;
+	int	error;
+
+	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
+	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+		return (EBADF);
+	vp = (struct vnode *)fp->f_data;
+	error = cap_get_vp(vp, 0, &cap, p);
+	if (error == 0)
+		error = copyout(&cap, SCARG(uap, cap_p), sizeof(cap));
 
-	return (ENOSYS);
+	return (error);
 }
 
 int
 __cap_get_file(struct proc *p, struct __cap_get_file_args *uap)
 {
+	struct nameidata	nd;
+	struct cap	cap;
+	int	error;
+
+	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE,
+	    SCARG(uap, path_p), p);
+	if ((error = namei(&nd)) != 0)
+		return (error);
+
+	error = cap_get_vp(nd.ni_vp, 0, &cap, p);
+	if (error == 0)
+		error = copyout(&cap, SCARG(uap, cap_p), sizeof(cap));
 
-	return (ENOSYS);
+	NDFREE(&nd, 0);
+	return (error);
 }
 
 /*
@@ -96,13 +474,39 @@
 int
 __cap_set_fd(struct proc *p, struct __cap_set_fd_args *uap)
 {
-
-	return (ENOSYS);
+	struct filedesc	*fdp = p->p_fd;
+	struct file	*fp;
+	struct vnode	*vp;
+	struct cap	cap;
+	int	error;
+
+	error = copyin(SCARG(uap, cap_p), &cap, sizeof(cap));
+	if (error)
+		return (error);
+
+	if ((unsigned)uap->fd >= fdp->fd_nfiles ||
+	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
+		return (EBADF);
+	vp = (struct vnode *)fp->f_data;
+	error = cap_set_vp(vp, 0, &cap, p);
+	return (error);
 }
 
 int
 __cap_set_file(struct proc *p, struct __cap_set_file_args *uap)
 {
-
-	return (ENOSYS);
+	struct nameidata	nd;
+	struct cap	cap;
+	int	error;
+
+	error = copyin(SCARG(uap, cap_p), &cap, sizeof(cap));
+	if (error)
+		return (error);
+
+	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path_p), p);
+	if ((error = namei(&nd)) != 0)
+		return (error);
+	error = cap_set_vp(nd.ni_vp, 0, &cap, p);
+	NDFREE(&nd, 0);
+	return (error);
 }
Index: sys/kern/kern_exec.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v
retrieving revision 1.121
diff -u -r1.121 kern_exec.c
--- sys/kern/kern_exec.c	2000/12/23 19:43:09	1.121
+++ sys/kern/kern_exec.c	2001/01/05 17:01:03
@@ -48,6 +48,7 @@
 #include <sys/shm.h>
 #include <sys/sysctl.h>
 #include <sys/vnode.h>
+#include <sys/capability.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -165,6 +166,7 @@
 
 	/*
 	 * Check file permissions (also 'opens' file)
+	 * XXX Capability interaction here?
 	 */
 	error = exec_check_permissions(imgp);
 	if (error) {
@@ -279,6 +281,8 @@
 	 *
 	 * Don't honor setuid/setgid if the filesystem prohibits it or if
 	 * the process is being traced.
+	 *
+	 * Do CAP execution stuff here, in style of setuid/setgid
 	 */
 	if ((((attr.va_mode & VSUID) && p->p_ucred->cr_uid != attr.va_uid) ||
 	     ((attr.va_mode & VSGID) && p->p_ucred->cr_gid != attr.va_gid)) &&
@@ -288,11 +292,13 @@
 		 * Turn off syscall tracing for set-id programs, except for
 		 * root.
 		 */
-		if (p->p_tracep && suser(p)) {
+		if (p->p_tracep && cap_check(NULL, p, CAP_SYS_PTRACE, 0)) {
 			p->p_traceflag = 0;
 			vrele(p->p_tracep);
 			p->p_tracep = NULL;
 		}
+		if (p->p_tracep)
+			suser_used(p);
 		/*
 		 * Set the new credentials.
 		 */
@@ -314,6 +320,30 @@
 	 */
 	p->p_cred->p_svuid = p->p_ucred->cr_uid;
 	p->p_cred->p_svgid = p->p_ucred->cr_gid;
+
+	/*
+	 * CAP inheritence, et al.
+	 * XXX should this be above the file CAP stuff?
+	 * XXX is this the right vp?  could be the vp from the interpreter.
+	 * XXX vp is now unlocked?
+	 * XXX What about ptrace() handling?
+	 * XXX is ordering here a problem?  (above does tracep first,
+	 * then rights, then sugid safety, but this is different)
+	 */
+	if (cap_inherit(ndp->ni_vp, p)) {
+		/*
+		 * Resulted in a process with capabilities.
+		 */
+		if (p->p_tracep && cap_check(NULL, p, CAP_SYS_PTRACE, 0)) {
+			p->p_traceflag = 0;
+			vrele(p->p_tracep);
+			p->p_tracep = NULL;
+		}
+		if (p->p_tracep)
+			suser_used(p);
+		setsugid(p);
+		setugidsafety(p);
+	}
 
 	/*
 	 * Store the vp for use in procfs
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	2000/12/13 05:37:20
@@ -56,9 +56,10 @@
 	struct jail j;
 	struct chroot_args ca;
 
-	error = suser(p);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_CHROOT, 0)) != 0)
 		return (error);
+	suser_used(p);
+
 	error = copyin(uap->jail, &j, sizeof j);
 	if (error)
 		return (error);
Index: sys/kern/kern_linker.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_linker.c,v
retrieving revision 1.54
diff -u -r1.54 kern_linker.c
--- sys/kern/kern_linker.c	2000/12/28 08:14:58	1.54
+++ sys/kern/kern_linker.c	2001/01/05 17:01:03
@@ -693,8 +693,9 @@
     if (securelevel > 0)	/* redundant, but that's OK */
 	return EPERM;
 
-    if ((error = suser(p)) != 0)
+    if ((error = cap_check(NULL, p, CAP_SYS_MODULE, 0)) != 0)
 	return error;
+    suser_used(p);
 
     realpath = NULL;
     pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
@@ -736,8 +737,9 @@
     if (securelevel > 0)	/* redundant, but that's OK */
 	return EPERM;
 
-    if ((error = suser(p)) != 0)
+    if ((error = cap_check(NULL, p, CAP_SYS_MODULE, 0)) != 0)
 	return error;
+    suser_used(p);
 
     lf = linker_find_file_by_id(SCARG(uap, fileid));
     if (lf) {
Index: sys/kern/kern_ntptime.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_ntptime.c,v
retrieving revision 1.37
diff -u -r1.37 kern_ntptime.c
--- sys/kern/kern_ntptime.c	2000/09/10 09:13:34	1.37
+++ sys/kern/kern_ntptime.c	2000/09/17 14:51:36
@@ -291,10 +291,11 @@
 	 * from the ntv.constant member, depending on the mode bits.
 	 */
 	modes = ntv.modes;
-	if (modes)
-		error = suser(p);
-	if (error)
-		return (error);
+	if (modes) {
+		if ((error = cap_check(NULL, p, CAP_SYS_TIME, 0)) != 0);
+			return (error);
+		suser_used(p);
+	}
 	s = splclock();
 	if (modes & MOD_FREQUENCY) {
 		freq = (ntv.freq * 1000LL) >> 16;
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v
retrieving revision 1.70
diff -u -r1.70 kern_prot.c
--- sys/kern/kern_prot.c	2000/12/23 19:43:09	1.70
+++ sys/kern/kern_prot.c	2001/01/05 17:01:04
@@ -422,7 +422,7 @@
 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
 	    uid != pc->pc_ucred->cr_uid &&	/* allow setuid(geteuid()) */
 #endif
-	    (error = suser_xxx(0, p, PRISON_ROOT)))
+	    (error = cap_check(0, p, CAP_SETUID, PRISON_ROOT)) != 0)
 		return (error);
 
 #ifdef _POSIX_SAVED_IDS
@@ -434,7 +434,7 @@
 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use the clause from B.4.2.2 */
 	    uid == pc->pc_ucred->cr_uid ||
 #endif
-	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
+	    cap_check(0, p, CAP_SETUID, PRISON_ROOT) == 0)
 #endif
 	{
 		/*
@@ -486,7 +486,7 @@
 	euid = uap->euid;
 	if (euid != pc->p_ruid &&		/* allow seteuid(getuid()) */
 	    euid != pc->p_svuid &&		/* allow seteuid(saved uid) */
-	    (error = suser_xxx(0, p, PRISON_ROOT)))
+	    (error = cap_check(0, p, CAP_SETUID, PRISON_ROOT)))
 		return (error);
 	/*
 	 * Everything's okay, do it.  Copy credentials so other references do
@@ -533,7 +533,7 @@
 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
 	    gid != pc->pc_ucred->cr_groups[0] && /* allow setgid(getegid()) */
 #endif
-	    (error = suser_xxx(0, p, PRISON_ROOT)))
+	    (error = cap_check(0, p, CAP_SETGID, PRISON_ROOT)))
 		return (error);
 
 #ifdef _POSIX_SAVED_IDS
@@ -545,7 +545,7 @@
 #ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
 	    gid == pc->pc_ucred->cr_groups[0] ||
 #endif
-	    suser_xxx(0, p, PRISON_ROOT) == 0) /* we are using privs */
+	    cap_check(0, p, CAP_SETGID, PRISON_ROOT) == 0)
 #endif
 	{
 		/*
@@ -597,7 +597,7 @@
 	egid = uap->egid;
 	if (egid != pc->p_rgid &&		/* allow setegid(getgid()) */
 	    egid != pc->p_svgid &&		/* allow setegid(saved gid) */
-	    (error = suser_xxx(0, p, PRISON_ROOT)))
+	    (error = cap_check(0, p, CAP_SETGID, PRISON_ROOT)))
 		return (error);
 	if (pc->pc_ucred->cr_groups[0] != egid) {
 		pc->pc_ucred = crcopy(pc->pc_ucred);
@@ -623,7 +623,7 @@
 	register u_int ngrp;
 	int error;
 
-	if ((error = suser_xxx(0, p, PRISON_ROOT)))
+	if ((error = cap_check(0, p, CAP_SETGID, PRISON_ROOT)))
 		return (error);
 	ngrp = uap->gidsetsize;
 	if (ngrp > NGROUPS)
@@ -672,7 +672,7 @@
 	if (((ruid != (uid_t)-1 && ruid != pc->p_ruid && ruid != pc->p_svuid) ||
 	     (euid != (uid_t)-1 && euid != pc->pc_ucred->cr_uid &&
 	     euid != pc->p_ruid && euid != pc->p_svuid)) &&
-	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
+	    (error = cap_check(0, p, CAP_SETUID, PRISON_ROOT)) != 0)
 		return (error);
 
 	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
@@ -712,7 +712,7 @@
 	if (((rgid != (gid_t)-1 && rgid != pc->p_rgid && rgid != pc->p_svgid) ||
 	     (egid != (gid_t)-1 && egid != pc->pc_ucred->cr_groups[0] &&
 	     egid != pc->p_rgid && egid != pc->p_svgid)) &&
-	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
+	    (error = cap_check(0, p, CAP_SETGID, PRISON_ROOT)) != 0)
 		return (error);
 
 	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
@@ -763,7 +763,7 @@
 	      euid != pc->pc_ucred->cr_uid) ||
 	     (suid != (uid_t)-1 && suid != pc->p_ruid && suid != pc->p_svuid &&
 	      suid != pc->pc_ucred->cr_uid)) &&
-	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
+	    (error = cap_check(0, p, CAP_SETUID, PRISON_ROOT)) != 0)
 		return (error);
 	if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
 		change_euid(p, euid);
@@ -811,7 +811,7 @@
 	      egid != pc->pc_ucred->cr_groups[0]) ||
 	     (sgid != (gid_t)-1 && sgid != pc->p_rgid && sgid != pc->p_svgid &&
 	      sgid != pc->pc_ucred->cr_groups[0])) &&
-	    (error = suser_xxx(0, p, PRISON_ROOT)) != 0)
+	    (error = cap_check(0, p, CAP_SETGID, PRISON_ROOT)) != 0)
 		return (error);
 
 	if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
@@ -928,6 +928,23 @@
 	return (0);
 }
 
+/*
+ * For accounting purposes, flag a process as having used super-user
+ * privileges.  Right now this is not called much, as most code still
+ * assumes that suser() will do the dirty work.  But this is incorrect
+ * behavior.  Use of suser_used() is difficult in current code due to
+ * abuse of short-circuit boolean evaluation to call or not call
+ * suser(), rather than isolating use of privilege.
+ */
+void
+suser_used(proc)
+	struct proc *proc;
+{
+
+	if (proc)
+		proc->p_acflag |= ASU;
+}
+
 static int suser_permitted = 1;
 
 SYSCTL_INT(_kern, OID_AUTO, suser_permitted, CTLFLAG_RW, &suser_permitted, 0,
@@ -935,8 +952,9 @@
 
 /*
  * Test whether the specified credentials imply "super-user"
- * privilege; if so, and we have accounting info, set the flag
- * indicating use of super-powers.
+ * privilege.  This used to also set the appropriate accounting flag,
+ * but now ``suser_used(p)'' must be called explicitely, as not all
+ * invocations of suser() result in the privilege being excercised.
  * Returns 0 or error.
  */
 int
@@ -978,14 +996,13 @@
 		return (ESRCH);
 
 	if (!ps_showallprocs && p1->p_ucred->cr_uid != p2->p_ucred->cr_uid) {
-		if (suser_xxx(NULL, p1, PRISON_ROOT) == 0) {
+		if (cap_check(NULL, p1, CAP_SYS_ADMIN, PRISON_ROOT) == 0) {
 			if (privused != NULL)
 				*privused = 1;
 			return (0);
 		}
 		return (ESRCH);
 	}
-
 	return (0);
 }
 
@@ -1014,21 +1031,12 @@
 		return (0);
 	if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
 		return (0);
-
-	if (!suser_xxx(0, p1, PRISON_ROOT)) {
+	if (!cap_check(NULL, p1, CAP_KILL, PRISON_ROOT)) {
 		if (privused != NULL)
 			*privused = 1;
 		return (0);
 	}
 
-#ifdef CAPABILITIES
-	if (!cap_check_xxx(0, p1, CAP_KILL, PRISON_ROOT)) {
-		if (privused != NULL)
-			*privused = 1;
-		return (0);
-	}
-#endif
-
 	return (EPERM);
 }
 
@@ -1057,21 +1065,12 @@
 		return (0);
 	if (p1->p_ucred->cr_uid == p2->p_ucred->cr_uid)
 		return (0);
-
-	if (!suser_xxx(0, p1, PRISON_ROOT)) {
+	if (!cap_check(0, p1, CAP_SYS_NICE, PRISON_ROOT)) {
 		if (privused != NULL)
 			*privused = 1;
 		return (0);
 	}
 
-#ifdef CAPABILITIES
-	if (!cap_check_xxx(0, p1, CAP_SYS_NICE, PRISON_ROOT)) {
-		if (privused != NULL)
-			*privused = 1;
-		return (0);
-	}
-#endif
-
 	return (EPERM);
 }
 
@@ -1096,7 +1095,8 @@
 	    p1->p_cred->p_ruid != p2->p_cred->p_ruid ||
 	    p1->p_cred->p_svuid != p2->p_cred->p_ruid ||
 	    p2->p_flag & P_SUGID) {
-		if ((error = suser_xxx(0, p1, PRISON_ROOT)))
+		if ((error =
+		   cap_check(NULL, p1, CAP_SYS_PTRACE, PRISON_ROOT)) != 0)
 			return (error);
 		if (privused != NULL)
 			*privused = 1;
@@ -1132,7 +1132,6 @@
 	}
 }
 
-
 /*
  * Allocate a zeroed cred structure.
  */
@@ -1262,7 +1261,7 @@
 	int error;
 	char logintmp[MAXLOGNAME];
 
-	if ((error = suser_xxx(0, p, PRISON_ROOT)))
+	if ((error = cap_check(0, p, CAP_SETUID, PRISON_ROOT)) != 0)
 		return (error);
 	error = copyinstr((caddr_t) uap->namebuf, (caddr_t) logintmp,
 	    sizeof(logintmp), (size_t *)0);
Index: sys/kern/kern_resource.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.69
diff -u -r1.69 kern_resource.c
--- sys/kern/kern_resource.c	2000/12/13 00:17:01	1.69
+++ sys/kern/kern_resource.c	2000/12/13 05:40:23
@@ -89,6 +89,7 @@
 {
 	register struct proc *p;
 	register int low = PRIO_MAX + 1;
+	int privused = 0, cumulative_privused = 0;
 
 	switch (uap->which) {
 
@@ -112,8 +113,11 @@
 		else if ((pg = pgfind(uap->who)) == NULL)
 			break;
 		LIST_FOREACH(p, &pg->pg_members, p_pglist) {
-			if (!p_can(curp, p, P_CAN_SEE, NULL) && p->p_nice < low)
+			if (!p_can(curp, p, P_CAN_SEE, &privused) &&
+			    p->p_nice < low)
 				low = p->p_nice;
+			if (privused)
+				cumulative_privused = 1;
 		}
 		break;
 	}
@@ -123,10 +127,13 @@
 			uap->who = curp->p_ucred->cr_uid;
 		ALLPROC_LOCK(AP_SHARED);
 		LIST_FOREACH(p, &allproc, p_list)
-			if (!p_can(curp, p, P_CAN_SEE, NULL) &&
+			if (!p_can(curp, p, P_CAN_SEE, NULL)  &&
 			    p->p_ucred->cr_uid == uap->who &&
-			    p->p_nice < low)
+			    p->p_nice < low) {
 				low = p->p_nice;
+				if (privused)
+					cumulative_privused = 1;
+			}
 		ALLPROC_LOCK(AP_RELEASE);
 		break;
 
@@ -135,6 +142,10 @@
 	}
 	if (low == PRIO_MAX + 1)
 		return (ESRCH);
+
+	if (cumulative_privused)
+		suser_used(curp);
+
 	curp->p_retval[0] = low;
 	return (0);
 }
@@ -220,8 +231,11 @@
 		n = PRIO_MAX;
 	if (n < PRIO_MIN)
 		n = PRIO_MIN;
-	if (n < chgp->p_nice && suser(curp))
-		return (EACCES);
+	if (n < chgp->p_nice) {
+		if ((error = cap_check(NULL, curp, CAP_SYS_NICE, 0)) != 0)
+			return (error);
+		suser_used(curp);
+	}
 	chgp->p_nice = n;
 	(void)resetpriority(chgp);
 	return (0);
@@ -269,7 +283,7 @@
 		if ((error = p_can(curp, p, P_CAN_SCHED, NULL)))
 		        return (error);
 		/* disallow setting rtprio in most cases if not superuser */
-		if (suser(curp) != 0) {
+		if (cap_check(NULL, curp, CAP_SYS_NICE, 0)) {
 			/* can't set someone else's */
 			if (uap->pid)
 				return (EPERM);
@@ -287,6 +301,7 @@
 			if (rtp.type != RTP_PRIO_NORMAL)
 				return (EPERM);
 		}
+		suser_used(curp);
 		switch (rtp.type) {
 #ifdef RTP_PRIO_FIFO
 		case RTP_PRIO_FIFO:
@@ -401,9 +416,12 @@
 		limp->rlim_max = RLIM_INFINITY;
 
 	if (limp->rlim_cur > alimp->rlim_max ||
-	    limp->rlim_max > alimp->rlim_max)
-		if ((error = suser_xxx(0, p, PRISON_ROOT)))
+	    limp->rlim_max > alimp->rlim_max) {
+		if ((error = cap_check(0, p, CAP_SYS_NICE, PRISON_ROOT))
+		    != 0)
 			return (error);
+		suser_used(p);
+	}
 	if (limp->rlim_cur > limp->rlim_max)
 		limp->rlim_cur = limp->rlim_max;
 	if (p->p_limit->p_refcnt > 1 &&
Index: sys/kern/kern_shutdown.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_shutdown.c,v
retrieving revision 1.90
diff -u -r1.90 kern_shutdown.c
--- sys/kern/kern_shutdown.c	2000/12/15 20:08:19	1.90
+++ sys/kern/kern_shutdown.c	2001/01/05 17:01:04
@@ -139,8 +139,9 @@
 {
 	int error;
 
-	if ((error = suser(p)))
+	if ((error = cap_check(NULL, p, CAP_SYS_BOOT, 0)) != 0)
 		return (error);
+	suser_used(p);
 
 	boot(uap->opt);
 	return (0);
Index: sys/kern/kern_sig.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.101
diff -u -r1.101 kern_sig.c
--- sys/kern/kern_sig.c	2001/01/02 18:54:09	1.101
+++ sys/kern/kern_sig.c	2001/01/05 17:01:05
@@ -65,6 +65,7 @@
 #include <sys/sysent.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
+#include <sys/capability.h>
 
 #include <machine/cpu.h>
 #include <machine/smp.h>
@@ -96,6 +97,11 @@
 
 /*
  * Can process p, with pcred pc, send the signal sig to process q?
+ * XXX should p be able to signal q outside the same prison if CAP_KILL
+ * is present?
+ *
+ * XXX This should propagate the privused flag up the stack but
+ * doesn't.
  */
 #define CANSIGNAL(p, q, sig) \
 	(!p_can(p, q, P_CAN_KILL, NULL) || \
Index: sys/kern/kern_sysctl.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.102
diff -u -r1.102 kern_sysctl.c
--- sys/kern/kern_sysctl.c	2001/01/05 07:00:44	1.102
+++ sys/kern/kern_sysctl.c	2001/01/05 17:01:05
@@ -1015,11 +1015,22 @@
 		return (EPERM);
 
 	/* Most likely only root can write */
+	/*
+	 * XXX What about capabilities?
+	 * Ought to have another argument to SYSCTL_* allowing a specific
+	 * capability to be identified as providing the privilege to write,
+	 * rather than just suser().  For now, use CAP_SYSADMIN, but this
+	 * should change.
+	 */
 	if (!(oid->oid_kind & CTLFLAG_ANYBODY) &&
-	    req->newptr && req->p &&
-	    (error = suser_xxx(0, req->p, 
-	    (oid->oid_kind & CTLFLAG_PRISON) ? PRISON_ROOT : 0)))
-		return (error);
+	    req->newptr && req->p) {
+		int flag_prison = ((oid->oid_kind & CTLFLAG_PRISON) ?
+		    PRISON_ROOT : 0);
+		if ((error = cap_check(0, req->p, CAP_SYS_ADMIN,
+		    flag_prison)) != 0)
+			return (error);
+		suser_used(req->p);
+	}
 
 	if (!oid->oid_handler)
 		return EINVAL;
Index: sys/kern/kern_time.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_time.c,v
retrieving revision 1.71
diff -u -r1.71 kern_time.c
--- sys/kern/kern_time.c	2000/11/27 22:52:29	1.71
+++ sys/kern/kern_time.c	2000/12/13 05:37:22
@@ -174,8 +174,9 @@
 	struct timespec ats;
 	int error;
 
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_SYS_TIME, 0)) != 0)
 		return (error);
+	suser_used(p);
 	if (SCARG(uap, clock_id) != CLOCK_REALTIME)
 		return (EINVAL);
 	if ((error = copyin(SCARG(uap, tp), &ats, sizeof(ats))) != 0)
@@ -331,8 +332,9 @@
 	struct timezone atz;
 	int error;
 
-	if ((error = suser(p)))
+	if ((error = cap_check(NULL, p, CAP_SYS_TIME, 0)) != 0)
 		return (error);
+	suser_used(p);
 	/* Verify all parameters before changing time. */
 	if (uap->tv) {
 		if ((error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
@@ -371,8 +373,10 @@
 	register long ndelta, ntickdelta, odelta;
 	int s, error;
 
-	if ((error = suser(p)))
+	if ((error = cap_check(NULL, p, CAP_SYS_TIME, 0)) != 0)
 		return (error);
+	suser_used(p);
+
 	if ((error =
 	    copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
 		return (error);
Index: sys/kern/kern_xxx.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_xxx.c,v
retrieving revision 1.31
diff -u -r1.31 kern_xxx.c
--- sys/kern/kern_xxx.c	1999/08/28 00:46:15	1.31
+++ sys/kern/kern_xxx.c	2000/09/17 14:56:07
@@ -85,8 +85,10 @@
 
 	name[0] = CTL_KERN;
 	name[1] = KERN_HOSTNAME;
-	if ((error = suser_xxx(0, p, PRISON_ROOT)))
+	if ((error = cap_check(0, p, CAP_SYS_ADMIN, PRISON_ROOT)) != 0)
 		return (error);
+	suser_used(p);
+
 	return (userland_sysctl(p, name, 2, 0, 0, 0,
 		uap->hostname, uap->len, 0));
 }
@@ -122,8 +124,10 @@
 {
 	int error;
 
-	if ((error = suser(p)))
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
+
 	hostid = uap->hostid;
 	return (0);
 }
@@ -244,8 +248,10 @@
 {
         int error, domainnamelen;
 
-        if ((error = suser(p)))
+        if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
                 return (error);
+	suser_used(p);
+
         if ((u_int)uap->len > sizeof (domainname) - 1)
                 return EINVAL;
         domainnamelen = uap->len;
Index: sys/kern/makesyscalls.sh
===================================================================
RCS file: /home/ncvs/src/sys/kern/makesyscalls.sh,v
retrieving revision 1.44
diff -u -r1.44 makesyscalls.sh
--- sys/kern/makesyscalls.sh	2000/12/01 08:47:54	1.44
+++ sys/kern/makesyscalls.sh	2000/12/13 05:37:22
@@ -111,8 +111,9 @@
 		printf " * created from%s\n */\n\n", $0 > sysarg
 		printf "#ifndef %s\n", sysproto_h > sysarg
 		printf "#define\t%s\n\n", sysproto_h > sysarg
-		printf "#include <sys/signal.h>\n\n" > sysarg
-		printf "#include <sys/acl.h>\n\n" > sysarg
+		printf "#include <sys/signal.h>\n" > sysarg
+		printf "#include <sys/acl.h>\n" > sysarg
+		printf "#include <sys/capability.h>\n\n" > sysarg
 		printf "struct proc;\n\n" > sysarg
 		printf "#define\tPAD_(t)\t(sizeof(register_t) <= sizeof(t) ? \\\n" > sysarg
 		printf "\t\t0 : sizeof(register_t) - sizeof(t))\n\n" > sysarg
Index: sys/kern/sys_process.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sys_process.c,v
retrieving revision 1.59
diff -u -r1.59 sys_process.c
--- sys/kern/sys_process.c	2000/12/31 01:30:27	1.59
+++ sys/kern/sys_process.c	2001/01/05 17:01:06
@@ -206,6 +206,7 @@
 	struct proc *p;
 	struct iovec iov;
 	struct uio uio;
+	int privused = 0;
 	int error = 0;
 	int write;
 	int s;
@@ -237,8 +238,10 @@
 		if (p->p_flag & P_TRACED)
 			return EBUSY;
 
-		if ((error = p_can(curp, p, P_CAN_DEBUG, NULL)))
+		if ((error = p_can(curp, p, P_CAN_DEBUG, &privused)))
 			return error;
+		if (privused)
+			suser_used(curp);
 
 		/* OK */
 		break;
Index: sys/kern/sys_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sys_socket.c,v
retrieving revision 1.32
diff -u -r1.32 sys_socket.c
--- sys/kern/sys_socket.c	2000/07/03 00:05:40	1.32
+++ sys/kern/sys_socket.c	2000/08/07 18:44:28
@@ -45,6 +45,7 @@
 #include <sys/stat.h>
 #include <sys/uio.h>
 #include <sys/filedesc.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 
 #include <net/if.h>
Index: sys/kern/sysv_ipc.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_ipc.c,v
retrieving revision 1.17
diff -u -r1.17 sysv_ipc.c
--- sys/kern/sysv_ipc.c	2000/12/01 08:57:45	1.17
+++ sys/kern/sysv_ipc.c	2000/12/14 00:42:39
@@ -92,8 +92,13 @@
 
 	/* Check for user match. */
 	if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) {
-		if (mode & IPC_M)
-			return (suser(p) == 0 ? 0 : EPERM);
+		if (mode & IPC_M) {
+			if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+				return (error);
+		else {
+			suser_used(p);
+			return (0);
+		}
 		/* Check for group match. */
 		mode >>= 3;
 		if (!groupmember(perm->gid, cred) &&
@@ -104,5 +109,13 @@
 
 	if (mode & IPC_M)
 		return (0);
-	return ((mode & perm->mode) == mode || suser(p) == 0 ? 0 : EACCES);
+
+	if ((mode & perm->mode) == mode)
+		return (0);
+
+	if (cap_check(NULL, p, CAP_IPC_OWNER, 0) == 0) {
+		suser_user(p);
+		return (0);
+	}
+	return (EACCES);
 }
Index: sys/kern/sysv_msg.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/sysv_msg.c,v
retrieving revision 1.28
diff -u -r1.28 sysv_msg.c
--- sys/kern/sysv_msg.c	2000/12/05 23:05:45	1.28
+++ sys/kern/sysv_msg.c	2000/12/13 05:37:24
@@ -402,9 +402,10 @@
 		if ((eval = copyin(user_msqptr, &msqbuf, sizeof(msqbuf))) != 0)
 			return(eval);
 		if (msqbuf.msg_qbytes > msqptr->msg_qbytes) {
-			eval = suser(p);
-			if (eval)
+			eval = cap_check(NULL, p, CAP_SYS_RESOURCE, 0);
+			if (eval != 0)
 				return(eval);
+			suser_used(p);
 		}
 		if (msqbuf.msg_qbytes > msginfo.msgmnb) {
 #ifdef MSG_DEBUG_OK
Index: sys/kern/tty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty.c,v
retrieving revision 1.142
diff -u -r1.142 tty.c
--- sys/kern/tty.c	2000/12/08 21:50:36	1.142
+++ sys/kern/tty.c	2000/12/13 05:37:24
@@ -816,8 +816,10 @@
 			    ISSET(constty->t_state, TS_CONNECTED))
 				return (EBUSY);
 #ifndef	UCONSOLE
-			if ((error = suser(p)) != 0)
+			if ((error = cap_check(NULL, p, CAP_SYS_TTY_CONFIG,
+			    0)) != 0)
 				return (error);
+			suser_used(p);
 #endif
 			constty = tp;
 		} else if (tp == constty)
@@ -988,10 +990,19 @@
 		splx(s);
 		break;
 	case TIOCSTI:			/* simulate terminal input */
-		if ((flag & FREAD) == 0 && suser(p))
-			return (EPERM);
-		if (!isctty(p, tp) && suser(p))
-			return (EACCES);
+		if ((flag & FREAD) == 0) {
+			if ((error = cap_check(NULL, p, CAP_SYS_TTY_CONFIG,
+			    0)) != 0)
+				return (error);
+			else
+				suser_used(p);
+		}
+		if (!isctty(p, tp)) {
+			if (cap_check(NULL, p, CAP_SYS_TTY_CONFIG, 0) != 0)
+				return (EACCES);
+			else
+				suser_used(p);
+		}
 		s = spltty();
 		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
 		splx(s);
@@ -1038,9 +1049,10 @@
 		}
 		break;
 	case TIOCSDRAINWAIT:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_SYS_TTY_CONFIG, 0)) != 0)
 			return (error);
+		suser_used(p);
+
 		tp->t_timeout = *(int *)data * hz;
 		wakeup(TSA_OCOMPLETE(tp));
 		wakeup(TSA_OLOWAT(tp));
Index: sys/kern/tty_cons.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_cons.c,v
retrieving revision 1.88
diff -u -r1.88 tty_cons.c
--- sys/kern/tty_cons.c	2000/12/20 21:50:37	1.88
+++ sys/kern/tty_cons.c	2001/01/05 17:01:06
@@ -374,9 +374,10 @@
 	 * output from the "virtual" console.
 	 */
 	if (cmd == TIOCCONS && constty) {
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_SYS_TTY_CONFIG, 0)) != 0)
 			return (error);
+		suser_used(p);
+
 		constty = NULL;
 		return (0);
 	}
Index: sys/kern/tty_pty.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_pty.c,v
retrieving revision 1.82
diff -u -r1.82 tty_pty.c
--- sys/kern/tty_pty.c	2000/12/08 21:50:37	1.82
+++ sys/kern/tty_pty.c	2000/12/13 05:37:25
@@ -183,7 +183,11 @@
 		tp->t_lflag = TTYDEF_LFLAG;
 		tp->t_cflag = TTYDEF_CFLAG;
 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
-	} else if (tp->t_state & TS_XCLUDE && suser(p)) {
+	} else if (tp->t_state & TS_XCLUDE) {
+		/*
+		 * XXX used to be && suser(p) with, why could suser override
+		 * TS_XCLUDE?
+		 */
 		return (EBUSY);
 	} else if (pti->pt_prison != p->p_prison) {
 		return (EBUSY);
Index: sys/kern/tty_snoop.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/tty_snoop.c,v
retrieving revision 1.50
diff -u -r1.50 tty_snoop.c
--- sys/kern/tty_snoop.c	2000/12/08 21:50:37	1.50
+++ sys/kern/tty_snoop.c	2000/12/13 05:37:25
@@ -285,7 +285,7 @@
 	struct snoop   *snp;
 	int error;
 
-	if ((error = suser(p)) != 0)
+	if (((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
 
 	if (dev->si_drv1 == NULL) {
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.298
diff -u -r1.298 vfs_subr.c
--- sys/kern/vfs_subr.c	2000/12/15 20:08:19	1.298
+++ sys/kern/vfs_subr.c	2001/01/05 17:01:07
@@ -3032,15 +3032,12 @@
 	int *privused;
 {
 	mode_t dac_granted;
-#ifdef CAPABILITIES
 	mode_t cap_granted;
-#endif
 
 	/*
 	 * Look for a normal, non-privileged way to access the file/directory
 	 * as requested.  If it exists, go with that.
 	 */
-
 	if (privused != NULL)
 		*privused = 0;
 
@@ -3088,14 +3085,6 @@
 		return (0);
 
 privcheck:
-	if (!suser_xxx(cred, NULL, PRISON_ROOT)) {
-		/* XXX audit: privilege used */
-		if (privused != NULL)
-			*privused = 1;
-		return (0);
-	}
-
-#ifdef CAPABILITIES
 	/*
 	 * Build a capability mask to determine if the set of capabilities
 	 * satisfies the requirements when combined with the granted mask
@@ -3104,16 +3093,27 @@
 	 * or the request type onto the cap_granted mask.
 	 */
 	cap_granted = 0;
-	if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
-	    !cap_check_xxx(cred, NULL, CAP_DAC_EXECUTE, PRISON_ROOT))
-	    cap_granted |= VEXEC;
+
+	if (type == VDIR) {
+		/*
+		 * For directories, use CAP_DAC_READ_SEARCH to satisfy
+		 * VEXEC requests, instead of CAP_DAC_EXECUTE.
+		 */
+		if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
+		    !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, PRISON_ROOT))
+			cap_granted |= VEXEC;
+	} else {
+		if ((acc_mode & VEXEC) && ((dac_granted & VEXEC) == 0) &&
+		    !cap_check(cred, NULL, CAP_DAC_EXECUTE, PRISON_ROOT))
+			cap_granted |= VEXEC;
+	}
 
 	if ((acc_mode & VREAD) && ((dac_granted & VREAD) == 0) &&
-	    !cap_check_xxx(cred, NULL, CAP_DAC_READ_SEARCH, PRISON_ROOT))
+	    !cap_check(cred, NULL, CAP_DAC_READ_SEARCH, PRISON_ROOT))
 		cap_granted |= VREAD;
 
 	if ((acc_mode & VWRITE) && ((dac_granted & VWRITE) == 0) &&
-	    !cap_check_xxx(cred, NULL, CAP_DAC_WRITE, PRISON_ROOT))
+	    !cap_check(cred, NULL, CAP_DAC_WRITE, PRISON_ROOT))
 		cap_granted |= VWRITE;
 
 	if ((acc_mode & VADMIN) && ((dac_granted & VADMIN) == 0) &&
@@ -3126,7 +3126,6 @@
 			*privused = 1;
 		return (0);
 	}
-#endif
 
 	return (EACCES);
 }
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.175
diff -u -r1.175 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	2000/12/13 00:17:01	1.175
+++ sys/kern/vfs_syscalls.c	2000/12/13 05:37:27
@@ -122,21 +122,28 @@
 	struct nameidata nd;
 	char fstypename[MFSNAMELEN];
 
-	if (usermount == 0 && (error = suser(p)))
-		return (error);
+	if (usermount == 0) {
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return (error);
+		suser_used(p);
+	}
 	/*
 	 * Do not allow NFS export by non-root users.
 	 */
 	if (SCARG(uap, flags) & MNT_EXPORTED) {
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 			return (error);
+		suser_used(p);
 	}
 	/*
 	 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
 	 */
-	if (suser_xxx(p->p_ucred, 0, 0)) 
+	if (cap_check(p->p_ucred, NULL, CAP_SYS_ADMIN, 0) != 0)
 		SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
+	else if ((SCARG(uap, flags) & (MNT_NOSUID | MNT_NODEV)) !=
+	    (MNT_NOSUID | MNT_NODEV))
+		suser_used(p);
+	
 	/*
 	 * Get vnode to be covered
 	 */
@@ -168,10 +175,11 @@
 		 * permitted to update it.
 		 */
 		if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
-		    (error = suser(p))) {
+		    ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)) {
 			vput(vp);
 			return (error);
-		}
+		} else
+			suser_used(p);
 		if (vfs_busy(mp, LK_NOWAIT, 0, p)) {
 			vput(vp);
 			return (EBUSY);
@@ -196,10 +204,13 @@
 	 * onto which we are attempting to mount.
 	 */
 	if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) ||
-	    (va.va_uid != p->p_ucred->cr_uid &&
-	     (error = suser(p)))) {
-		vput(vp);
-		return (error);
+	    (va.va_uid != p->p_ucred->cr_uid)) {
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			suser_used(p);
+		else {
+			vput(vp);
+			return (error);
+		}
 	}
 	if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) {
 		vput(vp);
@@ -220,10 +231,11 @@
 		linker_file_t lf;
 
 		/* Only load modules for root (very important!) */
-		if ((error = suser(p)) != 0) {
+		if ((error = cap_check(NULL, p, CAP_SYS_MODULE, 0)) != 0) {
 			vput(vp);
 			return error;
 		}
+		suser_used(p);
 		error = linker_load_file(fstypename, &lf);
 		if (error || lf == NULL) {
 			vput(vp);
@@ -426,10 +438,12 @@
 	 * Only root, or the user that did the original mount is
 	 * permitted to unmount this filesystem.
 	 */
-	if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
-	    (error = suser(p))) {
-		vput(vp);
-		return (error);
+	if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid)) {
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0) {
+			vput(vp);
+			return (error);
+		}
+		suser_used(p);
 	}
 
 	/*
@@ -652,11 +666,12 @@
 	if (error)
 		return (error);
 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
-	if (suser_xxx(p->p_ucred, 0, 0)) {
+	if (cap_check(p->p_ucred, NULL, CAP_SYS_ADMIN, 0) != 0) {
 		bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
 		sp = &sb;
-	}
+	} else
+		suser_used(p);
 	return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
 }
 
@@ -692,11 +707,12 @@
 	if (error)
 		return (error);
 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
-	if (suser_xxx(p->p_ucred, 0, 0)) {
+	if (cap_check(p->p_ucred, NULL, CAP_SYS_ADMIN, 0) != 0) {
 		bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
 		sp = &sb;
-	}
+	} else
+		suser_used(p);
 	return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
 }
 
@@ -908,9 +924,10 @@
 	int error;
 	struct nameidata nd;
 
-	error = suser_xxx(0, p, PRISON_ROOT);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_CHROOT, PRISON_ROOT)) != 0)
 		return (error);
+	suser_used(p);
+
 	if (chroot_allow_open_directories == 0 ||
 	    (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode))
 		error = chroot_refuse_vdir_fds(fdp);
@@ -1170,10 +1187,10 @@
 	switch (SCARG(uap, mode) & S_IFMT) {
 	case S_IFCHR:
 	case S_IFBLK:
-		error = suser(p);
+		error = cap_check(NULL, p, CAP_MKNOD, 0);
 		break;
 	default:
-		error = suser_xxx(0, p, PRISON_ROOT);
+		error = cap_check(NULL, p, CAP_MKNOD, PRISON_ROOT);
 		break;
 	}
 	if (error)
@@ -2052,9 +2069,12 @@
 	 * if they are allowed to set flags and programs assume that
 	 * chown can't fail when done as root.
 	 */
-	if ((vp->v_type == VCHR || vp->v_type == VBLK) && 
-	    ((error = suser_xxx(p->p_ucred, p, PRISON_ROOT)) != 0))
-		return (error);
+	if (vp->v_type == VCHR || vp->v_type == VBLK) {
+		if ((error = cap_check(p->p_ucred, p, CAP_SYS_SETFFLAG,
+		    PRISON_ROOT)) != 0)
+			return (error);
+		suser_used(p);
+	}
 
 	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
 		return (error);
@@ -3244,8 +3264,12 @@
 	}
 	if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
 		goto out;
-	if (p->p_ucred->cr_uid != vattr.va_uid &&
-	    (error = suser_xxx(0, p, PRISON_ROOT)))
+	if (p->p_ucred->cr_uid != vattr.va_uid) {
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN,
+		    PRISON_ROOT)) != 0)
+			goto out;
+		suser_used(p);
+	}
 		goto out;
 	if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
 		goto out;
@@ -3298,9 +3322,10 @@
 	/*
 	 * Must be super user
 	 */
-	error = suser(p);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
+
 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
 	error = namei(&nd);
 	if (error)
@@ -3353,9 +3378,9 @@
 	/*
 	 * Must be super user
 	 */
-	error = suser(p);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
 
 	fmode = FFLAGS(SCARG(uap, flags));
 	/* why not allow a non-read/write open for our lockd? */
@@ -3523,9 +3548,9 @@
 	/*
 	 * Must be super user
 	 */
-	error = suser(p);
-	if (error)
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
 	
 	error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t));
 	if (error)
@@ -3570,8 +3595,9 @@
 	/*
 	 * Must be super user
 	 */
-	if ((error = suser(p)))
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
 
 	if ((error = copyin(SCARG(uap, u_fhp), &fh, sizeof(fhandle_t))) != 0)
 		return (error);
@@ -3586,11 +3612,13 @@
 	if ((error = VFS_STATFS(mp, sp, p)) != 0)
 		return (error);
 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
-	if (suser_xxx(p->p_ucred, 0, 0)) {
+	if (cap_check(p->p_ucred, NULL, CAP_SYS_ADMIN, 0) != 0) {
 		bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
 		sp = &sb;
-	}
+	} else
+		suser_used(p);
+
 	return (copyout(sp, SCARG(uap, buf), sizeof(*sp)));
 }
 
Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.106
diff -u -r1.106 vfs_vnops.c
--- sys/kern/vfs_vnops.c	2000/11/18 23:06:23	1.106
+++ sys/kern/vfs_vnops.c	2000/12/13 05:37:27
@@ -531,7 +531,7 @@
 	}
 	
 	sb->st_flags = vap->va_flags;
-	if (suser_xxx(p->p_ucred, 0, 0))
+	if (cap_check(p->p_ucred, NULL, CAP_SYS_ADMIN, 0) != 0)
 		sb->st_gen = 0;
 	else
 		sb->st_gen = vap->va_gen;
Index: sys/miscfs/procfs/procfs_mem.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_mem.c,v
retrieving revision 1.47
diff -u -r1.47 procfs_mem.c
--- sys/miscfs/procfs/procfs_mem.c	2000/08/30 04:49:08	1.47
+++ sys/miscfs/procfs/procfs_mem.c	2000/09/17 15:32:38
@@ -304,7 +304,10 @@
 	struct ucred *cred;
 
 	cred = curp->p_ucred;
-	if (suser(curp))
+	/*
+	 * XXX is CAP_SYS_ADMIN appropriate here?  If not, what?
+	 */
+	if (cap_check(NULL, curp, CAP_SYS_ADMIN, 0))
 		return 1;
 
 	/* XXX: Why isn't this done with file-perms ??? */
Index: sys/miscfs/procfs/procfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/procfs/procfs_vnops.c,v
retrieving revision 1.87
diff -u -r1.87 procfs_vnops.c
--- sys/miscfs/procfs/procfs_vnops.c	2000/12/31 10:24:19	1.87
+++ sys/miscfs/procfs/procfs_vnops.c	2001/01/05 17:41:26
@@ -248,7 +248,8 @@
 	   */
 #define NFLAGS	(PF_ISUGID)
 	  flags = (unsigned char)*(unsigned int*)ap->a_data;
-	  if (flags & NFLAGS && (error = suser(p)))
+	  if (flags & NFLAGS && (error = cap_check(NULL, p, CAP_SYS_PTRACE,
+	    0)))
 	    return error;
 	  procp->p_pfsflags = flags;
 	  break;
Index: sys/miscfs/umapfs/umap_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/miscfs/umapfs/umap_vfsops.c,v
retrieving revision 1.33
diff -u -r1.33 umap_vfsops.c
--- sys/miscfs/umapfs/umap_vfsops.c	2000/10/29 16:06:36	1.33
+++ sys/miscfs/umapfs/umap_vfsops.c	2000/11/07 02:43:13
@@ -100,8 +100,9 @@
 
 	/*
 	 * Only for root
+	 * XXX: Is CAP_SYS_ADMIN appropriate?
 	 */
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
 		return (error);
 
 #ifdef DEBUG
Index: sys/msdosfs/msdosfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/msdosfs/msdosfs_vnops.c,v
retrieving revision 1.106
diff -u -r1.106 msdosfs_vnops.c
--- sys/msdosfs/msdosfs_vnops.c	2000/10/22 14:24:30	1.106
+++ sys/msdosfs/msdosfs_vnops.c	2000/10/23 06:52:29
@@ -391,7 +391,8 @@
 		if (vp->v_mount->mnt_flag & MNT_RDONLY)
 			return (EROFS);
 		if (cred->cr_uid != pmp->pm_uid &&
-		    (error = suser_xxx(cred, ap->a_p, PRISON_ROOT)))
+		    (error =
+		    cap_check(cred, ap->a_p, CAP_FOWNER, PRISON_ROOT)))
 			return (error);
 		/*
 		 * We are very inconsistent about handling unsupported
Index: sys/net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.96
diff -u -r1.96 if.c
--- sys/net/if.c	2000/12/08 21:50:43	1.96
+++ sys/net/if.c	2000/12/13 05:38:16
@@ -769,7 +769,7 @@
 	register struct ifnet *ifp;
 	register struct ifreq *ifr;
 	struct ifstat *ifs;
-	int error;
+	int error, privilege_used = 0;
 	short oif_flags;
 
 	switch (cmd) {
@@ -801,9 +801,10 @@
 		break;
 
 	case SIOCSIFFLAGS:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return (error);
+		suser_used(p);
+
 		ifr->ifr_prevflags = ifp->if_flags;
 		if (ifp->if_flags & IFF_SMART) {
 			/* Smart drivers twiddle their own routes */
@@ -826,31 +827,37 @@
 		break;
 
 	case SIOCSIFMETRIC:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return (error);
+		suser_used(p);
+
 		ifp->if_metric = ifr->ifr_metric;
 		getmicrotime(&ifp->if_lastchange);
 		break;
 
 	case SIOCSIFPHYS:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return error;
+		privilege_used = 1;
+
 		if (!ifp->if_ioctl)
 		        return EOPNOTSUPP;
 		error = (*ifp->if_ioctl)(ifp, cmd, data);
 		if (error == 0)
 			getmicrotime(&ifp->if_lastchange);
+
+		if (error == 0 && privilege_used)
+			suser_used(p);
 		return(error);
 
 	case SIOCSIFMTU:
 	{
 		u_long oldmtu = ifp->if_mtu;
 
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return (error);
+		privilege_used = 1;
+
 		if (ifp->if_ioctl == NULL)
 			return (EOPNOTSUPP);
 		if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU)
@@ -868,14 +875,16 @@
 			nd6_setmtu(ifp);
 #endif
 		}
+		if (error == 0 && privilege_used)
+			suser_used(p);
 		return (error);
 	}
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return (error);
+		privilege_used = 1;
 
 		/* Don't allow group membership on non-multicast interfaces. */
 		if ((ifp->if_flags & IFF_MULTICAST) == 0)
@@ -893,6 +902,8 @@
 		}
 		if (error == 0)
 			getmicrotime(&ifp->if_lastchange);
+		if (error == 0 && privilege_used)
+			suser_used(p);
 		return error;
 
 	case SIOCSIFPHYADDR:
@@ -902,14 +913,17 @@
 #endif
         case SIOCSIFMEDIA:
 	case SIOCSIFGENERIC:
-		error = suser(p);
-		if (error)
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 			return (error);
+		privilege_used = 1;
+
 		if (ifp->if_ioctl == 0)
 			return (EOPNOTSUPP);
 		error = (*ifp->if_ioctl)(ifp, cmd, data);
 		if (error == 0)
 			getmicrotime(&ifp->if_lastchange);
+		if (error == 0 && privilege_used)
+			suser_used(p);
 		return error;
 
 	case SIOCGIFSTATUS:
@@ -923,7 +937,7 @@
 		return ((*ifp->if_ioctl)(ifp, cmd, data));
 
 	case SIOCSIFLLADDR:
-		error = suser(p);
+		error = cap_check(NULL, p, CAP_NET_ADMIN, 0);
 		if (error)
 			return (error);
 		return if_setlladdr(ifp,
Index: sys/net/if_ppp.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_ppp.c,v
retrieving revision 1.68
diff -u -r1.68 if_ppp.c
--- sys/net/if_ppp.c	2000/11/25 07:35:31	1.68
+++ sys/net/if_ppp.c	2000/12/13 05:43:39
@@ -355,8 +355,10 @@
 	break;
 
     case PPPIOCSFLAGS:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	    return (error);
+	suser_used(p);
 	flags = *(int *)data & SC_MASK;
 	s = splsoftnet();
 #ifdef PPP_COMPRESS
@@ -369,8 +371,9 @@
 	break;
 
     case PPPIOCSMRU:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    return (error);
+	suser_used(p);
 	mru = *(int *)data;
 	if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
 	    sc->sc_mru = mru;
@@ -382,8 +385,9 @@
 
 #ifdef VJC
     case PPPIOCSMAXCID:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	if (sc->sc_comp) {
 	    s = splsoftnet();
 	    sl_compress_init(sc->sc_comp, *(int *)data);
@@ -393,15 +397,17 @@
 #endif
 
     case PPPIOCXFERUNIT:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	sc->sc_xfer = p->p_pid;
 	break;
 
 #ifdef PPP_COMPRESS
     case PPPIOCSCOMPRESS:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	odp = (struct ppp_option_data *) data;
 	nb = odp->length;
 	if (nb > sizeof(ccp_option))
@@ -475,8 +481,10 @@
 	if (cmd == PPPIOCGNPMODE) {
 	    npi->mode = sc->sc_npmode[npx];
 	} else {
-	    if ((error = suser(p)) != 0)
+	    if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 		break;
+		return (error);
+	    suser_used(p);
 	    if (npi->mode != sc->sc_npmode[npx]) {
 		s = splsoftnet();
 		sc->sc_npmode[npx] = npi->mode;
@@ -601,8 +609,9 @@
 	break;
 
     case SIOCSIFMTU:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	if (ifr->ifr_mtu > PPP_MAXMTU)
 	    error = EINVAL;
 	else {
Index: sys/net/if_sl.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_sl.c,v
retrieving revision 1.92
diff -u -r1.92 if_sl.c
--- sys/net/if_sl.c	2000/12/21 21:43:45	1.92
+++ sys/net/if_sl.c	2001/01/05 17:42:12
@@ -328,9 +328,10 @@
 	register struct sl_softc *sc;
 	int s, error;
 
-	error = suser(p);
+	error = cap_check(NULL, p, CAP_NET_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(p);
 
 	if (tp->t_line == SLIPDISC)
 		return (0);
Index: sys/net/if_tap.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_tap.c,v
retrieving revision 1.5
diff -u -r1.5 if_tap.c
--- sys/net/if_tap.c	2000/12/08 21:50:44	1.5
+++ sys/net/if_tap.c	2000/12/13 05:38:17
@@ -271,8 +271,9 @@
 	struct tap_softc	*tp = NULL;
 	int			 error;
 
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
 
 	tp = dev->si_drv1;
 	if (tp == NULL) {
Index: sys/net/if_tun.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if_tun.c,v
retrieving revision 1.83
diff -u -r1.83 if_tun.c
--- sys/net/if_tun.c	2000/12/08 21:50:44	1.83
+++ sys/net/if_tun.c	2000/12/13 05:38:18
@@ -180,9 +180,10 @@
 	struct tun_softc *tp;
 	register int	error;
 
-	error = suser(p);
+	error = cap_check(NULL, p, CAP_NET_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(p);
 
 	tp = dev->si_drv1;
 	if (!tp) {
Index: sys/net/ppp_tty.c
===================================================================
RCS file: /home/ncvs/src/sys/net/ppp_tty.c,v
retrieving revision 1.46
diff -u -r1.46 ppp_tty.c
--- sys/net/ppp_tty.c	2000/12/21 21:43:45	1.46
+++ sys/net/ppp_tty.c	2001/01/05 17:42:12
@@ -175,8 +175,9 @@
     register struct ppp_softc *sc;
     int error, s;
 
-    if ((error = suser(p)) != 0)
+    if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	return (error);
+    suser_used(p);
 
     s = spltty();
 
@@ -444,8 +445,9 @@
     error = 0;
     switch (cmd) {
     case PPPIOCSASYNCMAP:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	sc->sc_asyncmap[0] = *(u_int *)data;
 	break;
 
@@ -454,8 +456,9 @@
 	break;
 
     case PPPIOCSRASYNCMAP:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	sc->sc_rasyncmap = *(u_int *)data;
 	break;
 
@@ -464,8 +467,9 @@
 	break;
 
     case PPPIOCSXASYNCMAP:
-	if ((error = suser(p)) != 0)
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 	    break;
+	suser_used(p);
 	s = spltty();
 	bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
 	sc->sc_asyncmap[1] = 0;		    /* mustn't escape 0x20 - 0x3f */
Index: sys/net/raw_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/net/raw_usrreq.c,v
retrieving revision 1.19
diff -u -r1.19 raw_usrreq.c
--- sys/net/raw_usrreq.c	2000/10/29 16:06:43	1.19
+++ sys/net/raw_usrreq.c	2000/11/07 02:45:17
@@ -157,8 +157,9 @@
 
 	if (rp == 0)
 		return EINVAL;
-	if (p && (error = suser(p)) != 0)
+	if (p && (error = cap_check(NULL, p, CAP_NET_RAW, 0)) != 0)
 		return error;
+	suser_used(p);
 	return raw_attach(so, proto);
 }
 
Index: sys/netatalk/at_control.c
===================================================================
RCS file: /home/ncvs/src/sys/netatalk/at_control.c,v
retrieving revision 1.29
diff -u -r1.29 at_control.c
--- sys/netatalk/at_control.c	2000/12/08 21:50:45	1.29
+++ sys/netatalk/at_control.c	2000/12/13 05:38:19
@@ -11,6 +11,7 @@
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/socket.h>
+#include <sys/capability.h>
 #include <net/if.h>
 #include <net/route.h>
 #include <netinet/in.h>
@@ -52,6 +53,7 @@
     struct at_ifaddr	*aa0;
     struct at_ifaddr	*aa = 0;
     struct ifaddr	*ifa, *ifa0;
+    int			error;
 
     /*
      * If we have an ifp, then find the matching at_ifaddr if it exists
@@ -99,9 +101,10 @@
 	/* 
 	 * If we are not superuser, then we don't get to do these ops.
 	 */
-	if ( suser(p) ) {
-	    return( EPERM );
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0) {
+	    return( error );
 	}
+	suser_used(p);
 
 	sat = satosat( &ifr->ifr_addr );
 	nr = (struct netrange *)sat->sat_zero;
Index: sys/netatalk/ddp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netatalk/ddp_usrreq.c,v
retrieving revision 1.20
diff -u -r1.20 ddp_usrreq.c
--- sys/netatalk/ddp_usrreq.c	2000/12/08 21:50:45	1.20
+++ sys/netatalk/ddp_usrreq.c	2000/12/13 05:38:19
@@ -12,6 +12,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
+#include <sys/capability.h>
 #include <net/if.h>
 #include <net/route.h>
 
@@ -253,8 +254,9 @@
 		return( EINVAL );
 	    }
 	    if ( sat->sat_port < ATPORT_RESERVED &&
-		 suser(p) ) {
+		 cap_check(NULL, p, CAP_NET_BIND_SERVICE, 0) ) {
 		return( EACCES );
+		suser_used(p);
 	    }
 	}
     } else {
Index: sys/netatm/atm_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netatm/atm_usrreq.c,v
retrieving revision 1.11
diff -u -r1.11 atm_usrreq.c
--- sys/netatm/atm_usrreq.c	2000/12/07 22:19:04	1.11
+++ sys/netatm/atm_usrreq.c	2000/12/13 05:38:20
@@ -192,8 +192,11 @@
 		struct atmcfgreq	*acp = (struct atmcfgreq *)data;
 		struct atm_pif		*pip;
 
-		if (p && (suser(p) != 0))
-			ATM_RETERR(EPERM);
+		if (p) {
+			if ((err = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				ATM_RETERR(err);
+			suser_used(p);
+		}
 
 		switch (acp->acr_opcode) {
 
@@ -225,8 +228,11 @@
 		struct atmaddreq	*aap = (struct atmaddreq *)data;
 		Atm_endpoint		*epp;
 
-		if (p && (suser(p) != 0))
-			ATM_RETERR(EPERM);
+		if (p) {
+			if ((err = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				ATM_RETERR(err);
+			suser_used(p);
+		}
 
 		switch (aap->aar_opcode) {
 
@@ -275,8 +281,11 @@
 		struct sigmgr		*smp;
 		Atm_endpoint		*epp;
 
-		if (p && (suser(p) != 0))
-			ATM_RETERR(EPERM);
+		if (p) {
+			if ((err = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				ATM_RETERR(err);
+			suser_used(p);
+		}
 
 		switch (adp->adr_opcode) {
 
@@ -328,8 +337,11 @@
 		struct sigmgr		*smp;
 		struct ifnet		*ifp2;
 
-		if (p && (suser(p) != 0))
-			ATM_RETERR(EPERM);
+		if (p) {
+			if ((err = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				ATM_RETERR(err);
+			suser_used(p);
+		}
 
 		switch (asp->asr_opcode) {
 
Index: sys/netgraph/ng_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/netgraph/ng_socket.c,v
retrieving revision 1.20
diff -u -r1.20 ng_socket.c
--- sys/netgraph/ng_socket.c	2000/12/18 20:03:32	1.20
+++ sys/netgraph/ng_socket.c	2001/01/05 17:42:19
@@ -157,9 +157,11 @@
 ngc_attach(struct socket *so, int proto, struct proc *p)
 {
 	struct ngpcb *const pcbp = sotongpcb(so);
+	int	error;
 
-	if (suser(p))
-		return (EPERM);
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+		return (error);
+	suser_used(p);
 	if (pcbp != NULL)
 		return (EISCONN);
 	return (ng_attach_cntl(so));
Index: sys/netgraph/ng_tty.c
===================================================================
RCS file: /home/ncvs/src/sys/netgraph/ng_tty.c,v
retrieving revision 1.16
diff -u -r1.16 ng_tty.c
--- sys/netgraph/ng_tty.c	2000/12/18 20:03:32	1.16
+++ sys/netgraph/ng_tty.c	2001/01/05 17:42:19
@@ -195,8 +195,10 @@
 	int s, error;
 
 	/* Super-user only */
-	if ((error = suser(p)))
+	/* XXX perhaps this should be CAP_SYS_TTY_CONFIG? */
+	if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
 		return (error);
+	suser_used(p);
 	s = splnet();
 	(void) spltty();	/* XXX is this necessary? */
 
Index: sys/netinet/in.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.c,v
retrieving revision 1.48
diff -u -r1.48 in.c
--- sys/netinet/in.c	2000/12/08 21:50:46	1.48
+++ sys/netinet/in.c	2000/12/13 05:38:27
@@ -207,9 +207,12 @@
                 switch (cmd) {
                 case SIOCSIFPHYADDR:
 		case SIOCDIFPHYADDR:
-			if (p &&
-			    (error = suser(p)) != 0)
-        			return(error);
+			if (p) {
+				if ((error = cap_check(NULL, p, CAP_NET_ADMIN,
+				    0)) != 0)
+        				return(error);
+				suser_used(p);
+			}
                 case SIOCGIFPSRCADDR:
                 case SIOCGIFPDSTADDR:
                         return gif_ioctl(ifp, cmd, data);
@@ -220,8 +223,11 @@
 	switch (cmd) {
 	case SIOCALIFADDR:
 	case SIOCDLIFADDR:
-		if (p && (error = suser(p)) != 0)
-			return error;
+		if (p) {
+			if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				return error;
+			suser_used(p);
+		}
 		/*fall through*/
 	case SIOCGLIFADDR:
 		if (!ifp)
@@ -276,8 +282,11 @@
 	case SIOCSIFADDR:
 	case SIOCSIFNETMASK:
 	case SIOCSIFDSTADDR:
-		if (p && (error = suser(p)) != 0)
-			return error;
+		if (p) {
+			if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				return error;
+			suser_used(p);
+		}
 
 		if (ifp == 0)
 			return (EADDRNOTAVAIL);
@@ -312,8 +321,11 @@
 		break;
 
 	case SIOCSIFBRDADDR:
-		if (p && (error = suser(p)) != 0)
-			return error;
+		if (p) {
+			if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+				return error;
+			suser_used(p);
+		}
 		/* FALLTHROUGH */
 
 	case SIOCGIFADDR:
Index: sys/netinet/in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.71
diff -u -r1.71 in_pcb.c
--- sys/netinet/in_pcb.c	2000/12/27 03:02:29	1.71
+++ sys/netinet/in_pcb.c	2001/01/05 17:42:20
@@ -49,6 +49,7 @@
 #include <sys/jail.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
+#include <sys/capability.h>
 
 #include <machine/limits.h>
 
@@ -221,9 +222,12 @@
 			struct inpcb *t;
 
 			/* GROSS */
-			if (ntohs(lport) < IPPORT_RESERVED && p &&
-			    suser_xxx(0, p, PRISON_ROOT))
-				return (EACCES);
+			if (ntohs(lport) < IPPORT_RESERVED && p) {
+				if (cap_check(NULL, p, CAP_NET_BIND_SERVICE,
+				    PRISON_ROOT))
+					return (EACCES);
+				suser_used(p);
+			}
 			if (p && p->p_prison)
 				prison = 1;
 			if (so->so_cred->cr_uid != 0 &&
@@ -283,8 +287,12 @@
 			last  = ipport_hilastauto;
 			lastport = &pcbinfo->lasthi;
 		} else if (inp->inp_flags & INP_LOWPORT) {
-			if (p && (error = suser_xxx(0, p, PRISON_ROOT)))
-				return error;
+			if (p) {
+				if ((error = cap_check(NULL, p,
+				    CAP_NET_BIND_SERVICE, PRISON_ROOT)))
+					return error;
+				suser_used(p);
+			}
 			first = ipport_lowfirstauto;	/* 1023 */
 			last  = ipport_lowlastauto;	/* 600 */
 			lastport = &pcbinfo->lastlow;
Index: sys/netinet/ip_divert.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.48
diff -u -r1.48 ip_divert.c
--- sys/netinet/ip_divert.c	2000/10/29 16:06:47	1.48
+++ sys/netinet/ip_divert.c	2000/11/07 02:46:01
@@ -344,8 +344,11 @@
 	inp  = sotoinpcb(so);
 	if (inp)
 		panic("div_attach");
-	if (p && (error = suser(p)) != 0)
-		return error;
+	if (p) {
+		if ((error = cap_check(NULL, p, CAP_NET_RAW, 0)) != 0)
+			return error;
+		suser_used(p);
+	}
 
 	error = soreserve(so, div_sendspace, div_recvspace);
 	if (error)
Index: sys/netinet/ip_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.117
diff -u -r1.117 ip_output.c
--- sys/netinet/ip_output.c	2000/12/21 21:44:01	1.117
+++ sys/netinet/ip_output.c	2001/01/05 17:42:21
@@ -1231,8 +1231,14 @@
 				break;
 			if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
 				break;
-			priv = (sopt->sopt_p != NULL &&
-				suser(sopt->sopt_p) != 0) ? 0 : 1;
+			if (sopt->sopt_p != NULL) {
+				if (cap_check(sopt->sopt_p, CAP_NET_ADMIN))
+					priv = 0;
+				else {
+					priv = 1;
+					suser_used(sopt->sopt_p);
+				}
+			}
 			req = mtod(m, caddr_t);
 			len = m->m_len;
 			optname = sopt->sopt_name;
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.72
diff -u -r1.72 raw_ip.c
--- sys/netinet/raw_ip.c	2000/12/21 21:44:02	1.72
+++ sys/netinet/raw_ip.c	2001/01/05 17:42:22
@@ -46,6 +46,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
+#include <sys/capability.h>
 
 #include <vm/vm_zone.h>
 
@@ -444,8 +445,11 @@
 	inp = sotoinpcb(so);
 	if (inp)
 		panic("rip_attach");
-	if (p && (error = suser(p)) != 0)
-		return error;
+	if (p) {
+		if ((error = cap_check(NULL, p, CAP_NET_RAW, 0)) != 0)
+			return error;
+		suser_used(p);
+	}
 
 	error = soreserve(so, rip_sendspace, rip_recvspace);
 	if (error)
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.86
diff -u -r1.86 tcp_subr.c
--- sys/netinet/tcp_subr.c	2000/12/24 10:57:21	1.86
+++ sys/netinet/tcp_subr.c	2001/01/05 17:42:22
@@ -897,9 +897,11 @@
 	struct inpcb *inp;
 	int error, s;
 
-	error = suser(req->p);
+	/* XXX Why bother check for privilege here? */
+	error = cap_check(NULL, req->p, CAP_SYS_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(req->p);
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
@@ -927,9 +929,11 @@
 	struct inpcb *inp;
 	int error, s, mapped = 0;
 
-	error = suser(req->p);
+	/* XXX Why bother check for privilege here? */
+	error = cap_check(NULL, req->p, CAP_SYS_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(req->p);
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.80
diff -u -r1.80 udp_usrreq.c
--- sys/netinet/udp_usrreq.c	2000/12/24 10:57:21	1.80
+++ sys/netinet/udp_usrreq.c	2001/01/05 17:42:22
@@ -610,9 +610,10 @@
 	struct inpcb *inp;
 	int error, s;
 
-	error = suser(req->p);
+	error = cap_check(NULL, req->p, CAP_SYS_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(req->p);
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
 		return (error);
Index: sys/netinet6/in6.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6.c,v
retrieving revision 1.10
diff -u -r1.10 in6.c
--- sys/netinet6/in6.c	2000/07/12 05:20:41	1.10
+++ sys/netinet6/in6.c	2000/09/17 15:14:47
@@ -337,7 +337,7 @@
 	int privileged;
 
 	privileged = 0;
-	if (p == NULL || !suser(p))
+	if (p == NULL || !cap_check(NULL, p, CAP_NET_ADMIN, 0))
 		privileged++;
 
 	/*
@@ -349,6 +349,8 @@
 		case SIOCSIFPHYADDR_IN6:
 			if (!privileged)
 				return(EPERM);
+			if (p)
+				suser_used(p);
 			/*fall through*/
 		case SIOCGIFPSRCADDR_IN6:
 		case SIOCGIFPDSTADDR_IN6:
@@ -373,6 +375,8 @@
 	case SIOCSIFINFO_FLAGS:
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		/*fall through*/
 	case SIOCGIFINFO_IN6:
 	case SIOCGDRLST_IN6:
@@ -390,6 +394,8 @@
 	case SIOCSGIFPREFIX_IN6:
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		/*fall through*/
 	case SIOCGIFPREFIX_IN6:
 		if (ip6_forwarding == 0)
@@ -401,6 +407,8 @@
 	case SIOCSSCOPE6:
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		return(scope6_set(ifp, ifr->ifr_ifru.ifru_scope_id));
 		break;
 	case SIOCGSCOPE6:
@@ -416,6 +424,8 @@
 	case SIOCDLIFADDR:
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		/*fall through*/
 	case SIOCGLIFADDR:
 		return in6_lifaddr_ioctl(so, cmd, data, ifp, p);
@@ -475,6 +485,8 @@
 			return(EAFNOSUPPORT);
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		if (ia == NULL) {
 			ia = (struct in6_ifaddr *)
 				malloc(sizeof(*ia), M_IFADDR, M_WAITOK);
@@ -553,6 +565,8 @@
 
 		if (!privileged)
 			return(EPERM);
+		if (p)
+			suser_used(p);
 		if (ia == NULL)
 			return(EADDRNOTAVAIL);
 		/* sanity for overflow - beware unsigned */
Index: sys/netinet6/in6_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6_pcb.c,v
retrieving revision 1.13
diff -u -r1.13 in6_pcb.c
--- sys/netinet6/in6_pcb.c	2000/07/04 16:35:09	1.13
+++ sys/netinet6/in6_pcb.c	2000/09/17 15:15:16
@@ -177,10 +177,15 @@
 			struct inpcb *t;
 
 			/* GROSS */
-			if (ntohs(lport) < IPV6PORT_RESERVED && p &&
-			    suser_xxx(0, p, PRISON_ROOT))
-				return(EACCES);
-			if (so->so_cred->cr_uid != 0 &&
+			if (ntohs(lport) < IPV6PORT_RESERVED && p) {
+				if (cap_check(NULL, p, CAP_NET_BIND_SERVICE,
+				    PRISON_ROOT))
+					return(EACCES);
+				suser_used(p);
+			}
+			/* XXX setting suser_used() in this check is hard */
+			if (cap_check(so->so_cred, NULL, CAP_NET_ADMIN,
+			    PRISON_ROOT) &&
 			    !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
 				t = in6_pcblookup_local(pcbinfo,
 				    &sin6->sin6_addr, lport,
Index: sys/netinet6/in6_src.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6_src.c,v
retrieving revision 1.2
diff -u -r1.2 in6_src.c
--- sys/netinet6/in6_src.c	2000/10/29 16:06:48	1.2
+++ sys/netinet6/in6_src.c	2000/11/07 02:46:12
@@ -345,8 +345,12 @@
 		last  = ipport_hilastauto;
 		lastport = &pcbinfo->lasthi;
 	} else if (inp->inp_flags & INP_LOWPORT) {
-		if (p && (error = suser(p)))
-			return error;
+		if (p) {
+			if ((error = cap_check(NULL, p, CAP_NET_BIND_SERVICE,
+			    0)) != 0)
+				return error;
+			suser_used(p);
+		}
 		first = ipport_lowfirstauto;	/* 1023 */
 		last  = ipport_lowlastauto;	/* 600 */
 		lastport = &pcbinfo->lastlow;
Index: sys/netinet6/ip6_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.19
diff -u -r1.19 ip6_input.c
--- sys/netinet6/ip6_input.c	2000/11/25 07:35:34	1.19
+++ sys/netinet6/ip6_input.c	2000/12/13 05:38:30
@@ -940,7 +940,7 @@
 	int privileged;
 
 	privileged = 0;
-	if (p && !suser(p))
+	if (p && !cap_check(NULL, p, CAP_NET_ADMIN, 0))
 		privileged++;
 
 	if (in6p->in6p_socket->so_options & SO_TIMESTAMP) {
@@ -1005,6 +1005,7 @@
 			struct ip6_hbh *hbh;
 			int hbhlen;
 
+			suser_used(p);
 #ifndef PULLDOWN_TEST
 			hbh = (struct ip6_hbh *)(ip6 + 1);
 			hbhlen = (hbh->ip6h_len + 1) << 3;
@@ -1089,6 +1090,7 @@
 				  */
 				 if (!privileged)
 					 break;
+				suser_used(p);
 
 				 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
 						       IPV6_DSTOPTS,
Index: sys/netinet6/ip6_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.22
diff -u -r1.22 ip6_output.c
--- sys/netinet6/ip6_output.c	2000/12/21 21:44:10	1.22
+++ sys/netinet6/ip6_output.c	2001/01/05 17:42:24
@@ -1223,7 +1223,8 @@
 	}
 	error = optval = 0;
 
-	privileged = (p == 0 || suser(p)) ? 0 : 1;
+	/* XXX Should this be CAP_NET_ADMIN or CAP_NET_RAW? */
+	privileged = (p == 0 || cap_check(NULL, p, CAP_NET_ADMIN, 0)) ? 0 : 1;
 
 	if (level == IPPROTO_IPV6) {
 		switch (op) {
@@ -1248,6 +1249,7 @@
 					error = EPERM;
 					break;
 				}
+				suser_used(p);
 				/* fall through */
 			case IPV6_UNICAST_HOPS:
 			case IPV6_PKTINFO:
@@ -1388,6 +1390,7 @@
 					req = mtod(m, caddr_t);
 					len = m->m_len;
 				}
+				/* XXX can't set suser_used here */
 				error = ipsec6_set_policy(in6p, optname, req,
 				                          len, privileged);
 				m_freem(m);
@@ -1439,6 +1442,7 @@
 					error = EPERM;
 					break;
 				}
+				suser_used(p);
 				/* fall through */
 			case IPV6_UNICAST_HOPS:
 			case IPV6_PKTINFO:
@@ -1614,7 +1618,8 @@
 	}
 
 	/*  set options specified by user. */
-	if (p && !suser(p))
+	/* XXX Should this be CAP_NET_ADMIN or CAP_NET_RAW? */
+	if (p && !cap_check(NULL, p, CAP_NET_ADMIN, 0))
 		priv = 1;
 	if ((error = ip6_setpktoptions(m, opt, priv)) != 0) {
 		(void)m_free(m);
@@ -1732,11 +1737,12 @@
 			 * all multicast addresses. Only super user is allowed
 			 * to do this.
 			 */
-			if (suser(p))
+			if (cap_check(NULL, p, CAP_NET_BIND_SERVICE, 0))
 			{
 				error = EACCES;
 				break;
 			}
+			suser_used(p);
 		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
 			error = EINVAL;
 			break;
@@ -1839,10 +1845,11 @@
 		}
 		mreq = mtod(m, struct ipv6_mreq *);
 		if (IN6_IS_ADDR_UNSPECIFIED(&mreq->ipv6mr_multiaddr)) {
-			if (suser(p)) {
+			if (cap_check(NULL, p, CAP_NET_BIND_SERVICE, 0)) {
 				error = EACCES;
 				break;
 			}
+			suser_used(p);
 		} else if (!IN6_IS_ADDR_MULTICAST(&mreq->ipv6mr_multiaddr)) {
 			error = EINVAL;
 			break;
Index: sys/netinet6/raw_ip6.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.10
diff -u -r1.10 raw_ip6.c
--- sys/netinet6/raw_ip6.c	2000/12/21 21:44:10	1.10
+++ sys/netinet6/raw_ip6.c	2001/01/05 17:42:24
@@ -525,8 +525,11 @@
 	inp = sotoinpcb(so);
 	if (inp)
 		panic("rip6_attach");
-	if (p && (error = suser(p)) != 0)
-		return error;
+	if (p) {
+		if ((error = cap_check(NULL, p, CAP_NET_RAW, 0)) != 0)
+			return error;
+		suser_used(p);
+	}
 
 	error = soreserve(so, rip_sendspace, rip_recvspace);
 	if (error)
Index: sys/netinet6/udp6_output.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.2
diff -u -r1.2 udp6_output.c
--- sys/netinet6/udp6_output.c	2000/10/29 16:06:49	1.2
+++ sys/netinet6/udp6_output.c	2000/11/07 02:46:17
@@ -140,7 +140,8 @@
 	struct sockaddr_in6 tmp;
 
 	priv = 0;
-	if (p && !suser(p))
+	/* XXX Should this be CAP_NET_ADMIN or CAP_NET_RAW? */
+	if (p && !cap_check(NULL, p, CAP_NET_ADMIN, 0))
 		priv = 1;
 	if (control) {
 		if ((error = ip6_setpktoptions(control, &opt, priv)) != 0)
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.13
diff -u -r1.13 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c	2000/10/23 07:11:01	1.13
+++ sys/netinet6/udp6_usrreq.c	2000/11/07 02:46:17
@@ -478,9 +478,11 @@
 	struct inpcb *inp;
 	int error, s;
 
-	error = suser(req->p);
+	/* XXX Should this be CAP_NET_ADMIN or CAP_NET_RAW? */
+	error = cap_check(NULL, req->p, CAP_NET_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(req->p);
 
 	if (req->newlen != sizeof(addrs))
 		return (EINVAL);
Index: sys/netipx/ipx.c
===================================================================
RCS file: /home/ncvs/src/sys/netipx/ipx.c,v
retrieving revision 1.19
diff -u -r1.19 ipx.c
--- sys/netipx/ipx.c	2000/12/08 21:50:49	1.19
+++ sys/netipx/ipx.c	2000/12/13 05:38:32
@@ -108,8 +108,11 @@
 		return (0);
 	}
 
-	if (p && (error = suser(p)) != 0)
-		return (error);
+	if (p) {
+		if ((error = cap_check(NULL, p, CAP_NET_ADMIN, 0)) != 0)
+			return (error);
+		suser_used(p);
+	}
 
 	switch (cmd) {
 	case SIOCAIFADDR:
Index: sys/netipx/ipx_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netipx/ipx_pcb.c,v
retrieving revision 1.20
diff -u -r1.20 ipx_pcb.c
--- sys/netipx/ipx_pcb.c	2000/12/08 21:50:49	1.20
+++ sys/netipx/ipx_pcb.c	2000/12/13 05:40:34
@@ -98,9 +98,12 @@
 		u_short aport = ntohs(lport);
 		int error;
 
-		if (aport < IPXPORT_RESERVED &&
-		    p != NULL && (error = suser(p)) != 0)
-			return (error);
+		if (aport < IPXPORT_RESERVED && p != NULL) {
+			if ((error = cap_check(NULL, p, CAP_NET_BIND_SERVICE,
+			    0)) != 0)
+				return (error);
+			suser_used(p);
+		}
 		if (ipx_pcblookup(&zeroipx_addr, lport, 0))
 			return (EADDRINUSE);
 	}
Index: sys/netipx/ipx_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netipx/ipx_usrreq.c,v
retrieving revision 1.27
diff -u -r1.27 ipx_usrreq.c
--- sys/netipx/ipx_usrreq.c	2000/10/29 16:06:50	1.27
+++ sys/netipx/ipx_usrreq.c	2000/11/07 02:46:19
@@ -602,8 +602,11 @@
 	int s;
 	struct ipxpcb *ipxp = sotoipxpcb(so);
 
-	if (p != NULL && (error = suser(p)) != 0)
-		return (error);
+	if (p != NULL) {
+		if ((error = cap_check(NULL, p, CAP_NET_RAW, 0)) != 0)
+			return (error);
+		suser_used(error);
+	}
 	s = splnet();
 	error = ipx_pcballoc(so, &ipxrawpcb, p);
 	splx(s);
Index: sys/nfs/nfs_serv.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_serv.c,v
retrieving revision 1.98
diff -u -r1.98 nfs_serv.c
--- sys/nfs/nfs_serv.c	2000/12/21 21:44:24	1.98
+++ sys/nfs/nfs_serv.c	2001/01/05 17:42:28
@@ -1788,11 +1788,13 @@
 			/*
 			 * Handle SysV FIFO node special cases.  All other
 			 * devices require super user to access.
+			 *
+			 * XXX CAP_MKNOD seems to be the closest match.
 			 */
 			if (vap->va_type == VCHR && rdev == 0xffffffff)
 				vap->va_type = VFIFO;
                         if (vap->va_type != VFIFO &&
-                            (error = suser_xxx(cred, 0, 0))) {
+                            (error = cap_check(cred, NULL, CAP_MKNOD, 0))) {
 				goto nfsmreply0;
                         }
 			vap->va_rdev = rdev;
@@ -2004,7 +2006,10 @@
 		if (error)
 			NDFREE(&nd, NDF_ONLY_PNBUF);
 	} else {
-		if (vtyp != VFIFO && (error = suser_xxx(cred, 0, 0)))
+		/*
+		 * XXX CAP_MKNOD seems to be the closest match?
+		 */
+		if (vtyp != VFIFO && (error = cap_check(cred, NULL, CAP_MKNOD,			    0)))
 			goto out;
 		nqsrv_getl(nd.ni_dvp, ND_WRITE);
 
Index: sys/nfs/nfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_syscalls.c,v
retrieving revision 1.64
diff -u -r1.64 nfs_syscalls.c
--- sys/nfs/nfs_syscalls.c	2000/12/21 21:44:24	1.64
+++ sys/nfs/nfs_syscalls.c	2001/01/05 17:42:29
@@ -154,10 +154,12 @@
 
 	/*
 	 * Must be super user
+	 * XXX CAP_SYS_ADMIN seems to be a catch all, is it right?
 	 */
-	error = suser(p);
+	error = cap_check(NULL, p, CAP_SYS_ADMIN, 0);
 	if(error)
 		return (error);
+	suser_used(p);
 	while (nfssvc_sockhead_flag & SLP_INIT) {
 		 nfssvc_sockhead_flag |= SLP_WANTINIT;
 		(void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0);
Index: sys/pccard/pccard.c
===================================================================
RCS file: /home/ncvs/src/sys/pccard/pccard.c,v
retrieving revision 1.115
diff -u -r1.115 pccard.c
--- sys/pccard/pccard.c	2000/10/29 16:29:05	1.115
+++ sys/pccard/pccard.c	2000/11/07 02:46:52
@@ -507,8 +507,9 @@
 	 * At the very least, we only allow root to set the context.
 	 */
 	case PIOCSMEM:
-		if (suser(p))
-			return(EPERM);
+		if ((err = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return(err);
+		suser_used(p);
 		if (slt->state != filled)
 			return(ENXIO);
 		s = ((struct mem_desc *)data)->window;
@@ -532,8 +533,9 @@
 	 * Set I/O port context.
 	 */
 	case PIOCSIO:
-		if (suser(p))
-			return(EPERM);
+		if ((err = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return(err);
+		suser_used(p);
 		if (slt->state != filled)
 			return(ENXIO);
 		s = ((struct io_desc *)data)->window;
@@ -560,8 +562,9 @@
 				*(unsigned long *)data = pccard_mem;
 			break;
 		}
-		if (suser(p))
-			return(EPERM);
+		if ((err = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return(err);
+		suser_used(p);
 		/*
 		 * Validate the memory by checking it against the I/O
 		 * memory range. It must also start on an aligned block size.
@@ -589,8 +592,9 @@
 	 * Allocate a driver to this slot.
 	 */
 	case PIOCSDRV:
-		if (suser(p))
-			return(EPERM);
+		if ((err = cap_check(NULL, p, CAP_SYS_ADMIN, 0)) != 0)
+			return(err);
+		suser_used(p);
 		err = allocate_driver(slt, (struct dev_desc *)data);
 		if (!err)
 			pccard_success_beep();
Index: sys/sys/mount.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/mount.h,v
retrieving revision 1.99
diff -u -r1.99 mount.h
--- sys/sys/mount.h	2000/12/04 09:21:05	1.99
+++ sys/sys/mount.h	2000/12/13 05:40:51
@@ -37,6 +37,7 @@
 #ifndef _SYS_MOUNT_H_
 #define _SYS_MOUNT_H_
 
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/queue.h>
 #ifdef _KERNEL
Index: sys/sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.137
diff -u -r1.137 proc.h
--- sys/sys/proc.h	2000/12/23 19:43:10	1.137
+++ sys/sys/proc.h	2001/01/05 17:42:40
@@ -52,6 +52,7 @@
 #ifndef _KERNEL
 #include <sys/time.h>			/* For structs itimerval, timeval. */
 #endif
+#include <sys/capability.h>
 #include <sys/ucred.h>
 
 /*
@@ -333,6 +334,7 @@
 	uid_t	p_svuid;		/* Saved effective user id. */
 	gid_t	p_rgid;			/* Real group id. */
 	gid_t	p_svgid;		/* Saved effective group id. */
+	struct cap	p_cap;		/* Capabilities */
 	int	p_refcnt;		/* Number of references. */
 	struct	uidinfo *p_uidinfo;	/* Per uid resource consumption. */
 };
Index: sys/sys/sysctl.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/sysctl.h,v
retrieving revision 1.88
diff -u -r1.88 sysctl.h
--- sys/sys/sysctl.h	2001/01/05 07:00:45	1.88
+++ sys/sys/sysctl.h	2001/01/05 17:42:41
@@ -328,7 +328,7 @@
 #define	KERN_PS_STRINGS		32	/* int: address of PS_STRINGS */
 #define	KERN_USRSTACK		33	/* int: address of USRSTACK */
 #define	KERN_LOGSIGEXIT		34	/* int: do we log sigexit procs? */
-#define KERN_MAXID		35      /* number of valid kern ids */
+#define KERN_MAXID		35	/* number of valid kern ids */
 
 #define CTL_KERN_NAMES { \
 	{ 0, 0 }, \
Index: sys/sys/systm.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/systm.h,v
retrieving revision 1.131
diff -u -r1.131 systm.h
--- sys/sys/systm.h	2000/12/20 21:50:34	1.131
+++ sys/sys/systm.h	2001/01/05 17:42:41
@@ -47,6 +47,7 @@
 #include <sys/callout.h>
 
 extern int securelevel;		/* system security level (see init(8)) */
+extern int suser_permitted;	/* suser_xxx() is permitted to return 0 */
 
 extern int cold;		/* nonzero if we are doing a cold boot */
 extern const char *panicstr;	/* panic message */
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	2000/12/13 05:40:53
@@ -50,6 +50,7 @@
 	uid_t	cr_uid;			/* effective user id */
 	short	cr_ngroups;		/* number of groups */
 	gid_t	cr_groups[NGROUPS];	/* groups */
+	struct cap	cr_cap;		/* capabilities */
 	struct	uidinfo *cr_uidinfo;	/* per uid resource consumption */
 	struct	mtx cr_mtx;		/* protect refcount */
 };
Index: sys/sys/user.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/user.h,v
retrieving revision 1.26
diff -u -r1.26 user.h
--- sys/sys/user.h	2000/12/12 07:25:54	1.26
+++ sys/sys/user.h	2000/12/13 05:40:53
@@ -43,6 +43,7 @@
 #include <sys/errno.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/uio.h>
 #include <sys/proc.h>
Index: sys/sys/vnode.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/vnode.h,v
retrieving revision 1.134
diff -u -r1.134 vnode.h
--- sys/sys/vnode.h	2000/12/26 19:41:37	1.134
+++ sys/sys/vnode.h	2001/01/05 17:42:42
@@ -532,6 +532,7 @@
 struct proc;
 struct stat;
 struct nstat;
+struct cap;
 struct ucred;
 struct uio;
 struct vattr;
Index: sys/ufs/ufs/ufs_extattr.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_extattr.c,v
retrieving revision 1.15
diff -u -r1.15 ufs_extattr.c
--- sys/ufs/ufs/ufs_extattr.c	2000/10/09 20:04:39	1.15
+++ sys/ufs/ufs/ufs_extattr.c	2000/10/11 17:49:26
@@ -367,8 +367,9 @@
 	 * Processes with privilege, but in jail, are not allowed to
 	 * configure extended attributes.
 	 */
-	if ((error = suser_xxx(p->p_cred->pc_ucred, p, 0)))
+	if ((error = cap_check(p->p_cred->pc_ucred, p, CAP_SYS_ADMIN, 0)))
 		return (error);
+	suser_used(p);
 
 	switch(cmd) {
 	case UFS_EXTATTR_CMD_START:
@@ -424,13 +425,16 @@
 ufs_extattr_credcheck(struct vnode *vp, struct ufs_extattr_list_entry *uele,
     struct ucred *cred, struct proc *p, int access)
 {
-	int	system_namespace;
+	int	system_namespace, error;
 
 	system_namespace = (strlen(uele->uele_attrname) >= 1 &&
 	    uele->uele_attrname[0] == '$');
 
 	/*
-	 * Kernel-invoked always succeeds
+	 * Kernel-invoked always succeeds.
+	 *
+	 * XXX: Is this correct?  Might be appropriate to check also
+	 * whether the inode is immutable, et al.
 	 */
 	if (cred == NULL)
 		return (0);
@@ -442,9 +446,12 @@
 	 * XXX What capability should apply here?
 	 * Probably CAP_SYS_SETFFLAG.
 	 */
-	if (system_namespace)
-		return (suser_xxx(cred, p, 0));
-	else
+	if (system_namespace) {
+		if ((error = cap_check(cred, p, CAP_SYS_ADMIN, 0)))
+			return (error);
+		suser_used(p);
+		return (0);
+	} else
 		return (VOP_ACCESS(vp, access, cred, p));
 }
 
Index: sys/ufs/ufs/ufs_readwrite.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_readwrite.c,v
retrieving revision 1.73
diff -u -r1.73 ufs_readwrite.c
--- sys/ufs/ufs/ufs_readwrite.c	2000/12/26 19:41:37	1.73
+++ sys/ufs/ufs/ufs_readwrite.c	2001/01/05 17:42:45
@@ -530,7 +530,7 @@
 	 * tampering.
 	 */
 	if (resid > uio->uio_resid && ap->a_cred && 
-	    suser_xxx(ap->a_cred, NULL, PRISON_ROOT))
+	    cap_check(ap->a_cred, NULL, CAP_FSETID, PRISON_ROOT))
 		ip->i_mode &= ~(ISUID | ISGID);
 	if (resid > uio->uio_resid)
 		VN_KNOTE(vp, NOTE_WRITE | (extended ? NOTE_EXTEND : 0));
Index: sys/ufs/ufs/ufs_vfsops.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vfsops.c,v
retrieving revision 1.20
diff -u -r1.20 ufs_vfsops.c
--- sys/ufs/ufs/ufs_vfsops.c	2000/10/30 20:37:19	1.20
+++ sys/ufs/ufs/ufs_vfsops.c	2000/11/07 02:47:26
@@ -103,7 +103,7 @@
 #ifndef QUOTA
 	return (EOPNOTSUPP);
 #else
-	int cmd, type, error;
+	int cmd, type, error, privilege_used = 0;
 
 	if (uid == -1)
 		uid = p->p_cred->p_ruid;
@@ -117,8 +117,9 @@
 			break;
 		/* fall through */
 	default:
-		if ((error = suser_xxx(0, p, PRISON_ROOT)) != 0)
+		if ((error = cap_check(NULL, p, CAP_SYS_ADMIN, PRISON_ROOT)))
 			return (error);
+		privilege_used = 1;
 	}
 
 	type = cmds & SUBCMDMASK;
@@ -158,6 +159,8 @@
 		break;
 	}
 	vfs_unbusy(mp, p);
+	if (error == 0 && privilege_used)
+		suser_used(p);
 	return (error);
 #endif
 }
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.154
diff -u -r1.154 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c	2000/11/04 08:10:56	1.154
+++ sys/ufs/ufs/ufs_vnops.c	2001/01/07 17:22:45
@@ -58,6 +58,7 @@
 #include <sys/lockf.h>
 #include <sys/event.h>
 #include <sys/conf.h>
+#include <sys/capability.h>
 
 #include <machine/mutex.h>
 
@@ -303,9 +304,7 @@
 	struct vnode *vp = ap->a_vp;
 	struct inode *ip = VTOI(vp);
 	mode_t mode = ap->a_mode;
-#ifdef QUOTA
-	int error;
-#endif
+	int error, privused;
 
 	/*
 	 * Disallow write attempts on read-only file systems;
@@ -332,9 +331,16 @@
 	/* If immutable bit set, nobody gets to write it. */
 	if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT)))
 		return (EPERM);
+
+	privused = 0;
+	error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
+	    ap->a_mode, ap->a_cred, &privused);
+	if (error)
+		return (error);
+	if (privused)
+		suser_used(ap->a_p);
 
-	return (vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
-	    ap->a_mode, ap->a_cred, NULL));
+	return (0);
 }
 
 /* ARGSUSED */
@@ -396,7 +402,7 @@
 	struct inode *ip = VTOI(vp);
 	struct ucred *cred = ap->a_cred;
 	struct proc *p = ap->a_p;
-	int error;
+	int error, privilege_used = 0;
 
 	/*
 	 * Check for unsettable attributes.
@@ -413,16 +419,21 @@
 		/*
 		 * Callers may only modify the file flags on objects they
 		 * have VADMIN rights for.
+		 *
+		 * XXX: This abstracts use of privilege, and may not
+		 * account for it properly.
 		 */
 		if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
 			return (error);
+
 		/*
 		 * Unprivileged processes and privileged processes in
 		 * jail() are not permitted to set system flags.
 		 * Privileged processes not in jail() may only set system
 		 * flags if the securelevel <= 0.
 		 */
-		if (!suser_xxx(cred, NULL, 0)) {
+		if (!cap_check(cred, p, CAP_SYS_SETFFLAG, 0)) {
+			privilege_used = 1;
 			if ((ip->i_flags
 			    & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) &&
 			    securelevel > 0)
@@ -443,8 +454,11 @@
 			ip->i_flags |= (vap->va_flags & UF_SETTABLE);
 		}
 		ip->i_flag |= IN_CHANGE;
-		if (vap->va_flags & (IMMUTABLE | APPEND))
+		if (vap->va_flags & (IMMUTABLE | APPEND)) {
+			if (privilege_used)
+				suser_used(p);
 			return (0);
+		}
 	}
 	if (ip->i_flags & (IMMUTABLE | APPEND))
 		return (EPERM);
@@ -495,8 +509,12 @@
 		 */
 		if ((error = VOP_ACCESS(vp, VADMIN, cred, p)) &&
 		    ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
-		    (error = VOP_ACCESS(vp, VWRITE, cred, p))))
-			return (error);
+		    (error = VOP_ACCESS(vp, VWRITE, cred, p)))) {
+			if ((error = cap_check(cred, p, CAP_FOWNER,
+			    PRISON_ROOT)) != 0)
+				return (error);
+			privilege_used = 1;
+		}
 		if (vap->va_atime.tv_sec != VNOVAL)
 			ip->i_flag |= IN_ACCESS;
 		if (vap->va_mtime.tv_sec != VNOVAL)
@@ -524,6 +542,8 @@
 		error = ufs_chmod(vp, (int)vap->va_mode, cred, p);
 	}
 	VN_KNOTE(vp, NOTE_ATTRIB);
+	if (error == 0 && privilege_used)
+		suser_used(p);
 	return (error);
 }
 
@@ -539,28 +559,55 @@
 	struct proc *p;
 {
 	register struct inode *ip = VTOI(vp);
-	int error;
+	int error, privilege_used = 0;
 
 	/*
-	 * To modify the permissions on a file, must possess VADMIN
-	 * for that file.
+	 * In general, to modify the permissions on a file, you must posess
+	 * VADMIN for the file (by virtue of owning the file, or having
+	 * privilege such as super-user or CAP_FOWNER).  However, if the
+	 * modification involves either of the setugid bits being in the
+	 * new mode, additional checks are performed: for setuid, the
+	 * effective uid of the process must match the inode uid or
+	 * superuser/CAP_FSETID must be held, and for setgid, one of the
+	 * groups of the process must match that of the file, or supuser/
+	 * CAP_FSETID must be held.
+	 *
+	 * XXX: This diverges slightly from POSIX.1e D17 by tightening the
+	 * requirements: both CAP_FOWNER and CAP_FSETID must be held to
+	 * update sugid bits, but this divergence is portable to at least
+	 * Linux, and substantially simplifies (and makes sensical) the
+	 * interactions.
 	 */
 	if ((error = VOP_ACCESS(vp, VADMIN, cred, p)))
 		return (error);
 	/*
-	 * Privileged processes may set the sticky bit on non-directories,
-	 * as well as set the setgid bit on a file with a group that the
-	 * process is not a member of.
-	 */
-	if (suser_xxx(cred, NULL, PRISON_ROOT)) {
-		if (vp->v_type != VDIR && (mode & S_ISTXT))
-			return (EFTYPE);
-		if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
-			return (EPERM);
+	 * Traditionally, privilege has allowed a process to set the
+	 * sticky bit on non-directories.  However, this has no meaning,
+	 * so is now disabled.
+	 */
+	if (vp->v_type != VDIR && (mode & S_ISTXT))
+		return(EFTYPE);
+	/*
+	 * Privilege is required to set the setuid or setgid bits if the
+	 * process doesn't already have access to the respective uid
+	 * or gid in its credentials.
+	 * XXX: Check that uid/gid checks here fit abstractions.
+	 */
+	if ((ip->i_uid != cred->cr_uid) && (mode & ISUID)) {
+		if ((error = cap_check(cred, p, CAP_FSETID, PRISON_ROOT)) != 0)
+			return (error);
+		privilege_used = 1;
+	}
+	if (!groupmember(ip->i_gid, cred) && (mode & ISGID)) {
+		if ((error = cap_check(cred, p, CAP_FSETID, PRISON_ROOT)) != 0)
+			return (error);
+		privilege_used = 1;
 	}
 	ip->i_mode &= ~ALLPERMS;
 	ip->i_mode |= (mode & ALLPERMS);
 	ip->i_flag |= IN_CHANGE;
+	if (privilege_used)
+		suser_used(p);
 	return (0);
 }
 
@@ -579,7 +626,7 @@
 	register struct inode *ip = VTOI(vp);
 	uid_t ouid;
 	gid_t ogid;
-	int error = 0;
+	int error = 0, privilege_used = 0;
 #ifdef QUOTA
 	register int i;
 	long change;
@@ -600,10 +647,12 @@
 	 * to a group of which we are not a member, the caller must
 	 * have privilege.
 	 */
-	if ((uid != ip->i_uid || 
-	    (gid != ip->i_gid && !groupmember(gid, cred))) &&
-	    (error = suser_xxx(cred, p, PRISON_ROOT)))
-		return (error);
+	if (uid != ip->i_uid || 
+	    (gid != ip->i_gid && !groupmember(gid, cred))) {
+	    	if (error = cap_check(cred, p, CAP_CHOWN, PRISON_ROOT)))
+			return (error);
+		privilege_used = 1;
+	}
 	ogid = ip->i_gid;
 	ouid = ip->i_uid;
 #ifdef QUOTA
@@ -669,8 +718,14 @@
 		panic("ufs_chown: lost quota");
 #endif /* QUOTA */
 	ip->i_flag |= IN_CHANGE;
-	if (suser_xxx(cred, NULL, PRISON_ROOT) && (ouid != uid || ogid != gid))
-		ip->i_mode &= ~(ISUID | ISGID);
+	if (ouid != uid || ogid != gid) {
+		if (cap_check(cred, p, CAP_FSETID, PRISON_ROOT) != 0)
+			ip->i_mode &= ~(ISUID | ISGID);
+		else
+			privilege_used = 1;
+	}
+	if (privilege_used)
+		suser_used(p);
 	return (0);
 }
 
@@ -866,7 +921,7 @@
 	struct inode *ip, *xp, *dp;
 	struct direct newdir;
 	int doingdirectory = 0, oldparent = 0, newparent = 0;
-	int error = 0, ioflag;
+	int error = 0, ioflag, privilege_used = 0;
 
 #ifdef DIAGNOSTIC
 	if ((tcnp->cn_flags & HASBUF) == 0 ||
@@ -1104,6 +1159,14 @@
 		 * must possess VADMIN for the parent directory, or the
 		 * destination of the rename.  This implements append-only
 		 * directories.
+		 *
+		 * XXX: In TRIX, CAP_DAC_WRITE appears also to override the
+		 * sticky bit limitations -- should we do the same?  Such a
+		 * check would read:
+		 *	(cap_check(tcnp->cn_cred, NULL, CAP_DAC_WRITE,
+		 *	    PRISON_ROOT))
+		 * XXX: Since the introduction of VADMIN, the ability to
+		 * set privilege_used here has been lost.
 		 */
 		if ((dp->i_mode & S_ISTXT) &&
 		    VOP_ACCESS(tdvp, VADMIN, tcnp->cn_cred, p) &&
@@ -1197,6 +1260,8 @@
 		if (doingdirectory)
 			panic("ufs_rename: lost dir entry");
 		vrele(ap->a_fvp);
+		if (privilege_used)
+			suser_used(p);
 		return (0);
 	}
 	/*
@@ -1232,6 +1297,8 @@
 	if (xp)
 		vput(fvp);
 	vrele(ap->a_fvp);
+	if (error == 0 && privilege_used)
+		suser_used(p);
 	return (error);
 
 bad:
@@ -1251,6 +1318,8 @@
 		vput(fvp);
 	} else
 		vrele(fvp);
+	if (error == 0 && privilege_used)
+		suser_used(p);
 	return (error);
 }
 
@@ -2055,7 +2124,7 @@
 	register struct inode *ip, *pdir;
 	struct direct newdir;
 	struct vnode *tvp;
-	int error;
+	int error, privilege_used = 0;
 
 	pdir = VTOI(dvp);
 #ifdef DIAGNOSTIC
@@ -2133,9 +2202,12 @@
 	ip->i_nlink = 1;
 	if (DOINGSOFTDEP(tvp))
 		softdep_change_linkcnt(ip);
-	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) &&
-	    suser_xxx(cnp->cn_cred, NULL, PRISON_ROOT))
-		ip->i_mode &= ~ISGID;
+	if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred)) {
+		if (cap_check(cnp->cn_cred, NULL, CAP_FSETID, PRISON_ROOT))
+			ip->i_mode &= ~ISGID;
+		else
+			privilege_used = 1;
+	}
 
 	if (cnp->cn_flags & ISWHITEOUT)
 		ip->i_flags |= UF_OPAQUE;
@@ -2151,6 +2223,13 @@
 	if (error)
 		goto bad;
 	*vpp = tvp;
+/*
+	XXX struct proc is not passed in, so we can't mark as having used
+	    privilege
+
+	if (privilege_used)
+		suser_used(p);
+*/
 	return (0);
 
 bad:
Index: sys/vm/vm_mmap.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_mmap.c,v
retrieving revision 1.117
diff -u -r1.117 vm_mmap.c
--- sys/vm/vm_mmap.c	2000/11/18 21:01:04	1.117
+++ sys/vm/vm_mmap.c	2000/12/13 05:40:58
@@ -335,8 +335,11 @@
 			 */
 			if (securelevel >= 1)
 				disablexworkaround = 1;
-			else
-				disablexworkaround = suser(p);
+			else {
+				/* XXX How to suser_used() here? */
+				disablexworkaround = cap_check(NULL, p,
+				   CAP_SYS_RAWIO, 0);
+			}
 			if (vp->v_type == VCHR && disablexworkaround &&
 			    (flags & (MAP_PRIVATE|MAP_COPY))) {
 				error = EINVAL;
Index: sys/vm/vm_swap.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_swap.c,v
retrieving revision 1.106
diff -u -r1.106 vm_swap.c
--- sys/vm/vm_swap.c	2000/12/13 10:01:00	1.106
+++ sys/vm/vm_swap.c	2001/01/05 17:42:49
@@ -191,9 +191,10 @@
 	struct nameidata nd;
 	int error;
 
-	error = suser(p);
+	error = cap_check(NULL, p, CAP_SYS_ADMIN, 0);
 	if (error)
 		return (error);
+	suser_used(p);
 
 	/*
 	 * Swap metadata may not fit in the KVM if we have physical
Index: usr.bin/find/function.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/find/function.c,v
retrieving revision 1.27
diff -u -r1.27 function.c
--- usr.bin/find/function.c	2000/07/28 20:02:42	1.27
+++ usr.bin/find/function.c	2000/08/07 00:56:16
@@ -44,6 +44,7 @@
 #endif /* not lint */
 
 #include <sys/param.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
Index: usr.bin/kdump/Makefile
===================================================================
RCS file: /home/ncvs/src/usr.bin/kdump/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- usr.bin/kdump/Makefile	2000/09/14 18:52:48	1.7
+++ usr.bin/kdump/Makefile	2000/09/16 03:39:24
@@ -2,7 +2,7 @@
 # $FreeBSD: src/usr.bin/kdump/Makefile,v 1.7 2000/09/14 18:52:48 jkh Exp $
 
 PROG=	kdump
-CFLAGS+=-I${.CURDIR}/../ktrace -I${.CURDIR}/../..
+CFLAGS+=-I${.CURDIR}/../ktrace -I${.CURDIR}/../.. -I${.CURDIR}/../../sys
 SRCS=	kdump.c ioctl.c subr.c
 .PATH:	${.CURDIR}/../ktrace
 CLEANFILES+=ioctl.c
Index: usr.sbin/inetd/builtins.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/inetd/builtins.c,v
retrieving revision 1.29
diff -u -r1.29 builtins.c
--- usr.sbin/inetd/builtins.c	2000/12/05 13:56:01	1.29
+++ usr.sbin/inetd/builtins.c	2000/12/13 05:43:44
@@ -33,6 +33,7 @@
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/uio.h>
 #include <sys/utsname.h>
Index: usr.sbin/pstat/pstat.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/pstat/pstat.c,v
retrieving revision 1.52
diff -u -r1.52 pstat.c
--- usr.sbin/pstat/pstat.c	2000/12/30 15:41:40	1.52
+++ usr.sbin/pstat/pstat.c	2001/01/05 17:49:03
@@ -48,6 +48,7 @@
 #include <sys/param.h>
 #include <sys/time.h>
 #include <sys/vnode.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #define _KERNEL
 #include <sys/file.h>
Index: usr.sbin/rpc.umntall/rpc.umntall.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/rpc.umntall/rpc.umntall.c,v
retrieving revision 1.3
diff -u -r1.3 rpc.umntall.c
--- usr.sbin/rpc.umntall/rpc.umntall.c	2000/01/15 14:28:14	1.3
+++ usr.sbin/rpc.umntall/rpc.umntall.c	2000/04/12 20:10:46
@@ -31,6 +31,7 @@
 #endif /* not lint */
 
 #include <sys/param.h>
+#include <sys/capability.h>
 #include <sys/ucred.h>
 #include <sys/mount.h>
 
