1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-10-19 02:29:40 +00:00

Rework the credential code to support larger values of NGROUPS and

NGROUPS_MAX, eliminate ABI dependencies on them, and raise the to 1024
and 1023 respectively.  (Previously they were equal, but under a close
reading of POSIX, NGROUPS_MAX was defined to be too large by 1 since it
is the number of supplemental groups, not total number of groups.)

The bulk of the change consists of converting the struct ucred member
cr_groups from a static array to a pointer.  Do the equivalent in
kinfo_proc.

Introduce new interfaces crcopysafe() and crsetgroups() for duplicating
a process credential before modifying it and for setting group lists
respectively.  Both interfaces take care for the details of allocating
groups array. crsetgroups() takes care of truncating the group list
to the current maximum (NGROUPS) if necessary.  In the future,
crsetgroups() may be responsible for insuring invariants such as sorting
the supplemental groups to allow groupmember() to be implemented as a
binary search.

Because we can not change struct xucred without breaking application
ABIs, we leave it alone and introduce a new XU_NGROUPS value which is
always 16 and is to be used or NGRPS as appropriate for things such as
NFS which need to use no more than 16 groups.  When feasible, truncate
the group list rather than generating an error.

Minor changes:
  - Reduce the number of hand rolled versions of groupmember().
  - Do not assign to both cr_gid and cr_groups[0].
  - Modify ipfw to cache ucreds instead of part of their contents since
    they are immutable once referenced by more than one entity.

Submitted by:	Isilon Systems (initial implementation)
X-MFC after:	never
PR:		bin/113398 kern/133867
This commit is contained in:
Brooks Davis 2009-06-19 17:10:35 +00:00
parent f345b422d1
commit 838d985825
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194498
31 changed files with 282 additions and 187 deletions

View File

@ -22,6 +22,23 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
20090619:
NGROUPS_MAX and NGROUPS have been increased from 16 to 1023
and 1024 respectively. As long as no more than 16 groups per
process are used, no changes should be visible. When more
than 16 groups are used, old binaries may fail if they call
getgroups() or getgrouplist() with statically sized storage.
Recompiling will work around this, but applications should be
modified to use dynamically allocated storage for group arrays
as POSIX.1-2008 does not cap an implementation's number of
supported groups at NGROUPS_MAX+1 as previous versions did.
NFS and portalfs mounts may also be affected as the list of
groups is truncated to 16. Users of NFS who use more than 16
groups, should take care that negative group permissions are not
used on the exported file systems as they will not be reliable
unless a GSSAPI based authentication method is used.
20090616:
The compiling option ADAPTIVE_LOCKMGRS has been introduced.
This option compiles in the support for adaptive spinning for lockmgrs

View File

@ -61,9 +61,6 @@ __FBSDID("$FreeBSD$");
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
#ifndef NGROUPS
#define NGROUPS 16
#endif
#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT)

View File

@ -66,10 +66,6 @@ static char *NETIDFILE = "/etc/netid";
static int getnetid( char *, char * );
static int _getgroups( char *, gid_t * );
#ifndef NGROUPS
#define NGROUPS 16
#endif
/*
* Convert network-name into unix credential
*/
@ -104,7 +100,7 @@ netname2user(netname, uidp, gidp, gidlenp, gidlist)
return (0);
}
*gidp = (gid_t) atol(p);
for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
for (gidlen = 0; gidlen < NGRPS; gidlen++) {
p = strsep(&res, "\n,");
if (p == NULL)
break;
@ -157,7 +153,7 @@ netname2user(netname, uidp, gidp, gidlenp, gidlist)
static int
_getgroups(uname, groups)
char *uname;
gid_t groups[NGROUPS];
gid_t groups[NGRPS];
{
gid_t ngroups = 0;
struct group *grp;
@ -169,7 +165,7 @@ _getgroups(uname, groups)
while ((grp = getgrent())) {
for (i = 0; grp->gr_mem[i]; i++)
if (!strcmp(grp->gr_mem[i], uname)) {
if (ngroups == NGROUPS) {
if (ngroups == NGRPS) {
#ifdef DEBUG
fprintf(stderr,
"initgroups: %s is in too many groups\n", uname);

View File

@ -146,8 +146,7 @@ kvm_proclist(kd, what, arg, p, bp, maxcnt)
kp->ki_rgid = ucred.cr_rgid;
kp->ki_svgid = ucred.cr_svgid;
kp->ki_ngroups = ucred.cr_ngroups;
bcopy(ucred.cr_groups, kp->ki_groups,
NGROUPS * sizeof(gid_t));
kp->ki_groups = ucred.cr_groups;
kp->ki_uid = ucred.cr_uid;
if (ucred.cr_prison != NULL) {
if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) {

View File

@ -1132,7 +1132,7 @@ int
linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
{
struct ucred *newcred, *oldcred;
l_gid_t linux_gidset[NGROUPS];
l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@ -1140,13 +1140,14 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
ngrp = args->gidsetsize;
if (ngrp < 0 || ngrp >= NGROUPS)
return (EINVAL);
linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
if (error)
return (error);
goto out;
newcred = crget();
p = td->td_proc;
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
/*
* cr_groups[0] holds egid. Setting the whole set from
@ -1157,10 +1158,9 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
goto out;
}
crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups = ngrp + 1;
@ -1177,14 +1177,17 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
return (0);
error = 0;
out:
free(linux_gidset, M_TEMP);
return (error);
}
int
linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
{
struct ucred *cred;
l_gid_t linux_gidset[NGROUPS];
l_gid_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
@ -1207,13 +1210,16 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
return (EINVAL);
ngrp = 0;
linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
if ((error = copyout(linux_gidset, args->grouplist,
ngrp * sizeof(l_gid_t))))
error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
free(linux_gidset, M_TEMP);
if (error)
return (error);
td->td_retval[0] = ngrp;

View File

@ -98,7 +98,7 @@ int
linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
{
struct ucred *newcred, *oldcred;
l_gid16_t linux_gidset[NGROUPS];
l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int ngrp, error;
struct proc *p;
@ -111,13 +111,14 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
ngrp = args->gidsetsize;
if (ngrp < 0 || ngrp >= NGROUPS)
return (EINVAL);
linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
if (error)
return (error);
newcred = crget();
p = td->td_proc;
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
/*
* cr_groups[0] holds egid. Setting the whole set from
@ -128,10 +129,9 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
PROC_UNLOCK(p);
crfree(newcred);
return (error);
goto out;
}
crcopy(newcred, oldcred);
if (ngrp > 0) {
newcred->cr_ngroups = ngrp + 1;
@ -149,14 +149,17 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
p->p_ucred = newcred;
PROC_UNLOCK(p);
crfree(oldcred);
return (0);
error = 0;
out:
free(linux_gidset, M_TEMP);
return (error);
}
int
linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
{
struct ucred *cred;
l_gid16_t linux_gidset[NGROUPS];
l_gid16_t *linux_gidset;
gid_t *bsd_gidset;
int bsd_gidsetsz, ngrp, error;
@ -184,12 +187,15 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
return (EINVAL);
ngrp = 0;
linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
M_TEMP, M_WAITOK);
while (ngrp < bsd_gidsetsz) {
linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
ngrp++;
}
error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
free(linux_gidset, M_TEMP);
if (error)
return (error);

View File

@ -220,14 +220,9 @@ nfsrv_lookupfilename(struct nameidata *ndp, char *fname, NFSPROC_T *p)
void
newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
{
int ngroups, i;
cr->cr_uid = nfscr->nfsc_uid;
ngroups = (nfscr->nfsc_ngroups < NGROUPS) ?
nfscr->nfsc_ngroups : NGROUPS;
for (i = 0; i < ngroups; i++)
cr->cr_groups[i] = nfscr->nfsc_groups[i];
cr->cr_ngroups = ngroups;
crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups);
}
/*

View File

@ -976,14 +976,12 @@ nfscl_getmyip(struct nfsmount *nmp, int *isinet6p)
void
newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr)
{
int ngroups, i;
int i;
nfscr->nfsc_uid = cr->cr_uid;
ngroups = (cr->cr_ngroups > NGROUPS) ? NGROUPS :
cr->cr_ngroups;
for (i = 0; i < ngroups; i++)
nfscr->nfsc_ngroups = MIN(cr->cr_ngroups, XU_NGROUPS);
for (i = 0; i < nfscr->nfsc_ngroups; i++)
nfscr->nfsc_groups[i] = cr->cr_groups[i];
nfscr->nfsc_ngroups = ngroups;
}

View File

@ -2360,7 +2360,6 @@ int
nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
struct ucred *credanon)
{
int i;
int error = 0;
/*
@ -2403,9 +2402,8 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
(nd->nd_flag & ND_AUTHNONE))) {
nd->nd_cred->cr_uid = credanon->cr_uid;
nd->nd_cred->cr_gid = credanon->cr_gid;
for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
nd->nd_cred->cr_groups[i] = credanon->cr_groups[i];
nd->nd_cred->cr_ngroups = i;
crsetgroups(nd->nd_cred, credanon->cr_ngroups,
credanon->cr_groups);
}
return (0);
}

View File

@ -3577,7 +3577,6 @@ nfsrv_docallback(struct nfsclient *clp, int procnum,
nd->nd_repstat = 0;
cred->cr_uid = clp->lc_uid;
cred->cr_gid = clp->lc_gid;
cred->cr_groups[0] = clp->lc_gid;
callback = clp->lc_callback;
NFSUNLOCKSTATE();
cred->cr_ngroups = 1;

View File

@ -43,7 +43,7 @@ struct portal_cred {
int pcr_flag; /* File open mode */
uid_t pcr_uid; /* From ucred */
short pcr_ngroups; /* From ucred */
gid_t pcr_groups[NGROUPS]; /* From ucred */
gid_t pcr_groups[XU_NGROUPS]; /* From ucred */
};
#ifdef _KERNEL

View File

@ -311,8 +311,9 @@ portal_open(ap)
pcred.pcr_flag = ap->a_mode;
pcred.pcr_uid = ap->a_cred->cr_uid;
pcred.pcr_ngroups = ap->a_cred->cr_ngroups;
bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t));
pcred.pcr_ngroups = MIN(ap->a_cred->cr_ngroups, XU_NGROUPS);
bcopy(ap->a_cred->cr_groups, pcred.pcr_groups,
pcred.pcr_ngroups * sizeof(gid_t));
aiov[0].iov_base = (caddr_t) &pcred;
aiov[0].iov_len = sizeof(pcred);
aiov[1].iov_base = pt->pt_arg;

View File

@ -638,7 +638,6 @@ unionfs_check_corrected_access(accmode_t accmode,
uid_t uid; /* upper side vnode's uid */
gid_t gid; /* upper side vnode's gid */
u_short vmode; /* upper side vnode's mode */
gid_t *gp;
u_short mask;
mask = 0;
@ -659,17 +658,14 @@ unionfs_check_corrected_access(accmode_t accmode,
/* check group */
count = 0;
gp = cred->cr_groups;
for (; count < cred->cr_ngroups; count++, gp++) {
if (gid == *gp) {
if (accmode & VEXEC)
mask |= S_IXGRP;
if (accmode & VREAD)
mask |= S_IRGRP;
if (accmode & VWRITE)
mask |= S_IWGRP;
return ((vmode & mask) == mask ? 0 : EACCES);
}
if (groupmember(gid, cred)) {
if (accmode & VEXEC)
mask |= S_IXGRP;
if (accmode & VREAD)
mask |= S_IRGRP;
if (accmode & VWRITE)
mask |= S_IWGRP;
return ((vmode & mask) == mask ? 0 : EACCES);
}
/* check other */

View File

@ -657,24 +657,29 @@ ibcs2_getgroups(td, uap)
struct thread *td;
struct ibcs2_getgroups_args *uap;
{
ibcs2_gid_t iset[NGROUPS_MAX];
gid_t gp[NGROUPS_MAX];
ibcs2_gid_t *iset;
gid_t *gp;
u_int i, ngrp;
int error;
if (uap->gidsetsize < 0)
return (EINVAL);
ngrp = MIN(uap->gidsetsize, NGROUPS_MAX);
gp = malloc(ngrp * sizeof(*gp), M_TEMP, M_WAITOK);
error = kern_getgroups(td, &ngrp, gp);
if (error)
return (error);
goto out;
if (uap->gidsetsize > 0) {
iset = malloc(ngrp * sizeof(*iset), M_TEMP, M_WAITOK);
for (i = 0; i < ngrp; i++)
iset[i] = (ibcs2_gid_t)gp[i];
error = copyout(iset, uap->gidset, ngrp * sizeof(ibcs2_gid_t));
free(iset, M_TEMP);
}
if (error == 0)
td->td_retval[0] = ngrp;
out:
free(gp, M_TEMP);
return (error);
}
@ -683,21 +688,31 @@ ibcs2_setgroups(td, uap)
struct thread *td;
struct ibcs2_setgroups_args *uap;
{
ibcs2_gid_t iset[NGROUPS_MAX];
gid_t gp[NGROUPS_MAX];
ibcs2_gid_t *iset;
gid_t *gp;
int error, i;
if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX)
return (EINVAL);
if (uap->gidsetsize && uap->gidset) {
if (uap->gidsetsize && uap->gidset == NULL)
return (EINVAL);
gp = malloc(uap->gidsetsize * sizeof(*gp), M_TEMP, M_WAITOK);
if (uap->gidsetsize) {
iset = malloc(uap->gidsetsize * sizeof(*iset), M_TEMP, M_WAITOK);
error = copyin(uap->gidset, iset, sizeof(ibcs2_gid_t) *
uap->gidsetsize);
if (error)
return (error);
if (error) {
free(iset, M_TEMP);
goto out;
}
for (i = 0; i < uap->gidsetsize; i++)
gp[i] = (gid_t)iset[i];
}
return (kern_setgroups(td, uap->gidsetsize, gp));
error = kern_setgroups(td, uap->gidsetsize, gp);
out:
free(gp, M_TEMP);
return (error);
}
int

View File

@ -579,6 +579,7 @@ do_execve(td, args, mac_p)
* reset.
*/
PROC_LOCK(p);
oldcred = crcopysafe(p, newcred);
if (sigacts_shared(p->p_sigacts)) {
oldsigacts = p->p_sigacts;
PROC_UNLOCK(p);
@ -629,7 +630,6 @@ do_execve(td, args, mac_p)
* XXXMAC: For the time being, use NOSUID to also prohibit
* transitions on the file system.
*/
oldcred = p->p_ucred;
credential_changing = 0;
credential_changing |= (attr.va_mode & S_ISUID) && oldcred->cr_uid !=
attr.va_uid;
@ -683,7 +683,6 @@ do_execve(td, args, mac_p)
/*
* Set the new credentials.
*/
crcopy(newcred, oldcred);
if (attr.va_mode & S_ISUID)
change_euid(newcred, euip);
if (attr.va_mode & S_ISGID)
@ -723,7 +722,6 @@ do_execve(td, args, mac_p)
*/
if (oldcred->cr_svuid != oldcred->cr_uid ||
oldcred->cr_svgid != oldcred->cr_gid) {
crcopy(newcred, oldcred);
change_svuid(newcred, newcred->cr_uid);
change_svgid(newcred, newcred->cr_gid);
p->p_ucred = newcred;

View File

@ -730,10 +730,8 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
kp->ki_uid = cred->cr_uid;
kp->ki_ruid = cred->cr_ruid;
kp->ki_svuid = cred->cr_svuid;
/* XXX bde doesn't like KI_NGROUPS */
kp->ki_ngroups = min(cred->cr_ngroups, KI_NGROUPS);
bcopy(cred->cr_groups, kp->ki_groups,
kp->ki_ngroups * sizeof(gid_t));
kp->ki_ngroups = cred->cr_ngroups;
kp->ki_groups = cred->cr_groups;
kp->ki_rgid = cred->cr_rgid;
kp->ki_svgid = cred->cr_svgid;
kp->ki_cr_flags = cred->cr_flags;

View File

@ -82,6 +82,11 @@ static MALLOC_DEFINE(M_CRED, "cred", "credentials");
SYSCTL_NODE(_security, OID_AUTO, bsd, CTLFLAG_RW, 0, "BSD security policy");
static void crextend(struct ucred *cr, int n);
static void crsetgroups_locked(struct ucred *cr, int ngrp,
gid_t *groups);
#ifndef _SYS_SYSPROTO_H_
struct getpid_args {
int dummy;
@ -276,18 +281,21 @@ struct getgroups_args {
int
getgroups(struct thread *td, register struct getgroups_args *uap)
{
gid_t groups[NGROUPS];
gid_t *groups;
u_int ngrp;
int error;
ngrp = MIN(uap->gidsetsize, NGROUPS);
groups = malloc(ngrp * sizeof(*groups), M_TEMP, M_WAITOK);
error = kern_getgroups(td, &ngrp, groups);
if (error)
return (error);
goto out;
if (uap->gidsetsize > 0)
error = copyout(groups, uap->gidset, ngrp * sizeof(gid_t));
if (error == 0)
td->td_retval[0] = ngrp;
out:
free(groups, M_TEMP);
return (error);
}
@ -486,7 +494,10 @@ setuid(struct thread *td, struct setuid_args *uap)
newcred = crget();
uip = uifind(uid);
PROC_LOCK(p);
oldcred = p->p_ucred;
/*
* Copy credentials so other references do not see our changes.
*/
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setuid(oldcred, uid);
@ -521,10 +532,6 @@ setuid(struct thread *td, struct setuid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)) != 0)
goto fail;
/*
* Copy credentials so other references do not see our changes.
*/
crcopy(newcred, oldcred);
#ifdef _POSIX_SAVED_IDS
/*
* Do we have "appropriate privileges" (are we root or uid == euid)
@ -598,7 +605,10 @@ seteuid(struct thread *td, struct seteuid_args *uap)
newcred = crget();
euip = uifind(euid);
PROC_LOCK(p);
oldcred = p->p_ucred;
/*
* Copy credentials so other references do not see our changes.
*/
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_seteuid(oldcred, euid);
@ -612,8 +622,7 @@ seteuid(struct thread *td, struct seteuid_args *uap)
goto fail;
/*
* Everything's okay, do it. Copy credentials so other references do
* not see our changes.
* Everything's okay, do it.
*/
crcopy(newcred, oldcred);
if (oldcred->cr_uid != euid) {
@ -651,7 +660,7 @@ setgid(struct thread *td, struct setgid_args *uap)
AUDIT_ARG(gid, gid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setgid(oldcred, gid);
@ -680,7 +689,6 @@ setgid(struct thread *td, struct setgid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETGID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
#ifdef _POSIX_SAVED_IDS
/*
* Do we have "appropriate privileges" (are we root or gid == egid)
@ -750,7 +758,7 @@ setegid(struct thread *td, struct setegid_args *uap)
AUDIT_ARG(egid, egid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setegid(oldcred, egid);
@ -763,7 +771,6 @@ setegid(struct thread *td, struct setegid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETEGID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
if (oldcred->cr_groups[0] != egid) {
change_egid(newcred, egid);
setsugid(p);
@ -789,15 +796,19 @@ struct setgroups_args {
int
setgroups(struct thread *td, struct setgroups_args *uap)
{
gid_t groups[NGROUPS];
gid_t *groups = NULL;
int error;
if (uap->gidsetsize > NGROUPS)
return (EINVAL);
groups = malloc(uap->gidsetsize * sizeof(gid_t), M_TEMP, M_WAITOK);
error = copyin(uap->gidset, groups, uap->gidsetsize * sizeof(gid_t));
if (error)
return (error);
return (kern_setgroups(td, uap->gidsetsize, groups));
goto out;
error = kern_setgroups(td, uap->gidsetsize, groups);
out:
free(groups, M_TEMP);
return (error);
}
int
@ -811,8 +822,9 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
return (EINVAL);
AUDIT_ARG(groupset, groups, ngrp);
newcred = crget();
crextend(newcred, ngrp);
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setgroups(oldcred, ngrp, groups);
@ -824,11 +836,6 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
if (error)
goto fail;
/*
* XXX A little bit lazy here. We could test if anything has
* changed before crcopy() and setting P_SUGID.
*/
crcopy(newcred, oldcred);
if (ngrp < 1) {
/*
* setgroups(0, NULL) is a legitimate way of clearing the
@ -838,8 +845,7 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
*/
newcred->cr_ngroups = 1;
} else {
bcopy(groups, newcred->cr_groups, ngrp * sizeof(gid_t));
newcred->cr_ngroups = ngrp;
crsetgroups_locked(newcred, ngrp, groups);
}
setsugid(p);
p->p_ucred = newcred;
@ -877,7 +883,7 @@ setreuid(register struct thread *td, struct setreuid_args *uap)
euip = uifind(euid);
ruip = uifind(ruid);
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setreuid(oldcred, ruid, euid);
@ -892,7 +898,6 @@ setreuid(register struct thread *td, struct setreuid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETREUID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
change_euid(newcred, euip);
setsugid(p);
@ -942,7 +947,7 @@ setregid(register struct thread *td, struct setregid_args *uap)
AUDIT_ARG(rgid, rgid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setregid(oldcred, rgid, egid);
@ -957,7 +962,6 @@ setregid(register struct thread *td, struct setregid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETREGID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
change_egid(newcred, egid);
setsugid(p);
@ -1013,7 +1017,7 @@ setresuid(register struct thread *td, struct setresuid_args *uap)
euip = uifind(euid);
ruip = uifind(ruid);
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setresuid(oldcred, ruid, euid, suid);
@ -1033,7 +1037,6 @@ setresuid(register struct thread *td, struct setresuid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETRESUID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
if (euid != (uid_t)-1 && oldcred->cr_uid != euid) {
change_euid(newcred, euip);
setsugid(p);
@ -1090,7 +1093,7 @@ setresgid(register struct thread *td, struct setresgid_args *uap)
AUDIT_ARG(sgid, sgid);
newcred = crget();
PROC_LOCK(p);
oldcred = p->p_ucred;
oldcred = crcopysafe(p, newcred);
#ifdef MAC
error = mac_cred_check_setresgid(oldcred, rgid, egid, sgid);
@ -1110,7 +1113,6 @@ setresgid(register struct thread *td, struct setresgid_args *uap)
(error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID, 0)) != 0)
goto fail;
crcopy(newcred, oldcred);
if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
change_egid(newcred, egid);
setsugid(p);
@ -1780,6 +1782,7 @@ crget(void)
#ifdef MAC
mac_cred_init(cr);
#endif
crextend(cr, XU_NGROUPS);
return (cr);
}
@ -1829,6 +1832,7 @@ crfree(struct ucred *cr)
#ifdef MAC
mac_cred_destroy(cr);
#endif
free(cr->cr_groups, M_CRED);
free(cr, M_CRED);
}
}
@ -1854,6 +1858,7 @@ crcopy(struct ucred *dest, struct ucred *src)
bcopy(&src->cr_startcopy, &dest->cr_startcopy,
(unsigned)((caddr_t)&src->cr_endcopy -
(caddr_t)&src->cr_startcopy));
crsetgroups(dest, src->cr_ngroups, src->cr_groups);
uihold(dest->cr_uidinfo);
uihold(dest->cr_ruidinfo);
prison_hold(dest->cr_prison);
@ -1888,12 +1893,16 @@ crdup(struct ucred *cr)
void
cru2x(struct ucred *cr, struct xucred *xcr)
{
int ngroups;
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));
ngroups = MIN(cr->cr_ngroups, XU_NGROUPS);
xcr->cr_ngroups = ngroups;
bcopy(cr->cr_groups, xcr->cr_groups,
ngroups * sizeof(*cr->cr_groups));
}
/*
@ -1915,6 +1924,97 @@ cred_update_thread(struct thread *td)
crfree(cred);
}
struct ucred *
crcopysafe(struct proc *p, struct ucred *cr)
{
struct ucred *oldcred;
int groups;
PROC_LOCK_ASSERT(p, MA_OWNED);
oldcred = p->p_ucred;
while (cr->cr_agroups < oldcred->cr_agroups) {
groups = oldcred->cr_agroups;
PROC_UNLOCK(p);
crextend(cr, groups);
PROC_LOCK(p);
oldcred = p->p_ucred;
}
crcopy(cr, oldcred);
return (oldcred);
}
/*
* Extend the passed in credential to hold n items.
*/
static void
crextend(struct ucred *cr, int n)
{
int cnt;
/* Truncate? */
if (n <= cr->cr_agroups)
return;
/*
* We extend by 2 each time since we're using a power of two
* allocator until we need enough groups to fill a page.
* Once we're allocating multiple pages, only allocate as many
* as we actually need. The case of processes needing a
* non-power of two number of pages seems more likely than
* a real world process that adds thousands of groups one at a
* time.
*/
if ( n < PAGE_SIZE / sizeof(gid_t) ) {
if (cr->cr_agroups == 0)
cnt = MINALLOCSIZE / sizeof(gid_t);
else
cnt = cr->cr_agroups * 2;
while (cnt < n)
cnt *= 2;
} else
cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t));
/* Free the old array. */
if (cr->cr_groups)
free(cr->cr_groups, M_CRED);
cr->cr_groups = malloc(cnt * sizeof(gid_t), M_CRED, M_WAITOK | M_ZERO);
cr->cr_agroups = cnt;
}
/*
* Copy groups in to a credential, preserving any necessicary invariants
* (i.e. sorting in the future). crextend() must have been called
* before hand to ensure sufficient space is available. If
*/
static void
crsetgroups_locked(struct ucred *cr, int ngrp, gid_t *groups)
{
KASSERT(cr->cr_agroups >= ngrp, ("cr_ngroups is too small"));
bcopy(groups, cr->cr_groups, ngrp * sizeof(gid_t));
cr->cr_ngroups = ngrp;
}
/*
* Copy groups in to a credential after expanding it if required.
* Truncate the list to NGROUPS if it is too large.
*/
void
crsetgroups(struct ucred *cr, int ngrp, gid_t *groups)
{
if (ngrp > NGROUPS)
ngrp = NGROUPS;
crextend(cr, ngrp);
crsetgroups_locked(cr, ngrp, groups);
}
/*
* Get login name, if available.
*/

View File

@ -120,9 +120,8 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
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));
crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
argp->ex_anon.cr_groups);
np->netc_numsecflavors = argp->ex_numsecflavors;
bcopy(argp->ex_secflavors, np->netc_secflavors,
sizeof(np->netc_secflavors));
@ -205,9 +204,8 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
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));
crsetgroups(np->netc_anon, argp->ex_anon.cr_ngroups,
np->netc_anon->cr_groups);
np->netc_numsecflavors = argp->ex_numsecflavors;
bcopy(argp->ex_secflavors, np->netc_secflavors,
sizeof(np->netc_secflavors));

View File

@ -134,19 +134,6 @@ static uma_zone_t ipfw_dyn_rule_zone;
struct ip_fw *ip_fw_default_rule;
/*
* Data structure to cache our ucred related
* information. This structure only gets used if
* the user specified UID/GID based constraints in
* a firewall rule.
*/
struct ip_fw_ugid {
gid_t fw_groups[NGROUPS];
int fw_ngroups;
uid_t fw_uid;
int fw_prid;
};
/*
* list of rules for layer 3
*/
@ -2009,22 +1996,10 @@ dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
return (0);
}
static void
fill_ugid_cache(struct inpcb *inp, struct ip_fw_ugid *ugp)
{
struct ucred *cr;
cr = inp->inp_cred;
ugp->fw_prid = jailed(cr) ? cr->cr_prison->pr_id : -1;
ugp->fw_uid = cr->cr_uid;
ugp->fw_ngroups = cr->cr_ngroups;
bcopy(cr->cr_groups, ugp->fw_groups, sizeof(ugp->fw_groups));
}
static int
check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
struct in_addr dst_ip, u_int16_t dst_port, struct in_addr src_ip,
u_int16_t src_port, struct ip_fw_ugid *ugp, int *ugid_lookupp,
u_int16_t src_port, struct ucred **uc, int *ugid_lookupp,
struct inpcb *inp)
{
INIT_VNET_INET(curvnet);
@ -2032,7 +2007,6 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
int wildcard;
struct inpcb *pcb;
int match;
gid_t *gp;
/*
* Check to see if the UDP or TCP stack supplied us with
@ -2042,7 +2016,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
if (inp && *ugid_lookupp == 0) {
INP_LOCK_ASSERT(inp);
if (inp->inp_socket != NULL) {
fill_ugid_cache(inp, ugp);
*uc = crhold(inp->inp_cred);
*ugid_lookupp = 1;
} else
*ugid_lookupp = -1;
@ -2075,7 +2049,7 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
dst_ip, htons(dst_port),
wildcard, NULL);
if (pcb != NULL) {
fill_ugid_cache(pcb, ugp);
*uc = crhold(inp->inp_cred);
*ugid_lookupp = 1;
}
INP_INFO_RUNLOCK(pi);
@ -2091,16 +2065,11 @@ check_uidgid(ipfw_insn_u32 *insn, int proto, struct ifnet *oif,
}
}
if (insn->o.opcode == O_UID)
match = (ugp->fw_uid == (uid_t)insn->d[0]);
else if (insn->o.opcode == O_GID) {
for (gp = ugp->fw_groups;
gp < &ugp->fw_groups[ugp->fw_ngroups]; gp++)
if (*gp == (gid_t)insn->d[0]) {
match = 1;
break;
}
} else if (insn->o.opcode == O_JAIL)
match = (ugp->fw_prid == (int)insn->d[0]);
match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
else if (insn->o.opcode == O_GID)
match = groupmember((gid_t)insn->d[0], *uc);
else if (insn->o.opcode == O_JAIL)
match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
return match;
}
@ -2178,8 +2147,8 @@ ipfw_chk(struct ip_fw_args *args)
* these types of constraints, as well as decrease contention
* on pcb related locks.
*/
struct ip_fw_ugid fw_ugid_cache;
int ugid_lookup = 0;
struct ucred *ucred_cache = NULL;
int ucred_lookup = 0;
/*
* divinput_flags If non-zero, set to the IP_FW_DIVERT_*_FLAG
@ -2641,8 +2610,8 @@ do { \
(ipfw_insn_u32 *)cmd,
proto, oif,
dst_ip, dst_port,
src_ip, src_port, &fw_ugid_cache,
&ugid_lookup, args->inp);
src_ip, src_port, &ucred_cache,
&ucred_lookup, args->inp);
break;
case O_RECV:
@ -3270,6 +3239,8 @@ do { \
/* XXX statistic */
/* drop packet */
IPFW_RUNLOCK(chain);
if (ucred_cache != NULL)
crfree(ucred_cache);
return (IP_FW_DENY);
}
dt = (struct divert_tag *)(mtag+1);
@ -3475,6 +3446,8 @@ next_rule:; /* try next rule */
} /* end of outer for, scan rules */
printf("ipfw: ouch!, skip past end of rules, denying packet\n");
IPFW_RUNLOCK(chain);
if (ucred_cache != NULL)
crfree(ucred_cache);
return (IP_FW_DENY);
done:
@ -3483,6 +3456,8 @@ next_rule:; /* try next rule */
f->bcnt += pktlen;
f->timestamp = time_uptime;
IPFW_RUNLOCK(chain);
if (ucred_cache != NULL)
crfree(ucred_cache);
return (retval);
pullup_failed:

View File

@ -370,11 +370,11 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
}
tl = nfsm_dissect_nonblock(u_int32_t *, (len + 2) * NFSX_UNSIGNED);
for (i = 1; i <= len; i++)
if (i < NGROUPS)
if (i < XU_NGROUPS)
nd->nd_cr->cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
else
tl++;
nd->nd_cr->cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
nd->nd_cr->cr_ngroups = MIN(XU_NGROUPS, len + 1);
if (nd->nd_cr->cr_ngroups > 1)
nfsrvw_sort(nd->nd_cr->cr_groups, nd->nd_cr->cr_ngroups);
len = fxdr_unsigned(int, *++tl);

View File

@ -1181,9 +1181,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
cred = nfsd->nd_cr;
if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) {
cred->cr_uid = credanon->cr_uid;
for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
cred->cr_groups[i] = credanon->cr_groups[i];
cred->cr_ngroups = i;
crsetgroups(cred, credanon->cr_ngroups, credanon->cr_groups);
}
if (exflags & MNT_EXRDONLY)
*rdonlyp = 1;

View File

@ -449,11 +449,7 @@ rpc_gss_svc_getcred(struct svc_req *req, struct ucred **crp, int *flavorp)
cr = client->cl_cred = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
cr->cr_rgid = cr->cr_svgid = uc->gid;
cr->cr_ngroups = uc->gidlen;
if (cr->cr_ngroups > NGROUPS)
cr->cr_ngroups = NGROUPS;
for (i = 0; i < cr->cr_ngroups; i++)
cr->cr_groups[i] = uc->gidlist[i];
crsetgroups(cr, uc->gidlen, uc->gidlist);
*crp = crhold(cr);
return (TRUE);

View File

@ -166,7 +166,7 @@ int
svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
{
struct ucred *cr = NULL;
int flavor, i;
int flavor;
struct xucred *xcr;
flavor = rqst->rq_cred.oa_flavor;
@ -178,9 +178,7 @@ svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
xcr = (struct xucred *) rqst->rq_clntcred;
cr = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
cr->cr_ngroups = xcr->cr_ngroups;
for (i = 0; i < xcr->cr_ngroups; i++)
cr->cr_groups[i] = xcr->cr_groups[i];
crsetgroups(cr, xcr->cr_ngroups, xcr->cr_groups);
cr->cr_rgid = cr->cr_svgid = cr->cr_groups[0];
cr->cr_prison = &prison0;
prison_hold(cr->cr_prison);

View File

@ -95,13 +95,13 @@ _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg)
goto done;
}
for (i = 0; i < gid_len; i++) {
if (i + 1 < NGROUPS)
if (i + 1 < XU_NGROUPS)
xcr->cr_groups[i + 1] = IXDR_GET_INT32(buf);
else
buf++;
}
if (gid_len + 1 > NGROUPS)
xcr->cr_ngroups = NGROUPS;
if (gid_len + 1 > XU_NGROUPS)
xcr->cr_ngroups = XU_NGROUPS;
else
xcr->cr_ngroups = gid_len + 1;

View File

@ -77,7 +77,7 @@
#define MAXLOGNAME 17 /* max login name length (incl. NUL) */
#define MAXUPRC CHILD_MAX /* max simultaneous processes */
#define NCARGS ARG_MAX /* max bytes for an exec function */
#define NGROUPS NGROUPS_MAX /* max number groups */
#define NGROUPS (NGROUPS_MAX+1) /* max number groups */
#define NOFILE OPEN_MAX /* max open files per process */
#define NOGROUP 65535 /* marker for empty group set member */
#define MAXHOSTNAMELEN 256 /* max hostname size */

View File

@ -54,7 +54,9 @@
#define MAX_CANON 255 /* max bytes in term canon input line */
#define MAX_INPUT 255 /* max bytes in terminal input */
#define NAME_MAX 255 /* max bytes in a file name */
#define NGROUPS_MAX 16 /* max supplemental group id's */
#ifndef NGROUPS_MAX
#define NGROUPS_MAX 1023 /* max supplemental group id's */
#endif
#ifndef OPEN_MAX
#define OPEN_MAX 64 /* max open files per process */
#endif

View File

@ -48,8 +48,7 @@ struct ucred {
uid_t cr_uid; /* effective user id */
uid_t cr_ruid; /* real user id */
uid_t cr_svuid; /* saved user id */
short cr_ngroups; /* number of groups */
gid_t cr_groups[NGROUPS]; /* groups */
int cr_ngroups; /* number of groups */
gid_t cr_rgid; /* real group id */
gid_t cr_svgid; /* saved group id */
struct uidinfo *cr_uidinfo; /* per euid resource consumption */
@ -61,11 +60,15 @@ struct ucred {
#define cr_endcopy cr_label
struct label *cr_label; /* MAC label */
struct auditinfo_addr cr_audit; /* Audit properties. */
gid_t *cr_groups; /* groups */
int cr_agroups; /* Available groups */
};
#define NOCRED ((struct ucred *)0) /* no credential available */
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
#endif /* _KERNEL || _WANT_UCRED */
#define XU_NGROUPS 16
/*
* This is the external representation of struct ucred.
*/
@ -73,7 +76,7 @@ struct xucred {
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 */
gid_t cr_groups[XU_NGROUPS]; /* groups */
void *_cr_unused1; /* compatibility with old ucred */
};
#define XUCRED_VERSION 0
@ -82,6 +85,7 @@ struct xucred {
#define cr_gid cr_groups[0]
#ifdef _KERNEL
struct proc;
struct thread;
void change_egid(struct ucred *newcred, gid_t egid);
@ -91,6 +95,7 @@ void change_ruid(struct ucred *newcred, struct uidinfo *ruip);
void change_svgid(struct ucred *newcred, gid_t svgid);
void change_svuid(struct ucred *newcred, uid_t svuid);
void crcopy(struct ucred *dest, struct ucred *src);
struct ucred *crcopysafe(struct proc *p, struct ucred *cr);
struct ucred *crdup(struct ucred *cr);
void cred_update_thread(struct thread *td);
void crfree(struct ucred *cr);
@ -98,6 +103,7 @@ struct ucred *crget(void);
struct ucred *crhold(struct ucred *cr);
int crshared(struct ucred *cr);
void cru2x(struct ucred *cr, struct xucred *xcr);
void crsetgroups(struct ucred *cr, int n, gid_t *groups);
int groupmember(gid_t gid, struct ucred *cred);
#endif /* _KERNEL */

View File

@ -85,7 +85,7 @@
*/
#define KI_NSPARE_INT 9
#define KI_NSPARE_LONG 12
#define KI_NSPARE_PTR 7
#define KI_NSPARE_PTR 6
#ifdef __amd64__
#define KINFO_PROC_SIZE 1088
@ -117,7 +117,6 @@
#define OCOMMLEN 16 /* size of returned thread name */
#define COMMLEN 19 /* size of returned ki_comm name */
#define KI_EMULNAMELEN 16 /* size of returned ki_emul */
#define KI_NGROUPS 16 /* number of groups in ki_groups */
#define LOGNAMELEN 17 /* size of returned ki_login */
struct kinfo_proc {
@ -151,7 +150,7 @@ struct kinfo_proc {
gid_t ki_svgid; /* Saved effective group id */
short ki_ngroups; /* number of groups */
short ki_spare_short2; /* unused (just here for alignment) */
gid_t ki_groups[KI_NGROUPS]; /* groups */
uint32_t __was_ki_groups[16]; /* unused; left for bin compat */
vm_size_t ki_size; /* virtual size */
segsz_t ki_rssize; /* current resident set size in pages */
segsz_t ki_swrss; /* resident set size before last swap */
@ -201,6 +200,7 @@ struct kinfo_proc {
struct pcb *ki_pcb; /* kernel virtual addr of pcb */
void *ki_kstack; /* kernel virtual addr of stack */
void *ki_udata; /* User convenience pointer */
gid_t *ki_groups; /* groups */
/*
* When adding new variables, take space for pointers from the
* front of ki_spareptrs, and longs from the end of ki_sparelongs.

View File

@ -2266,6 +2266,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
{
#ifdef QUOTA
struct ucred ucred, *ucp;
gid_t ucred_group;
ucp = cnp->cn_cred;
#endif
/*
@ -2292,6 +2293,7 @@ ufs_makeinode(mode, dvp, vpp, cnp)
refcount_init(&ucred.cr_ref, 1);
ucred.cr_uid = ip->i_uid;
ucred.cr_ngroups = 1;
ucred.cr_groups = &ucred_group;
ucred.cr_groups[0] = pdir->i_gid;
ucp = &ucred;
#endif

View File

@ -36,6 +36,7 @@
*/
#include <sys/cdefs.h>
#include <sys/ucred.h>
#include <fs/portalfs/portal.h>
/*

View File

@ -2637,7 +2637,7 @@ parsecred(namelist, cr)
char *names;
struct passwd *pw;
struct group *gr;
gid_t groups[NGROUPS + 1];
gid_t groups[XU_NGROUPS + 1];
int ngroups;
cr->cr_version = XUCRED_VERSION;
@ -2665,7 +2665,7 @@ parsecred(namelist, cr)
return;
}
cr->cr_uid = pw->pw_uid;
ngroups = NGROUPS + 1;
ngroups = XU_NGROUPS + 1;
if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups))
syslog(LOG_ERR, "too many groups");
/*
@ -2690,7 +2690,7 @@ parsecred(namelist, cr)
return;
}
cr->cr_ngroups = 0;
while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS) {
while (names != NULL && *names != '\0' && cr->cr_ngroups < XU_NGROUPS) {
name = strsep(&names, ":");
if (isdigit(*name) || *name == '-') {
cr->cr_groups[cr->cr_ngroups++] = atoi(name);
@ -2702,7 +2702,7 @@ parsecred(namelist, cr)
cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid;
}
}
if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS)
if (names != NULL && *names != '\0' && cr->cr_ngroups == XU_NGROUPS)
syslog(LOG_ERR, "too many groups");
}