Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 07 Feb 2001 13:28:21 -0500
From:      "Brian F. Feldman" <green@FreeBSD.org>
To:        arch@FreeBSD.org
Subject:   xucred introduction
Message-ID:  <200102071828.f17ISLr17637@green.dyndns.org>

next in thread | raw e-mail | index | archive | help
I'd like to commit this further clean-up of the kernel API in which struct 
ucred's use outside of the kernel is to be a last resort, and everything 
which would use ucred will use xucred.  This mainly affects mount(2), and 
changes the size of those structures.  However, xucred won't have to be 
changing size all the time, so this will be the last time mountd or
i(den|ne)td would panic the kernel or return an error (respectively) for 
changes to ucred.

Mike Smith would prefer it that for userland, ucred and xucred would be more 
something like the in-kernel kucred and external ucred, but I believe this 
will introduce absolutely nothing but headaches for code due to 
conditionalized structure definition upon _KERNEL being defined.  Therefore, 
I've kept ucred as the in-kernel structure for kvm-using apps, xucred for 
everything else, with unfortunately the limitation that ucred.h must still 
be treated as a kernel header and dependencies noted accordingly by the 
programmer.

I've verified this works on at least -CURRENT from the past week.  I'd like 
to commit it soon to lessen any pain from more ucred changes, like 
rwatson's.  The only question is whether or not to add some spare fields to 
xucred now in case we /do/ want to expand it in the future, and also whether 
it's appropriate to make some of the field type changes (for example, 
sockaddr length type -> u_char, since that _IS_ what is defined by the 
sockaddr interface).

Discussion please :)

Index: sbin/mountd/mountd.c
===================================================================
RCS file: /usr2/ncvs/src/sbin/mountd/mountd.c,v
retrieving revision 1.39
diff -u -r1.39 mountd.c
--- sbin/mountd/mountd.c	1999/12/03 20:23:53	1.39
+++ sbin/mountd/mountd.c	2001/01/23 00:24:24
@@ -161,9 +161,9 @@
 void	del_mlist __P((char *, char *));
 struct dirlist *dirp_search __P((struct dirlist *, char *));
 int	do_mount __P((struct exportlist *, struct grouplist *, int,
-		struct ucred *, char *, int, struct statfs *));
+		struct xucred *, char *, int, struct statfs *));
 int	do_opt __P((char **, char **, struct exportlist *, struct grouplist *,
-				int *, int *, struct ucred *));
+				int *, int *, struct xucred *));
 struct	exportlist *ex_search __P((fsid_t *));
 struct	exportlist *get_exp __P((void));
 void	free_dir __P((struct dirlist *));
@@ -184,7 +184,7 @@
 void	mntsrv __P((struct svc_req *, SVCXPRT *));
 void	nextfield __P((char **, char **));
 void	out_of_mem __P((void));
-void	parsecred __P((char *, struct ucred *));
+void	parsecred __P((char *, struct xucred *));
 int	put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *));
 int	scan_tree __P((struct dirlist *, u_int32_t));
 static void usage __P((void));
@@ -202,8 +202,7 @@
 struct mountlist *mlhead;
 struct grouplist *grphead;
 char exname[MAXPATHLEN];
-struct ucred def_anon = {
-	1,
+struct xucred def_anon = {
 	(uid_t) -2,
 	1,
 	{ (gid_t) -2 }
@@ -732,7 +731,7 @@
 	struct dirlist *dirhead;
 	struct statfs fsb, *fsp;
 	struct hostent *hpe;
-	struct ucred anon;
+	struct xucred anon;
 	char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
 	int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp;
 
@@ -1332,7 +1331,7 @@
 	struct grouplist *grp;
 	int *has_hostp;
 	int *exflagsp;
-	struct ucred *cr;
+	struct xucred *cr;
 {
 	char *cpoptarg, *cpoptend;
 	char *cp, *endcp, *cpopt, savedc, savedc2;
@@ -1591,7 +1590,7 @@
 	struct exportlist *ep;
 	struct grouplist *grp;
 	int exflags;
-	struct ucred *anoncrp;
+	struct xucred *anoncrp;
 	char *dirp;
 	int dirplen;
 	struct statfs *fsb;
@@ -1842,7 +1841,7 @@
 void
 parsecred(namelist, cr)
 	char *namelist;
-	struct ucred *cr;
+	struct xucred *cr;
 {
 	char *name;
 	int cnt;
@@ -1854,7 +1853,6 @@
 	/*
 	 * Set up the unprivileged user.
 	 */
-	cr->cr_ref = 1;
 	cr->cr_uid = -2;
 	cr->cr_groups[0] = -2;
 	cr->cr_ngroups = 1;
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /usr2/ncvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.301
diff -u -r1.301 vfs_subr.c
--- sys/kern/vfs_subr.c	2001/01/31 04:54:23	1.301
+++ sys/kern/vfs_subr.c	2001/02/01 04:14:22
@@ -2319,7 +2319,11 @@
 			return (EPERM);
 		np = &nep->ne_defexported;
 		np->netc_exflags = argp->ex_flags;
-		np->netc_anon = argp->ex_anon;
+		bzero(&np->netc_anon, sizeof(np->netc_anon));
+		np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
+		np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
+		bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
+		    sizeof(np->netc_anon.cr_groups));
 		np->netc_anon.cr_ref = 1;
 		mp->mnt_flag |= MNT_DEFEXPORTED;
 		return (0);
@@ -2363,7 +2367,11 @@
 		goto out;
 	}
 	np->netc_exflags = argp->ex_flags;
-	np->netc_anon = argp->ex_anon;
+	bzero(&np->netc_anon, sizeof(np->netc_anon));
+	np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
+	np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
+	bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
+	    sizeof(np->netc_anon.cr_groups));
 	np->netc_anon.cr_ref = 1;
 	return (0);
 out:
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /usr2/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/23 00:13:00
@@ -893,6 +893,7 @@
 static int
 tcp_getcred(SYSCTL_HANDLER_ARGS)
 {
+	struct xucred xuc;
 	struct sockaddr_in addrs[2];
 	struct inpcb *inp;
 	int error, s;
@@ -910,19 +911,25 @@
 		error = ENOENT;
 		goto out;
 	}
-	error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred));
+
+	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
+	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
+	    sizeof(xuc.cr_groups));
+	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
 out:
 	splx(s);
 	return (error);
 }
 
 SYSCTL_PROC(_net_inet_tcp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
-    0, 0, tcp_getcred, "S,ucred", "Get the ucred of a TCP connection");
+    0, 0, tcp_getcred, "S,xucred", "Get the xucred of a TCP connection");
 
 #ifdef INET6
 static int
 tcp6_getcred(SYSCTL_HANDLER_ARGS)
 {
+	struct xucred xuc;
 	struct sockaddr_in6 addrs[2];
 	struct inpcb *inp;
 	int error, s, mapped = 0;
@@ -956,8 +963,12 @@
 		error = ENOENT;
 		goto out;
 	}
-	error = SYSCTL_OUT(req, inp->inp_socket->so_cred, 
-			   sizeof(struct ucred));
+	
+	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
+	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
+	    sizeof(xuc.cr_groups));
+	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
 out:
 	splx(s);
 	return (error);
@@ -965,7 +976,7 @@
 
 SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
 	    0, 0,
-	    tcp6_getcred, "S,ucred", "Get the ucred of a TCP6 connection");
+	    tcp6_getcred, "S,xucred", "Get the xucred of a TCP6 connection");
 #endif
 
 
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /usr2/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/23 00:13:50
@@ -606,6 +606,7 @@
 static int
 udp_getcred(SYSCTL_HANDLER_ARGS)
 {
+	struct xucred xuc;
 	struct sockaddr_in addrs[2];
 	struct inpcb *inp;
 	int error, s;
@@ -623,14 +624,19 @@
 		error = ENOENT;
 		goto out;
 	}
-	error = SYSCTL_OUT(req, inp->inp_socket->so_cred, sizeof(struct ucred));
+
+	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
+	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
+	    sizeof(xuc.cr_groups));
+	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
 out:
 	splx(s);
 	return (error);
 }
 
 SYSCTL_PROC(_net_inet_udp, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
-    0, 0, udp_getcred, "S,ucred", "Get the ucred of a UDP connection");
+    0, 0, udp_getcred, "S,xucred", "Get the xucred of a UDP connection");
 
 static int
 udp_output(inp, m, addr, control, p)
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /usr2/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	2001/01/23 00:15:16
@@ -474,6 +474,7 @@
 static int
 udp6_getcred(SYSCTL_HANDLER_ARGS)
 {
+	struct xucred xuc;
 	struct sockaddr_in6 addrs[2];
 	struct inpcb *inp;
 	int error, s;
@@ -484,7 +485,7 @@
 
 	if (req->newlen != sizeof(addrs))
 		return (EINVAL);
-	if (req->oldlen != sizeof(struct ucred))
+	if (req->oldlen != sizeof(struct xucred))
 		return (EINVAL);
 	error = SYSCTL_IN(req, addrs, sizeof(addrs));
 	if (error)
@@ -498,9 +499,12 @@
 		error = ENOENT;
 		goto out;
 	}
-	error = SYSCTL_OUT(req, inp->inp_socket->so_cred,
-			   sizeof(struct ucred));
 
+	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
+	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
+	    sizeof(xuc.cr_groups));
+	error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
 out:
 	splx(s);
 	return (error);
@@ -508,7 +512,7 @@
 
 SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
 	    0, 0,
-	    udp6_getcred, "S,ucred", "Get the ucred of a UDP6 connection");
+	    udp6_getcred, "S,xucred", "Get the xucred of a UDP6 connection");
 
 static int
 udp6_abort(struct socket *so)
Index: sys/nfs/nfs.h
===================================================================
RCS file: /usr2/ncvs/src/sys/nfs/nfs.h,v
retrieving revision 1.56
diff -u -r1.56 nfs.h
--- sys/nfs/nfs.h	2000/10/24 10:13:36	1.56
+++ sys/nfs/nfs.h	2001/01/23 00:28:27
@@ -197,7 +197,7 @@
 	struct nfsd	*nsd_nfsd;	/* Pointer to in kernel nfsd struct */
 	uid_t		nsd_uid;	/* Effective uid mapped to cred */
 	u_int32_t	nsd_haddr;	/* Ip address of client */
-	struct ucred	nsd_cr;		/* Cred. uid maps to */
+	struct xucred	nsd_cr;		/* Cred. uid maps to */
 	int		nsd_authlen;	/* Length of auth string (ret) */
 	u_char		*nsd_authstr;	/* Auth string (ret) */
 	int		nsd_verflen;	/* and the verfier */
Index: sys/nfs/nfs_syscalls.c
===================================================================
RCS file: /usr2/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/23 00:48:56
@@ -244,7 +244,7 @@
 				slp->ns_numuids++;
 				nuidp = (struct nfsuid *)
 				   malloc(sizeof (struct nfsuid), M_NFSUID,
-					M_WAITOK);
+					M_WAITOK | M_ZERO);
 			    } else
 				nuidp = (struct nfsuid *)0;
 			    if ((slp->ns_flag & SLP_VALID) == 0) {
@@ -260,7 +260,12 @@
 					FREE(nuidp->nu_nam, M_SONAME);
 			        }
 				nuidp->nu_flag = 0;
-				nuidp->nu_cr = nsd->nsd_cr;
+				nuidp->nu_cr.cr_uid = nsd->nsd_cr.cr_uid;
+				nuidp->nu_cr.cr_ngroups =
+				  nsd->nsd_cr.cr_ngroups;
+				bcopy(nsd->nsd_cr.cr_groups,
+				  nuidp->nu_cr.cr_groups,
+				  sizeof(nuidp->nu_cr.cr_groups));
 				if (nuidp->nu_cr.cr_ngroups > NGROUPS)
 				    nuidp->nu_cr.cr_ngroups = NGROUPS;
 				nuidp->nu_cr.cr_ref = 1;
Index: sys/sys/mount.h
===================================================================
RCS file: /usr2/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	2001/01/23 00:32:10
@@ -245,11 +245,11 @@
 struct export_args {
 	int	ex_flags;		/* export related flags */
 	uid_t	ex_root;		/* mapping for root uid */
-	struct	ucred ex_anon;		/* mapping for anonymous user */
+	struct	xucred ex_anon;		/* mapping for anonymous user */
 	struct	sockaddr *ex_addr;	/* net address to which exported */
-	int	ex_addrlen;		/* and the net address length */
+	u_char	ex_addrlen;		/* and the net address length */
 	struct	sockaddr *ex_mask;	/* mask of valid bits in saddr */
-	int	ex_masklen;		/* and the smask length */
+	u_char	ex_masklen;		/* and the smask length */
 	char	*ex_indexfile;		/* index file for WebNFS URLs */
 };
 
Index: sys/sys/ucred.h
===================================================================
RCS file: /usr2/ncvs/src/sys/sys/ucred.h,v
retrieving revision 1.19
diff -u -r1.19 ucred.h
--- sys/sys/ucred.h	2000/11/30 19:09:47	1.19
+++ sys/sys/ucred.h	2001/01/28 22:53:01
@@ -53,9 +53,18 @@
 	struct	uidinfo *cr_uidinfo;	/* per uid resource consumption */
 	struct	mtx cr_mtx;		/* protect refcount */
 };
-#define cr_gid cr_groups[0]
 #define NOCRED ((struct ucred *)0)	/* no credential available */
 #define FSCRED ((struct ucred *)-1)	/* filesystem credential */
+
+/*
+ * This is the external representation of struct ucred which "won't change".
+ */
+struct xucred {
+	uid_t	cr_uid;			/* effective user id */
+	short	cr_ngroups;		/* number of groups */
+	gid_t	cr_groups[NGROUPS];	/* groups */
+};
+#define cr_gid cr_groups[0]
 
 #ifdef _KERNEL
 
Index: usr.sbin/inetd/builtins.c
===================================================================
RCS file: /usr2/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	2001/01/22 23:54:26
@@ -338,7 +338,7 @@
 	struct sockaddr_in6 sin6[2];
 #endif
 	struct sockaddr_storage ss[2];
-	struct ucred uc;
+	struct xucred uc;
 	struct timeval tv = {
 		10,
 		0


-- 
 Brian Fundakowski Feldman           \  FreeBSD: The Power to Serve!  /
 green@FreeBSD.org                    `------------------------------'




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200102071828.f17ISLr17637>