diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c index a754cb60f8..fa1cbe12c7 100644 --- a/src/afs/LINUX/osi_groups.c +++ b/src/afs/LINUX/osi_groups.c @@ -29,6 +29,12 @@ RCSID #include "h/smp_lock.h" #endif +#ifdef AFS_LINUX26_ONEGROUP_ENV +#define NUMPAGGROUPS 1 +#else +#define NUMPAGGROUPS 2 +#endif + #if defined(AFS_LINUX26_ENV) static int afs_setgroups(cred_t **cr, struct group_info *group_info, int change_parent) @@ -160,26 +166,53 @@ __setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, gid_t g0, g1; struct group_info *tmp; int i; +#ifdef AFS_LINUX26_ONEGROUP_ENV + int j; +#endif int need_space = 0; group_info = afs_getgroups(*cr); - if (group_info->ngroups < 2 - || afs_get_pag_from_groups(GROUP_AT(group_info, 0), - GROUP_AT(group_info, 1)) == NOPAG) + if (group_info->ngroups < NUMPAGGROUPS + || afs_get_pag_from_groups( +#ifdef AFS_LINUX26_ONEGROUP_ENV + group_info +#else + GROUP_AT(group_info, 0) ,GROUP_AT(group_info, 1) +#endif + ) == NOPAG) /* We will have to make sure group_info is big enough for pag */ - need_space = 2; + need_space = NUMPAGGROUPS; tmp = groups_alloc(group_info->ngroups + need_space); + *newpag = (pagvalue == -1 ? genpag() : pagvalue); +#ifdef AFS_LINUX26_ONEGROUP_ENV + for (i = 0, j = 0; i < group_info->ngroups; ++i) { + int ths = GROUP_AT(group_info, i); + int last = i > 0 ? GROUP_AT(group_info, i-1) : 0; + if ((ths >> 24) == 'A') + continue; + if (last <= *newpag && ths > *newpag) { + GROUP_AT(tmp, j) = *newpag; + j++; + } + GROUP_AT(tmp, j) = ths; + j++; + } + if (j != i + need_space) + GROUP_AT(tmp, j) = *newpag; +#else for (i = 0; i < group_info->ngroups; ++i) GROUP_AT(tmp, i + need_space) = GROUP_AT(group_info, i); +#endif put_group_info(group_info); group_info = tmp; - *newpag = (pagvalue == -1 ? genpag() : pagvalue); +#ifndef AFS_LINUX26_ONEGROUP_ENV afs_get_groups_from_pag(*newpag, &g0, &g1); GROUP_AT(group_info, 0) = g0; GROUP_AT(group_info, 1) = g1; +#endif afs_setgroups(cr, group_info, change_parent); @@ -524,15 +557,18 @@ static int afs_pag_instantiate(struct key *key, const void *data, size_t datalen if (datalen != sizeof(afs_uint32) || !data) goto error; - if (current->group_info->ngroups < 2) + if (current->group_info->ngroups < NUMPAGGROUPS) goto error; /* ensure key being set matches current pag */ - +#ifdef AFS_LINUX26_ONEGROUP_ENV + pag = afs_get_pag_from_groups(current->group_info); +#else g0 = GROUP_AT(current->group_info, 0); g1 = GROUP_AT(current->group_info, 1); pag = afs_get_pag_from_groups(g0, g1); +#endif if (pag == NOPAG) goto error; diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h index 9c78febf04..52488af124 100644 --- a/src/afs/LINUX/osi_machdep.h +++ b/src/afs/LINUX/osi_machdep.h @@ -15,6 +15,11 @@ #ifndef OSI_MACHDEP_H_ #define OSI_MACHDEP_H_ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4) +#define AFS_LINUX26_ONEGROUP_ENV 1 +#endif + /* Only needed for xdr.h in glibc 2.1.x */ #ifndef quad_t #define quad_t __quad_t diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c index 8137c8bf47..f7da6aa219 100644 --- a/src/afs/afs_osi_pag.c +++ b/src/afs/afs_osi_pag.c @@ -44,6 +44,11 @@ afs_uint32 pagCounter = 1; afs_uint32 pagCounter = 0; #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ +#ifdef AFS_LINUX26_ONEGROUP_ENV +#define NUMPAGGROUPS 1 +#else +#define NUMPAGGROUPS 2 +#endif /* Local variables */ /* @@ -363,6 +368,7 @@ afs_setpag_val(int pagval) return (code); } +#ifndef AFS_LINUX26_ONEGROUP_ENV int afs_getpag_val() { @@ -376,13 +382,13 @@ afs_getpag_val() gidset0 = gids[0]; gidset1 = gids[1]; #else - gidset0 = credp->cr_groups[0]; gidset1 = credp->cr_groups[1]; #endif pagvalue = afs_get_pag_from_groups(gidset0, gidset1); return pagvalue; } +#endif #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ @@ -441,7 +447,22 @@ afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred) } +#ifdef AFS_LINUX26_ONEGROUP_ENV +afs_uint32 +afs_get_pag_from_groups(struct group_info *group_info) +{ + afs_uint32 g0 = 0; + afs_uint32 i; + AFS_STATCNT(afs_get_pag_from_groups); + for (i = 0; (i < group_info->ngroups && + (g0 = GROUP_AT(group_info, i)) != (gid_t) NOGROUP); i++) { + if (((g0 >> 24) & 0xff) == 'A') + return g0; + } + return NOPAG; +} +#else afs_uint32 afs_get_pag_from_groups(gid_t g0a, gid_t g1a) { @@ -450,6 +471,7 @@ afs_get_pag_from_groups(gid_t g0a, gid_t g1a) afs_uint32 h, l, ret; AFS_STATCNT(afs_get_pag_from_groups); + g0 -= 0x3f00; g1 -= 0x3f00; if (g0 < 0xc000 && g1 < 0xc000) { @@ -467,7 +489,7 @@ afs_get_pag_from_groups(gid_t g0a, gid_t g1a) } return NOPAG; } - +#endif void afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p) @@ -476,6 +498,10 @@ afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p) AFS_STATCNT(afs_get_groups_from_pag); +#ifdef AFS_LINUX26_ONEGROUP_ENV + *g0p = pag; + *g1p = 0; +#else #if !defined(UKERNEL) || !defined(AFS_WEB_ENHANCEMENTS) pag &= 0x7fffffff; #endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */ @@ -485,6 +511,7 @@ afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p) g1 |= ((pag >> 28) % 3) << 14; *g0p = g0 + 0x3f00; *g1p = g1 + 0x3f00; +#endif } @@ -525,7 +552,7 @@ PagInCred(const struct AFS_UCRED *cred) return NOPAG; } #elif defined(AFS_LINUX26_ENV) - if (cred->cr_group_info->ngroups < 2) { + if (cred->cr_group_info->ngroups < NUMPAGGROUPS) { pag = NOPAG; goto out; } @@ -542,6 +569,7 @@ PagInCred(const struct AFS_UCRED *cred) #if defined(AFS_AIX51_ENV) g0 = cred->cr_groupset.gs_union.un_groups[0]; g1 = cred->cr_groupset.gs_union.un_groups[1]; +#elif defined(AFS_LINUX26_ONEGROUP_ENV) #elif defined(AFS_LINUX26_ENV) g0 = GROUP_AT(cred->cr_group_info, 0); g1 = GROUP_AT(cred->cr_group_info, 1); @@ -553,7 +581,11 @@ PagInCred(const struct AFS_UCRED *cred) g1 = cred->cr_groups[1]; #endif #endif +#if defined(AFS_LINUX26_ONEGROUP_ENV) + pag = (afs_int32) afs_get_pag_from_groups(cred->cr_group_info); +#else pag = (afs_int32) afs_get_pag_from_groups(g0, g1); +#endif out: #if defined(AFS_LINUX26_ENV) && defined(LINUX_KEYRING_SUPPORT) if (pag == NOPAG) { diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 188b11845f..74d7c6c74e 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -508,7 +508,13 @@ extern int AddPag(struct proc *p, afs_int32 aval, struct AFS_UCRED **credpp); extern int AddPag(afs_int32 aval, struct AFS_UCRED **credpp); #endif extern int afs_InitReq(register struct vrequest *av, struct AFS_UCRED *acred); +#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) extern afs_uint32 afs_get_pag_from_groups(gid_t g0a, gid_t g1a); +#else +#ifdef AFS_LINUX26_ONEGROUP_ENV +extern afs_uint32 afs_get_pag_from_groups(struct group_info *gi); +#endif +#endif extern void afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p); extern afs_int32 PagInCred(const struct AFS_UCRED *cred);