#include <linux/smp_lock.h>
#ifdef AFS_LINUX26_ONEGROUP_ENV
-#define NUMPAGGROUPS 1
+# define NUMPAGGROUPS 1
+
+static afs_uint32
+afs_linux_pag_from_groups(struct group_info *group_info) {
+ afs_uint32 g0 = 0;
+ afs_uint32 i;
+
+ if (group_info->ngroups < NUMPAGGROUPS)
+ return NOPAG;
+
+ 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;
+}
+
+static inline void
+afs_linux_pag_to_groups(afs_uint32 newpag,
+ struct group_info *old, struct group_info **new) {
+ int need_space = 0;
+ int i;
+ int j;
+
+ if (afs_linux_pag_from_groups(old) == NOPAG)
+ need_space = NUMPAGGROUPS;
+
+ *new = groups_alloc(old->ngroups + need_space);
+
+ for (i = 0, j = 0; i < old->ngroups; ++i) {
+ int ths = GROUP_AT(old, i);
+ int last = i > 0 ? GROUP_AT(old, i-1) : 0;
+ if ((ths >> 24) == 'A')
+ continue;
+ if (last <= newpag && ths > newpag) {
+ GROUP_AT(*new, j) = newpag;
+ j++;
+ }
+ GROUP_AT(*new, j) = ths;
+ j++;
+ }
+ if (j != i + need_space)
+ GROUP_AT(*new, j) = newpag;
+}
+
#else
-#define NUMPAGGROUPS 2
+# define NUMPAGGROUPS 2
+
+static inline afs_uint32
+afs_linux_pag_from_groups(struct group_info *group_info) {
+
+ if (group_info->ngroups < NUMPAGGROUPS)
+ return NOPAG;
+
+ return afs_get_pag_from_groups(GROUP_AT(group_info, 0), GROUP_AT(group_info, 1));
+}
+
+static inline void
+afs_linux_pag_to_groups(afs_uint32 newpag,
+ struct group_info *old, struct group_info *new) {
+ int need_space = 0;
+ int i;
+ gid_t g0;
+ gid_t g1;
+
+ if (afs_linux_pag_from_groups(old) == NOPAG)
+ need_space = NUMPAGGGROUPS;
+
+ *new = groups_alloc(old->ngroups + need_space);
+
+ for (i = 0; i < old->ngroups; ++i)
+ GROUP_AT(new, i + need_space) = GROUP_AT(old, i);
+
+ afs_get_groups_from_pag(newpag, &g0, g1);
+ GROUP_AT(new, 0) = g0;
+ GROUP_AT(new, 1) = g1;
+}
#endif
+afs_int32
+osi_get_group_pag(afs_ucred_t *cred) {
+ return afs_linux_pag_from_groups(afs_cr_group_info(cred));
+}
+
+
static int
afs_setgroups(cred_t **cr, struct group_info *group_info, int change_parent)
{
return (0);
}
-/* Returns number of groups. And we trust groups to be large enough to
- * hold all the groups.
- */
-static struct group_info *
-afs_getgroups(cred_t * cr)
-{
- AFS_STATCNT(afs_getgroups);
-
- get_group_info(afs_cr_group_info(cr));
- return afs_cr_group_info(cr);
-}
int
__setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
int change_parent)
{
struct group_info *group_info;
-#ifndef AFS_LINUX26_ONEGROUP_ENV
- gid_t g0, g1;
-#endif
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 < 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 = NUMPAGGROUPS;
+ get_group_info(afs_cr_group_info(*cr));
+ group_info = afs_cr_group_info(*cr);
- 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
+ afs_linux_pag_to_groups(*newpag, group_info, &tmp);
+
put_group_info(group_info);
group_info = tmp;
-#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);
put_group_info(group_info);
{
int code;
afs_uint32 *userpag, pag = NOPAG;
-#ifndef AFS_LINUX26_ONEGROUP_ENV
- int g0, g1;
-#endif
if (key->uid != 0 || key->gid != 0)
return -EPERM;
if (datalen != sizeof(afs_uint32) || !data)
goto error;
- 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_linux_pag_from_groups(current_group_info());
- pag = afs_get_pag_from_groups(g0, g1);
-#endif
if (pag == NOPAG)
goto error;
* and the creds are from the current process */
if (afs_linux_cred_is_current(cred) &&
((keyring_pag >> 24) & 0xff) == 'A' &&
- keyring_pag != afs_get_pag_from_groups(current_group_info())) {
+ keyring_pag != afs_linux_pag_from_groups(current_group_info())) {
__setpag(&cred, keyring_pag, &newpag, 0);
}
}
return 0;
}
-
-#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
+#ifndef AFS_LINUX26_ONEGROUP_ENV
afs_uint32
afs_get_pag_from_groups(gid_t g0a, gid_t g1a)
{
h = (g0 >> 14);
h = (g1 >> 14) + h + h + h;
ret = ((h << 28) | l);
-#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+# if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
return ret;
-#else
+# else
/* Additional testing */
if (((ret >> 24) & 0xff) == 'A')
return ret;
-#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
+# endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
}
return NOPAG;
}
-#endif
void
afs_get_groups_from_pag(afs_uint32 pag, gid_t * g0p, gid_t * g1p)
{
-#ifndef AFS_LINUX26_ONEGROUP_ENV
unsigned short g0, g1;
-#endif
-
AFS_STATCNT(afs_get_groups_from_pag);
-#ifdef AFS_LINUX26_ONEGROUP_ENV
*g0p = pag;
*g1p = 0;
-#else
-#if !defined(UKERNEL) || !defined(AFS_WEB_ENHANCEMENTS)
+# if !defined(UKERNEL) || !defined(AFS_WEB_ENHANCEMENTS)
pag &= 0x7fffffff;
-#endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
+# endif /* UKERNEL && AFS_WEB_ENHANCEMENTS */
g0 = 0x3fff & (pag >> 14);
g1 = 0x3fff & pag;
g0 |= ((pag >> 28) / 3) << 14;
g1 |= ((pag >> 28) % 3) << 14;
*g0p = g0 + 0x3f00;
*g1p = g1 + 0x3f00;
-#endif
}
+#else
+void afs_get_groups_from_pag(afs_uint32 pag, gid_t *g0p, gid_t *g1p)
+{
+ AFS_STATCNT(afs_get_groups_from_pag);
+ *g0p = pag;
+ *g1p = 0;
+}
+#endif
-
-afs_int32
-afs_get_group_pag(afs_ucred_t *cred)
+#ifndef AFS_LINUX26_ENV
+static afs_int32
+osi_get_group_pag(afs_ucred_t *cred)
{
afs_int32 pag = NOPAG;
-#if !defined(AFS_LINUX26_ONEGROUP_ENV)
gid_t g0, g1;
-#endif
#if defined(AFS_SUN510_ENV)
const gid_t *gids;
int ngroups;
g0 = cred->cr_groups[1];
g1 = cred->cr_groups[2];
#else
-#if defined(AFS_AIX_ENV)
+# if defined(AFS_AIX_ENV)
if (cred->cr_ngrps < 2)
return NOPAG;
-#elif defined(AFS_LINUX26_ENV)
+# elif defined(AFS_LINUX26_ENV)
if (afs_cr_group_info(cred)->ngroups < NUMPAGGROUPS)
return NOPAG;
-#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
-#if defined(AFS_SUN510_ENV)
+# elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_XBSD_ENV)
+# if defined(AFS_SUN510_ENV)
if (ngroups < 2) {
-#else
+# else
if (cred->cr_ngroups < 2) {
-#endif
+# endif
return NOPAG;
}
-#endif
-#if defined(AFS_AIX51_ENV)
+# endif
+# 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(afs_cr_group_info(cred), 0);
- g1 = GROUP_AT(afs_cr_group_info(cred), 1);
#elif defined(AFS_SUN510_ENV)
g0 = gids[0];
g1 = gids[1];
g1 = cred->cr_groups[1];
#endif
#endif
-#if defined(AFS_LINUX26_ONEGROUP_ENV)
- pag = (afs_int32) afs_get_pag_from_groups(afs_cr_group_info(cred));
-#else
pag = (afs_int32) afs_get_pag_from_groups(g0, g1);
-#endif
return pag;
}
+#endif
afs_int32
* to looking at the keyrings.
*/
# if !defined(STRUCT_TASK_HAS_CRED)
- pag = afs_get_group_pag(cred);
+ pag = osi_get_group_pag(cred);
# endif
if (pag == NOPAG)
pag = osi_get_keyring_pag(cred);
#else
- pag = afs_get_group_pag(cred);
+ pag = osi_get_group_pag(cred);
#endif
return pag;
}