Introduce a version field to `struct xucred' in place of one of the

spares (the size of the field was changed from u_short to u_int to
reflect what it really ends up being).  Accordingly, change users of
xucred to set and check this field as appropriate.  In the kernel,
this is being done inside the new cru2x() routine which takes a
`struct ucred' and fills out a `struct xucred' according to the
former.  This also has the pleasant sideaffect of removing some
duplicate code.

Reviewed by:	rwatson
This commit is contained in:
Dima Dorfman 2002-02-27 04:45:37 +00:00
parent b7eeb587f6
commit 76183f3453
13 changed files with 38 additions and 50 deletions

View File

@ -118,7 +118,8 @@ have been called.
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 ,

View File

@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ucred.h>
#include <sys/un.h>
#include <errno.h>
#include <unistd.h>
int
@ -45,6 +46,8 @@ getpeereid(int s, uid_t *euid, gid_t *egid)
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);

View File

@ -211,7 +211,7 @@ struct mountlist *mlhead;
struct grouplist *grphead;
char exname[MAXPATHLEN];
struct xucred def_anon = {
0,
XUCRED_VERSION,
(uid_t)-2,
1,
{ (gid_t)-2 },
@ -2050,6 +2050,7 @@ parsecred(namelist, cr)
struct group *gr;
int ngroups, groups[NGROUPS + 1];
cr->cr_version = XUCRED_VERSION;
/*
* Set up the unprivileged user.
*/

View File

@ -1759,6 +1759,22 @@ crdup(cr)
return (newcr);
}
/*
* 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));
}
/*
* small routine to swap a thread's current ucred for the correct one
* taken from the process.

View File

@ -717,11 +717,7 @@ unp_connect(so, nam, td)
* 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
@ -1427,11 +1423,7 @@ unp_listen(unp, p)
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);
}

View File

@ -922,11 +922,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
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);
@ -978,11 +974,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
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);

View File

@ -922,11 +922,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
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);
@ -978,11 +974,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
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);

View File

@ -651,11 +651,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
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);

View File

@ -486,11 +486,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
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);

View File

@ -265,11 +265,7 @@ lomac_local_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
* 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

View File

@ -73,12 +73,13 @@ struct ucred {
* 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_int 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
@ -96,6 +97,7 @@ void crfree(struct ucred *cr);
struct ucred *crget(void);
struct ucred *crhold(struct ucred *cr);
int crshared(struct ucred *cr);
void cru2x(struct ucred *cr, struct xucred *xcr);
int groupmember(gid_t gid, struct ucred *cred);
#endif /* _KERNEL */

View File

@ -569,7 +569,7 @@ ident_stream(s, sep) /* Ident service (AKA "auth") */
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);

View File

@ -211,7 +211,7 @@ struct mountlist *mlhead;
struct grouplist *grphead;
char exname[MAXPATHLEN];
struct xucred def_anon = {
0,
XUCRED_VERSION,
(uid_t)-2,
1,
{ (gid_t)-2 },
@ -2050,6 +2050,7 @@ parsecred(namelist, cr)
struct group *gr;
int ngroups, groups[NGROUPS + 1];
cr->cr_version = XUCRED_VERSION;
/*
* Set up the unprivileged user.
*/