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 static DECLARE_MUTEX(linux_cred_pool_lock);
38 static struct semaphore linux_cred_pool_lock = MUTEX;
40 #define CRED_LOCK() down(&linux_cred_pool_lock)
41 #define CRED_UNLOCK() up(&linux_cred_pool_lock)
52 cred_pool = (cred_t *) osi_Alloc(CRED_ALLOC_STEP * sizeof(cred_t));
54 osi_Panic("crget: No more memory for creds!\n");
56 for (i = 0; i < CRED_ALLOC_STEP - 1; i++)
57 cred_pool[i].cr_ref = (long)&cred_pool[i + 1];
58 cred_pool[i].cr_ref = 0;
61 cred_pool = (cred_t *) tmp->cr_ref;
65 memset(tmp, 0, sizeof(cred_t));
66 #if defined(AFS_LINUX26_ENV)
67 tmp->cr_group_info = groups_alloc(0);
77 #if defined(AFS_LINUX26_ENV)
78 put_group_info(cr->cr_group_info);
85 cr->cr_ref = (long)cred_pool;
92 /* Return a duplicate of the cred. */
96 cred_t *tmp = crget();
98 tmp->cr_uid = cr->cr_uid;
99 tmp->cr_ruid = cr->cr_ruid;
100 tmp->cr_gid = cr->cr_gid;
101 #if defined(AFS_LINUX26_ENV)
103 struct group_info *old_info;
105 old_info = tmp->cr_group_info;
106 get_group_info(cr->cr_group_info);
107 tmp->cr_group_info = cr->cr_group_info;
108 put_group_info(old_info);
111 memcpy(tmp->cr_groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
112 tmp->cr_ngroups = cr->cr_ngroups;
122 cred_t *cr = crget();
124 cr->cr_uid = current->fsuid;
125 cr->cr_ruid = current->uid;
126 cr->cr_gid = current->fsgid;
127 cr->cr_rgid = current->gid;
128 #if defined(AFS_LINUX26_ENV)
130 struct group_info *old_info;
132 old_info = cr->cr_group_info;
133 get_group_info(current->group_info);
134 cr->cr_group_info = current->group_info;
135 put_group_info(old_info);
138 memcpy(cr->cr_groups, current->groups, NGROUPS * sizeof(gid_t));
139 cr->cr_ngroups = current->ngroups;
145 /* Set the cred info into the current task */
149 current->fsuid = cr->cr_uid;
150 current->uid = cr->cr_ruid;
151 current->fsgid = cr->cr_gid;
152 current->gid = cr->cr_rgid;
153 #if defined(AFS_LINUX26_ENV)
155 struct group_info *old_info;
157 /* using set_current_groups() will sort the groups */
158 old_info = current->group_info;
159 get_group_info(cr->cr_group_info);
160 current->group_info = cr->cr_group_info;
161 put_group_info(old_info);
164 memcpy(current->groups, cr->cr_groups, NGROUPS * sizeof(gid_t));
165 current->ngroups = cr->cr_ngroups;