2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * osi_cred.c - Linux cred handling routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
20 #include "afs/sysincludes.h"
21 #include "afsincludes.h"
23 /* Setup a pool for creds. Allocate several at a time. */
24 #define CRED_ALLOC_STEP 29 /* at 140 bytes/cred = 4060 bytes. */
27 static cred_t *cred_pool = NULL;
31 /* Cred locking assumes current single threaded non-preemptive kernel.
32 * Also assuming a fast path through both down and up if no waiters. Otherwise,
33 * test if no creds in pool before grabbing lock in crfree().
35 #if defined(AFS_LINUX24_ENV)
36 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
37 static DEFINE_MUTEX(linux_cred_pool_lock);
39 static DECLARE_MUTEX(linux_cred_pool_lock);
42 static struct semaphore linux_cred_pool_lock = MUTEX;
44 #define CRED_LOCK() down(&linux_cred_pool_lock)
45 #define CRED_UNLOCK() up(&linux_cred_pool_lock)
56 cred_pool = (cred_t *) osi_Alloc(CRED_ALLOC_STEP * sizeof(cred_t));
58 osi_Panic("crget: No more memory for creds!\n");
60 for (i = 0; i < CRED_ALLOC_STEP - 1; i++)
61 cred_pool[i].cr_next = (cred_t *) &cred_pool[i + 1];
62 cred_pool[i].cr_next = NULL;
65 cred_pool = (cred_t *) tmp->cr_next;
69 memset(tmp, 0, sizeof(cred_t));
82 #if defined(AFS_LINUX26_ENV)
83 put_group_info(cr->cr_group_info);
86 cr->cr_next = (cred_t *) cred_pool;
93 /* Return a duplicate of the cred. */
97 cred_t *tmp = crget();
99 tmp->cr_uid = cr->cr_uid;
100 tmp->cr_ruid = cr->cr_ruid;
101 tmp->cr_gid = cr->cr_gid;
103 #if defined(AFS_LINUX26_ENV)
104 get_group_info(cr->cr_group_info);
105 tmp->cr_group_info = cr->cr_group_info;
107 memcpy(tmp->cr_groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
108 tmp->cr_ngroups = cr->cr_ngroups;
118 cred_t *cr = crget();
120 cr->cr_uid = current->fsuid;
121 cr->cr_ruid = current->uid;
122 cr->cr_gid = current->fsgid;
123 cr->cr_rgid = current->gid;
125 #if defined(AFS_LINUX26_ENV)
127 get_group_info(current->group_info);
128 cr->cr_group_info = current->group_info;
129 task_unlock(current);
131 memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
132 cr->cr_ngroups = current->ngroups;
138 /* Set the cred info into the current task */
142 current->fsuid = cr->cr_uid;
143 current->uid = cr->cr_ruid;
144 current->fsgid = cr->cr_gid;
145 current->gid = cr->cr_rgid;
146 #if defined(AFS_LINUX26_ENV)
148 struct group_info *old_info;
150 /* using set_current_groups() will sort the groups */
151 get_group_info(cr->cr_group_info);
154 old_info = current->group_info;
155 current->group_info = cr->cr_group_info;
156 task_unlock(current);
158 put_group_info(old_info);
161 memcpy(current->groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
162 current->ngroups = cr->cr_ngroups;