Hi,
I think I'm almost there with a (preliminary but working in my test
machine) setag function.
It is mostly a copy of setpag code with an added parameter specifying the
keyring type (diff of src/afs/LINUX/osi_groups.c is attached) and
a few lines to store thread/process/session keyrings.
setag, to work consistently, requires the LINUX_KEYRING_SUPPORT code in
PagInCred to be moved at the beginning of PagInCred as suggested
in a previous post.
My concerns are:
1. as in previous code any preexistent keyring is replaced,
is this acceptable ?
2. is frustrating not to have exported necessary functions from
the kerel, a previous thread in this list concluded, as I
undestand, that there is no option, still true ?
3. the name of the installed keyring is ``_afs.``
nobody seems to care about the name as i know,
but the kernel code use different names for different
keryring types ... opinions ?
4. what about other architectures ?
To test the function i'm still using a syscall but i'd like to try a
new pioctl; any advice ? Really the code is not so easy so any help
would be good (e.g. where to start !)
Thank you,
Alberto.
On Fri, 7 Aug 2009, Chas Williams (CONTRACTOR) wrote:
In message <[email protected]>,Derric
k Brashear writes:
What we are discussing is not a PAG but a Thread Authentication
Credential which when set overrides the process credential as obtained
from the PAG or uid.
It's not necessarily a single credential; it could also be a group.
i was thinking that it should be something like set_ag(.., CONTEXT,
...) where context is thread, session (process) or whatever. some
operating systems will not (or currently do not) support thread context,
so you would fall back to the next highest context, like process or session.
anyway, i was just mention that we atleast need to drop the p since it
isnt a process group anymore. ag feels stupid though.
_______________________________________________
OpenAFS-devel mailing list
[email protected]
https://lists.openafs.org/mailman/listinfo/openafs-devel
diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c
index bf9f8a0..0a7abc4 100644
--- a/src/afs/LINUX/osi_groups.c
+++ b/src/afs/LINUX/osi_groups.c
@@ -11,6 +11,7 @@
* Implements:
* setgroups (syscall)
* setpag
+ * setag
*
*/
#include <afsconfig.h>
@@ -286,6 +287,112 @@ install_session_keyring(struct key *keyring)
out:
return code;
}
+
+
+
+struct key *prepare_keyring(int *ret_code)
+{
+
+ char desc[20];
+ unsigned long not_in_quota;
+
+ int code = -EINVAL;
+ struct key *keyring = NULL;
+
+ if (!__key_type_keyring)
+ goto out;
+
+
+ /* create an empty keyring */
+ not_in_quota = KEY_ALLOC_IN_QUOTA;
+
+ /* to remember this is an afs_keyring :) */
+ sprintf(desc, "_afs.%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,
+ current_uid(), current_gid(),
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
+ not_in_quota);
+#endif
+ if (IS_ERR(keyring)) {
+ code = PTR_ERR(keyring);
+ keyring = NULL;
+ goto out;
+ }
+
+ code = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
+ if (code < 0) {
+ key_put(keyring);
+ keyring = NULL;
+ goto out;
+ }
+ code = 0;
+
+ out:
+ *ret_code = code;
+ return keyring;
+}
+
+
+
+
+static int
+install_keyring(struct key *keyring, int ag_type)
+{
+ struct key *old;
+
+ /* install the keyring */
+
+ switch(ag_type) {
+ case -3:
+ /* session, install_session_keyring code */
+ spin_lock_irq(¤t->sighand->siglock);
+ old = task_session_keyring(current);
+ smp_wmb();
+ task_session_keyring(current) = keyring;
+ spin_unlock_irq(¤t->sighand->siglock);
+ break;
+ case -2:
+ /* install_process_keyring */
+ spin_lock_irq(¤t->sighand->siglock);
+ old = task_process_keyring(current);
+ task_process_keyring(current) = keyring;
+ spin_unlock_irq(¤t->sighand->siglock);
+ break;
+ case -1:
+ /* install_thread_keyring */
+ task_lock(current);
+ old = task_thread_keyring(current);
+ task_thread_keyring(current) = keyring;
+ task_unlock(current);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (old)
+ key_put(old);
+
+ return 0;
+}
+
+
+
+
+
+
+
+
#endif /* LINUX_KEYRING_SUPPORT */
#else
@@ -369,6 +476,72 @@ setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32
*newpag,
return code;
}
+int
+setag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag,
+ int change_parent,int ag_type)
+{
+ int code;
+
+ AFS_STATCNT(setpag);
+
+
+ //printf("entering setAG code %d\n",ag_type);
+
+ if(ag_type > -1 || ag_type < -3)
+ return -EINVAL;
+
+ //printf("pagvalue= %d\n",pagvalue);
+
+
+ code = __setpag(cr, pagvalue, newpag, change_parent);
+
+ //printf("newpag = %d\n",*newpag);
+
+#ifdef LINUX_KEYRING_SUPPORT
+ if (code == 0 && (*cr)->cr_rgid != NFSXLATOR_CRED) {
+
+ struct key *keyring = NULL;
+
+ keyring = prepare_keyring(&code);
+ if(code != 0)
+ return code;
+
+ code = install_keyring(keyring,ag_type);
+ if(code != 0)
+ return code;
+
+ if (keyring) {
+
+ struct key *key;
+ key_perm_t perm;
+
+ //printf("preparing key, keyring stored\n");
+
+ 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
+
+ if (!IS_ERR(key)) {
+ key_instantiate_and_link(key, (void *) newpag, sizeof(afs_uint32),
+ keyring, NULL);
+ key_put(key);
+ }
+ }
+ }
+#endif /* LINUX_KEYRING_SUPPORT */
+
+
+ //printf("exiting setAG type %d code: %d\n",ag_type,code);
+
+ return code;
+}
/* Intercept the standard system call. */
extern asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h
index 7335c0b..ce1044a 100644
--- a/src/afs/LINUX/osi_machdep.h
+++ b/src/afs/LINUX/osi_machdep.h
@@ -192,8 +192,17 @@ typedef struct afs_cred { /* maps to task field:
*/
#define task_uid(task) (task->uid)
#endif
#define task_user(task) (task->user)
+
#define task_session_keyring(task) (task->signal->session_keyring)
#define current_session_keyring() (current->signal->session_keyring)
+
+#define task_process_keyring(task) (task->signal->process_keyring)
+#define current_process_keyring() (current->signal->process_keyring)
+
+#define task_thread_keyring(task) (task->thread_keyring)
+#define current_thread_keyring() (current->thread_keyring)
+
+
#endif
#define crhold(c) (c)->cr_ref++