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>