#include "afs/nfsclient.h"
#include "osi_compat.h"
-#ifdef AFS_LINUX26_ONEGROUP_ENV
-# define NUMPAGGROUPS 1
+#ifdef AFS_PAG_ONEGROUP_ENV
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)
+ if (group_info->ngroups < AFS_NUMPAGGROUPS)
return NOPAG;
for (i = 0; i < group_info->ngroups; i++) {
afs_kgid_t newkgid = afs_make_kgid(newpag);
if (afs_linux_pag_from_groups(old) == NOPAG)
- need_space = NUMPAGGROUPS;
+ need_space = AFS_NUMPAGGROUPS;
*new = groups_alloc(old->ngroups + need_space);
}
#else
-# define NUMPAGGROUPS 2
static inline afs_uint32
afs_linux_pag_from_groups(struct group_info *group_info) {
- if (group_info->ngroups < NUMPAGGROUPS)
+ if (group_info->ngroups < AFS_NUMPAGGROUPS)
return NOPAG;
return afs_get_pag_from_groups(GROUP_AT(group_info, 0), GROUP_AT(group_info, 1));
gid_t g1;
if (afs_linux_pag_from_groups(old) == NOPAG)
- need_space = NUMPAGGGROUPS;
+ need_space = AFS_NUMPAGGROUPS;
*new = groups_alloc(old->ngroups + need_space);
return code;
}
-
+#ifndef LINUX_KEYRING_SUPPORT
/* Intercept the standard system call. */
extern asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
asmlinkage long
return (-code);
}
-#if defined(AFS_PPC64_LINUX20_ENV)
+# if defined(AFS_PPC64_LINUX20_ENV)
/* Intercept the uid16 system call as used by 32bit programs. */
extern asmlinkage long (*sys32_setgroupsp)(int gidsetsize, gid_t *grouplist);
asmlinkage long afs32_xsetgroups(int gidsetsize, gid_t *grouplist)
/* Linux syscall ABI returns errno as negative */
return (-code);
}
-#endif
+# endif
-#if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_AMD64_LINUX20_ENV)
+# if defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_AMD64_LINUX20_ENV)
/* Intercept the uid16 system call as used by 32bit programs. */
-#ifdef AFS_AMD64_LINUX20_ENV
+# ifdef AFS_AMD64_LINUX20_ENV
extern asmlinkage long (*sys32_setgroupsp) (int gidsetsize, u16 * grouplist);
-#endif /* AFS_AMD64_LINUX20_ENV */
-#ifdef AFS_SPARC64_LINUX26_ENV
+# endif /* AFS_AMD64_LINUX20_ENV */
+# ifdef AFS_SPARC64_LINUX26_ENV
extern asmlinkage int (*sys32_setgroupsp) (int gidsetsize,
__kernel_gid32_t * grouplist);
-#endif /* AFS_SPARC64_LINUX26_ENV */
+# endif /* AFS_SPARC64_LINUX26_ENV */
asmlinkage long
afs32_xsetgroups(int gidsetsize, u16 * grouplist)
{
}
/* Intercept the uid32 system call as used by 32bit programs. */
-#ifdef AFS_AMD64_LINUX20_ENV
+# ifdef AFS_AMD64_LINUX20_ENV
extern asmlinkage long (*sys32_setgroups32p) (int gidsetsize, gid_t * grouplist);
-#endif /* AFS_AMD64_LINUX20_ENV */
-#ifdef AFS_SPARC64_LINUX26_ENV
+# endif /* AFS_AMD64_LINUX20_ENV */
+# ifdef AFS_SPARC64_LINUX26_ENV
extern asmlinkage int (*sys32_setgroups32p) (int gidsetsize,
__kernel_gid32_t * grouplist);
-#endif /* AFS_SPARC64_LINUX26_ENV */
+# endif /* AFS_SPARC64_LINUX26_ENV */
asmlinkage long
afs32_xsetgroups32(int gidsetsize, gid_t * grouplist)
{
/* Linux syscall ABI returns errno as negative */
return (-code);
}
-#endif
-
+# endif
+#endif /* !LINUX_KEYRING_SUPPORT */
#ifdef LINUX_KEYRING_SUPPORT
static void afs_pag_describe(const struct key *key, struct seq_file *m)
if (*userpag != pag)
goto error;
+#if defined(STRUCT_KEY_HAS_PAYLOAD_VALUE)
key->payload.value = (unsigned long) *userpag;
+#else
+ memcpy(&key->payload, userpag, sizeof(afs_uint32));
+#endif
key->datalen = sizeof(afs_uint32);
code = 0;
return code;
}
-#if defined(STRUCT_KEY_TYPE_HAS_MATCH)
+#if !defined(STRUCT_KEY_TYPE_HAS_MATCH_PREPARSE)
+/* Note that we only define a ->match function if struct
+ * key_type.match_preparse does _not_ exist. If key_type.match_preparse does
+ * exist, we would use that to specify an alternative comparison function; but
+ * since we just rely on default behavior, we don't need to actually specify
+ * one. But for kernels with no such match_preparse function, we need to
+ * specify a 'match' function, since there is no default. */
static int afs_pag_match(const struct key *key, const void *description)
{
return strcmp(key->description, description) == 0;
static void afs_pag_destroy(struct key *key)
{
- afs_uint32 pag = key->payload.value;
+ afs_uint32 pag;
int locked = ISAFS_GLOCK();
+#if defined(STRUCT_KEY_HAS_PAYLOAD_VALUE)
+ pag = key->payload.value;
+#else
+ memcpy(&pag, &key->payload, sizeof(afs_uint32));
+#endif
+
if (!locked)
AFS_GLOCK();
#else
.instantiate = afs_pag_instantiate,
#endif
-#if defined(STRUCT_KEY_TYPE_HAS_MATCH)
+#if !defined(STRUCT_KEY_TYPE_HAS_MATCH_PREPARSE)
.match = afs_pag_match,
#endif
.destroy = afs_pag_destroy,
if (!IS_ERR(key)) {
if (key_validate(key) == 0 && uid_eq(key->uid, GLOBAL_ROOT_UID)) { /* also verify in the session keyring? */
+#if defined(STRUCT_KEY_HAS_PAYLOAD_VALUE)
keyring_pag = key->payload.value;
+#else
+ memcpy(&keyring_pag, &key->payload, sizeof(afs_int32));
+#endif
/* Only set PAG in groups if needed,
* and the creds are from the current process */
if (afs_linux_cred_is_current(cred) &&