Date: Fri, 14 Dec 2001 07:09:10 +0000 From: Dima Dorfman <dima@trit.org> To: Robert Watson <rwatson@freebsd.org> Cc: "Brian F. Feldman" <green@freebsd.org>, arch@freebsd.org Subject: Re: MFC'ing xucred definition Message-ID: <20011214070915.91CB13E2F@bazooka.trit.org> In-Reply-To: <Pine.NEB.3.96L.1011213221643.74588G-100000@fledge.watson.org>; from rwatson@freebsd.org on "Thu, 13 Dec 2001 22:17:50 -0500 (EST)"
next in thread | previous in thread | raw e-mail | index | archive | help
Robert Watson <rwatson@freebsd.org> wrote:
>
> On Fri, 14 Dec 2001, Dima Dorfman wrote:
>
> > > Actually, the one thing I'd like to see before we move forward is a
> > > standard routine that accepts a ucred, and a *xucred, and fills out the
> > > xucred using the ucred (preferably, in kern_prot.c). Right now, xucred i
> s
> > > filled out in various places manually (netinet, socket code, et al). As
> > > we begin to broaden the scope of xucred (for example, I'd like to push in
> > > the ruid and rgid), it will make things a lot easier, and also prevent
> > > more code from knowing much about the innards of ucred. That way, also,
> > > the version number can be kept in one place.
> >
> > I had patches to add this routine (and vice versa, xucred->ucred)
> > before you added the extra fields to ucred, at which point I dropped it
> > since it didn't make much sense: Which fields do you copy? Effective,
> > real, or saved {u,g}ids? It would again make sense if xucred had the
> > same set of fields as ucred, however.
>
> It's always been euid in ucred previously, so I assumed that for version 0
> of xucred, only euid and egid (plus additional groups) would be exported.
> Future versions of xucred (probably version 1, only in -CURRENT) would
> also be able to export ruid, svuid, rgid, and svgid.
Very well. The attached patch adds two routines, cru2x() and crx2u()
which convert from a ucred to xucred and vice versa, respectively.
cru2x() sets the version number, and crx2u() checks it. If the check
fails, it returns EINVAL. I'm not sure if there's a better way to do
this error passing, since it seems that none of the other cr*()
routines return an error code.
The userland parts remain unchanged from my previous patches.
Index: lib/libc/gen/getpeereid.3
===================================================================
RCS file: /ref/cvsf/src/lib/libc/gen/getpeereid.3,v
retrieving revision 1.3
diff -u -r1.3 getpeereid.3
--- lib/libc/gen/getpeereid.3 2001/12/02 23:50:40 1.3
+++ lib/libc/gen/getpeereid.3 2001/12/14 01:20:17
@@ -118,7 +118,8 @@
The argument
.Fa s
does not refer to a socket of type
-.Dv SOCK_STREAM .
+.Dv SOCK_STREAM ,
+or the kernel returned invalid data.
.El
.Sh SEE ALSO
.Xr connect 2 ,
Index: lib/libc/gen/getpeereid.c
===================================================================
RCS file: /ref/cvsf/src/lib/libc/gen/getpeereid.c,v
retrieving revision 1.1
diff -u -r1.1 getpeereid.c
--- lib/libc/gen/getpeereid.c 2001/08/17 22:09:15 1.1
+++ lib/libc/gen/getpeereid.c 2001/12/14 01:20:17
@@ -34,6 +34,7 @@
#include <sys/ucred.h>
#include <sys/un.h>
+#include <errno.h>
#include <unistd.h>
int
@@ -47,6 +48,8 @@
error = getsockopt(s, LOCAL_PEERCRED, 1, &xuc, &xuclen);
if (error != 0)
return (error);
+ if (xuc.cr_version != XUCRED_VERSION)
+ return (EINVAL);
*euid = xuc.cr_uid;
*egid = xuc.cr_gid;
return (0);
Index: sbin/mountd/mountd.c
===================================================================
RCS file: /ref/cvsf/src/sbin/mountd/mountd.c,v
retrieving revision 1.59
diff -u -r1.59 mountd.c
--- sbin/mountd/mountd.c 2001/09/20 02:15:17 1.59
+++ sbin/mountd/mountd.c 2001/12/14 01:20:17
@@ -211,7 +211,7 @@
struct grouplist *grphead;
char exname[MAXPATHLEN];
struct xucred def_anon = {
- 0,
+ XUCRED_VERSION,
(uid_t)-2,
1,
{ (gid_t)-2 },
@@ -2050,6 +2050,7 @@
struct group *gr;
int ngroups, groups[NGROUPS + 1];
+ cr->cr_version = XUCRED_VERSION;
/*
* Set up the unprivileged user.
*/
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /ref/cvsf/src/sys/kern/kern_prot.c,v
retrieving revision 1.131
diff -u -r1.131 kern_prot.c
--- sys/kern/kern_prot.c 2001/12/06 21:58:47 1.131
+++ sys/kern/kern_prot.c 2001/12/14 03:30:55
@@ -1670,6 +1670,41 @@
}
/*
+ * Fill in a struct xucred based on a struct ucred.
+ */
+void
+cru2x(cr, xcr)
+ struct ucred *cr;
+ struct xucred *xcr;
+{
+
+ bzero(xcr, sizeof(*xcr));
+ xcr->cr_version = XUCRED_VERSION;
+ xcr->cr_uid = cr->cr_uid;
+ xcr->cr_ngroups = cr->cr_ngroups;
+ bcopy(cr->cr_groups, xcr->cr_groups, sizeof(cr->cr_groups));
+}
+
+/*
+ * Copy information out of a struct xucred into a struct ucred. This
+ * routine does *not* initialize (zero) the output structure (cr)
+ * because that's the job of crget() or crdup().
+ */
+int
+crx2u(xcr, cr)
+ struct xucred *xcr;
+ struct ucred *cr;
+{
+
+ if (xcr->cr_version != XUCRED_VERSION)
+ return (EINVAL);
+ cr->cr_uid = xcr->cr_uid;
+ cr->cr_ngroups = xcr->cr_ngroups;
+ bcopy(xcr->cr_groups, cr->cr_groups, sizeof(xcr->cr_groups));
+ return (0);
+}
+
+/*
* Get login name, if available.
*/
#ifndef _SYS_SYSPROTO_H_
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /ref/cvsf/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.78
diff -u -r1.78 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c 2001/12/13 22:09:37 1.78
+++ sys/kern/uipc_usrreq.c 2001/12/14 03:33:12
@@ -710,11 +710,7 @@
* from its process structure at the time of connect()
* (which is now).
*/
- memset(&unp3->unp_peercred, '\0', sizeof(unp3->unp_peercred));
- unp3->unp_peercred.cr_uid = td->td_proc->p_ucred->cr_uid;
- unp3->unp_peercred.cr_ngroups = td->td_proc->p_ucred->cr_ngroups;
- memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_groups,
- sizeof(unp3->unp_peercred.cr_groups));
+ cru2x(td->td_proc->p_ucred, &unp3->unp_peercred);
unp3->unp_flags |= UNP_HAVEPC;
/*
* The receiver's (server's) credentials are copied
@@ -1396,11 +1392,7 @@
struct proc *p;
{
- bzero(&unp->unp_peercred, sizeof(unp->unp_peercred));
- unp->unp_peercred.cr_uid = p->p_ucred->cr_uid;
- unp->unp_peercred.cr_ngroups = p->p_ucred->cr_ngroups;
- bcopy(p->p_ucred->cr_groups, unp->unp_peercred.cr_groups,
- sizeof(unp->unp_peercred.cr_groups));
+ cru2x(p->p_ucred, &unp->unp_peercred);
unp->unp_flags |= UNP_HAVEPCCACHED;
return (0);
}
Index: sys/kern/vfs_export.c
===================================================================
RCS file: /ref/cvsf/src/sys/kern/vfs_export.c,v
retrieving revision 1.312
diff -u -r1.312 vfs_export.c
--- sys/kern/vfs_export.c 2001/09/10 11:28:05 1.312
+++ sys/kern/vfs_export.c 2001/12/14 03:40:24
@@ -98,11 +98,9 @@
return (EPERM);
np = &nep->ne_defexported;
np->netc_exflags = argp->ex_flags;
- 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));
+ error = crx2u(&argp->ex_anon, &np->netc_anon);
+ if (error != 0)
+ return (error);
np->netc_anon.cr_ref = 1;
mp->mnt_flag |= MNT_DEFEXPORTED;
return (0);
@@ -150,11 +148,9 @@
goto out;
}
np->netc_exflags = argp->ex_flags;
- 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));
+ error = crx2u(&argp->ex_anon, &np->netc_anon);
+ if (error != 0)
+ goto out;
np->netc_anon.cr_ref = 1;
return (0);
out:
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /ref/cvsf/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.118
diff -u -r1.118 tcp_subr.c
--- sys/netinet/tcp_subr.c 2001/11/22 04:50:43 1.118
+++ sys/netinet/tcp_subr.c 2001/12/14 03:34:19
@@ -919,11 +919,7 @@
error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
if (error)
goto out;
- bzero(&xuc, sizeof(xuc));
- 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));
+ cru2x(inp->inp_socket->so_cred, &xuc);
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
out:
splx(s);
@@ -975,11 +971,7 @@
error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
if (error)
goto out;
- bzero(&xuc, sizeof(xuc));
- 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));
+ cru2x(inp->inp_socket->so_cred, &xuc);
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
out:
splx(s);
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /ref/cvsf/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.100
diff -u -r1.100 udp_usrreq.c
--- sys/netinet/udp_usrreq.c 2001/11/08 02:13:17 1.100
+++ sys/netinet/udp_usrreq.c 2001/12/14 03:34:36
@@ -651,11 +651,7 @@
error = cr_cansee(req->td->td_proc->p_ucred, inp->inp_socket->so_cred);
if (error)
goto out;
- bzero(&xuc, sizeof(xuc));
- 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));
+ cru2x(inp->inp_socket->so_cred, &xuc);
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
out:
splx(s);
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /ref/cvsf/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.19
diff -u -r1.19 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c 2001/11/08 02:13:18 1.19
+++ sys/netinet6/udp6_usrreq.c 2001/12/14 03:35:00
@@ -484,11 +484,7 @@
error = ENOENT;
goto out;
}
- bzero(&xuc, sizeof(xuc));
- 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));
+ cru2x(inp->inp_socket->so_cred, &xuc);
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
out:
splx(s);
Index: sys/security/lomac/kernel_socket.c
===================================================================
RCS file: /ref/cvsf/src/sys/security/lomac/kernel_socket.c,v
retrieving revision 1.2
diff -u -r1.2 kernel_socket.c
--- sys/security/lomac/kernel_socket.c 2001/12/03 00:21:18 1.2
+++ sys/security/lomac/kernel_socket.c 2001/12/14 03:35:23
@@ -265,11 +265,7 @@
* from its process structure at the time of connect()
* (which is now).
*/
- memset(&unp3->unp_peercred, '\0', sizeof(unp3->unp_peercred));
- unp3->unp_peercred.cr_uid = td->td_proc->p_ucred->cr_uid;
- unp3->unp_peercred.cr_ngroups = td->td_proc->p_ucred->cr_ngroups;
- memcpy(unp3->unp_peercred.cr_groups, td->td_proc->p_ucred->cr_groups,
- sizeof(unp3->unp_peercred.cr_groups));
+ cru2x(td->td_proc->p_ucred, &unp3->unp_peercred);
unp3->unp_flags |= UNP_HAVEPC;
/*
* The receiver's (server's) credentials are copied
Index: sys/sys/ucred.h
===================================================================
RCS file: /ref/cvsf/src/sys/sys/ucred.h,v
retrieving revision 1.26
diff -u -r1.26 ucred.h
--- sys/sys/ucred.h 2001/10/11 23:38:17 1.26
+++ sys/sys/ucred.h 2001/12/14 03:30:26
@@ -73,12 +73,13 @@
* any need to change the size of this or layout of its used fields.
*/
struct xucred {
- u_short _cr_unused0; /* compatibility with old ucred */
+ u_short cr_version; /* structure layout version */
uid_t cr_uid; /* effective user id */
short cr_ngroups; /* number of groups */
gid_t cr_groups[NGROUPS]; /* groups */
void *_cr_unused1; /* compatibility with old ucred */
};
+#define XUCRED_VERSION 0
#ifdef _KERNEL
@@ -95,6 +96,8 @@
struct ucred *crget __P((void));
struct ucred *crhold __P((struct ucred *cr));
int crshared __P((struct ucred *cr));
+void cru2x __P((struct ucred *cr, struct xucred *xcr));
+int crx2u __P((struct xucred *xcr, struct ucred *cr));
int groupmember __P((gid_t gid, struct ucred *cred));
#endif /* _KERNEL */
Index: usr.sbin/inetd/builtins.c
===================================================================
RCS file: /ref/cvsf/src/usr.sbin/inetd/builtins.c,v
retrieving revision 1.36
diff -u -r1.36 builtins.c
--- usr.sbin/inetd/builtins.c 2001/07/17 07:12:57 1.36
+++ usr.sbin/inetd/builtins.c 2001/12/14 01:20:18
@@ -569,7 +569,7 @@
getcredfail = EAFNOSUPPORT;
break;
}
- if (getcredfail != 0) {
+ if (getcredfail != 0 || uc.cr_version != XUCRED_VERSION) {
if (*idbuf == '\0')
iderror(lport, fport, s,
getcredfail == ENOENT ? ID_NOUSER : ID_UNKNOWN);
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?20011214070915.91CB13E2F>
