Linux: Simplify keyring compatibility code
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Sat, 19 Dec 2009 20:21:36 +0000 (20:21 +0000)
committerDerrick Brashear <shadow|account-1000005@unknown>
Sun, 20 Dec 2009 18:03:56 +0000 (10:03 -0800)
This introduces a few inline functions in osi_compat.h, to reduce the
number of #ifdefs in the main chunk of code. In particular, we gain
  * afs_linux_key_alloc : to handle all the different key_alloc
                          signatures
  * afs_linux_search_keyring : to handle our two different mechanisms
                               for searching a keyring
  * afs_linux_cred_is_current : will return true if we're using native
credentials, and the passed creds are also
those of the current task

Change-Id: I138f3533a7e8e88e04e4b5508158e003882d63ee
Reviewed-on: http://gerrit.openafs.org/1005
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

src/afs/LINUX/osi_compat.h
src/afs/LINUX/osi_groups.c

index bcbb42a..090851d 100644 (file)
@@ -136,4 +136,56 @@ init_once_func(void * foo) {
 #define KALLOC_TYPE GFP_KERNEL
 #endif
 
+static inline struct key *
+afs_linux_key_alloc(struct key_type *type, const char *desc, uid_t uid,
+                   gid_t gid, key_perm_t perm, unsigned long flags)
+{
+#if defined(KEY_ALLOC_NEEDS_STRUCT_TASK)
+    return key_alloc(type, desc, uid, gid, current, perm, flags);
+#elif defined(KEY_ALLOC_NEEDS_CRED)
+    return key_alloc(type, desc, uid, gid, current_cred(), perm, flags);
+#else
+    return key_alloc(type, desc, uid, gid, perm, flags);
+#endif
+}
+
+#if defined(STRUCT_TASK_HAS_CRED)
+static inline struct key*
+afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
+{
+    key_ref_t key_ref;
+
+    if (cred->tgcred->session_keyring) {
+       key_ref = keyring_search(
+                     make_key_ref(cred->tgcred->session_keyring, 1),
+                     type, "_pag");
+       if (IS_ERR(key_ref))
+           return ERR_CAST(key_ref);
+
+       return key_ref_to_ptr(key_ref);
+    }
+
+    return ERR_PTR(-ENOKEY);
+}
+
+static inline int
+afs_linux_cred_is_current(afs_ucred_t *cred)
+{
+    return (cred == current_cred());
+}
+
+#else
+static inline struct key*
+afs_linux_search_keyring(afs_ucred_t *cred, struct key_type *type)
+{
+    return request_key(type, "_pag", NULL);
+}
+
+static inline int
+afs_linux_cred_is_current(afs_ucred_t *cred, cred)
+{
+    return 1;
+}
+#endif
+
 #endif
index 891cf07..e37e8c9 100644 (file)
@@ -24,6 +24,8 @@
 #include "afsincludes.h"
 #include "afs/afs_stats.h"     /* statistics */
 #include "afs/nfsclient.h"
+#include "osi_compat.h"
+
 #include <linux/smp_lock.h>
 
 #ifdef AFS_LINUX26_ONEGROUP_ENV
@@ -143,7 +145,6 @@ install_session_keyring(struct key *keyring)
 {
     struct key *old;
     char desc[20];
-    unsigned long not_in_quota;
     int code = -EINVAL;
 
     if (!__key_type_keyring)
@@ -152,25 +153,14 @@ install_session_keyring(struct key *keyring)
     if (!keyring) {
 
        /* create an empty session keyring */
-       not_in_quota = KEY_ALLOC_IN_QUOTA;
        sprintf(desc, "_ses.%u", current->tgid);
 
-#if defined(KEY_ALLOC_NEEDS_STRUCT_TASK)
-       keyring = key_alloc(__key_type_keyring, desc,
-                           current_uid(), current_gid(), current,
-                           (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
-                           not_in_quota);
-#elif defined(KEY_ALLOC_NEEDS_CRED)
-       keyring = key_alloc(__key_type_keyring, desc,
-                           current_uid(), current_gid(), current_cred(),
-                           (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
-                           not_in_quota);
-#else
-       keyring = key_alloc(__key_type_keyring, desc,
+       keyring = afs_linux_key_alloc(
+                           __key_type_keyring, desc,
                            current_uid(), current_gid(),
                            (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
-                           not_in_quota);
-#endif
+                           KEY_ALLOC_IN_QUOTA);
+
        if (IS_ERR(keyring)) {
            code = PTR_ERR(keyring);
            goto out;
@@ -219,13 +209,7 @@ setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
            perm = KEY_POS_VIEW | KEY_POS_SEARCH;
            perm |= KEY_USR_VIEW | KEY_USR_SEARCH;
 
-#if defined(KEY_ALLOC_NEEDS_STRUCT_TASK)
-           key = key_alloc(&key_type_afs_pag, "_pag", 0, 0, current, perm, 1);
-#elif defined(KEY_ALLOC_NEEDS_CRED)
-           key = key_alloc(&key_type_afs_pag, "_pag", 0, 0, current_cred(), perm, 1);
-#else
-           key = key_alloc(&key_type_afs_pag, "_pag", 0, 0, perm, 1);
-#endif
+           key = afs_linux_key_alloc(&key_type_afs_pag, "_pag", 0, 0, perm, 1);
 
            if (!IS_ERR(key)) {
                key_instantiate_and_link(key, (void *) newpag, sizeof(afs_uint32),
@@ -559,36 +543,16 @@ osi_get_keyring_pag(afs_ucred_t *cred)
     afs_int32 keyring_pag = NOPAG;
 
     if (afs_cr_rgid(cred) != NFSXLATOR_CRED) {
+       key = afs_linux_search_keyring(cred, &key_type_afs_pag);
 
-#if defined(STRUCT_TASK_HAS_CRED)
-       /* If we have a kernel cred, search the passed credentials */
-       if (cred->tgcred->session_keyring) {
-           key_ref_t key_ref;
-
-           key_ref = keyring_search(
-                         make_key_ref(cred->tgcred->session_keyring, 1),
-                         &key_type_afs_pag, "_pag");
-           if (IS_ERR(key_ref))
-               key = ERR_CAST(key_ref);
-           else
-               key = key_ref_to_ptr(key_ref);
-       } else {
-           key = ERR_PTR(-ENOKEY);
-       }
-#else
-       /* Search the keyrings of the current process */
-       key = request_key(&key_type_afs_pag, "_pag", NULL);
-#endif
        if (!IS_ERR(key)) {
            if (key_validate(key) == 0 && key->uid == 0) {      /* also verify in the session keyring? */
                keyring_pag = key->payload.value;
-               /* Only set PAG in groups if needed, and the creds are from the current process */
-#if defined(STRUCT_TASK_HAS_CRED)
-               if (cred == current_cred() && ((keyring_pag >> 24) & 0xff) == 'A') {
-#else
-               if (((keyring_pag >> 24) & 0xff) == 'A') {
-#endif
-                   if (keyring_pag != afs_get_pag_from_groups(current_group_info()))
+               /* Only set PAG in groups if needed,
+                * 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())) {
                        __setpag(&cred, keyring_pag, &newpag, 0);
                }
            }