bozo: Introduce bnode_Wait()
[openafs.git] / src / afs / LINUX / osi_cred.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9
10 /*
11  * osi_cred.c - Linux cred handling routines.
12  *
13  */
14 #include <afsconfig.h>
15 #include "afs/param.h"
16
17
18 #include "afs/sysincludes.h"
19 #include "afsincludes.h"
20
21 /* Copy one credential structure to another, being careful about references */
22 static inline void
23 afs_copy_creds(cred_t *to_cred, const cred_t *from_cred) {
24 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
25     /* Skip afs_from_kuid/afs_make_kuid round trip */
26     to_cred->fsuid = from_cred->fsuid;
27     to_cred->fsgid = from_cred->fsgid;
28     to_cred->uid = from_cred->uid;
29     to_cred->gid = from_cred->gid;
30 #else
31     afs_set_cr_uid(to_cred, afs_cr_uid(from_cred));
32     afs_set_cr_gid(to_cred, afs_cr_gid(from_cred));
33     afs_set_cr_ruid(to_cred, afs_cr_ruid(from_cred));
34     afs_set_cr_rgid(to_cred, afs_cr_rgid(from_cred));
35 #endif
36     get_group_info(afs_cr_group_info(from_cred));
37     afs_set_cr_group_info(to_cred, afs_cr_group_info(from_cred));
38 }
39
40 cred_t *
41 crget(void)
42 {
43     cred_t *tmp;
44     
45     tmp = kmalloc(sizeof(cred_t), GFP_NOFS);
46     if (!tmp)
47         osi_Panic("crget: No more memory for creds!\n");
48
49 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
50     get_cred(tmp);
51 #else
52     atomic_set(&tmp->cr_ref, 1);
53 #endif
54     return tmp;
55 }
56
57 void
58 crfree(cred_t * cr)
59 {
60 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
61     put_cred(cr);
62 #else
63     if (atomic_dec_and_test(&cr->cr_ref)) {
64         put_group_info(afs_cr_group_info(cr));
65         kfree(cr);
66     }
67 #endif
68 }
69
70
71 /* Return a duplicate of the cred. */
72 cred_t *
73 crdup(cred_t * cr)
74 {
75     cred_t *tmp = crget();
76 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
77     afs_copy_creds(tmp, cr);
78 #else
79     afs_set_cr_uid(tmp, afs_cr_uid(cr));
80     afs_set_cr_ruid(tmp, afs_cr_ruid(cr));
81     afs_set_cr_gid(tmp, afs_cr_gid(cr));
82     afs_set_cr_rgid(tmp, afs_cr_rgid(cr));
83
84     get_group_info(afs_cr_group_info(cr));
85     afs_set_cr_group_info(tmp, afs_cr_group_info(cr));
86 #endif
87     return tmp;
88 }
89
90 cred_t *
91 crref(void)
92 {
93 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
94     return (cred_t *)get_current_cred();
95 #else
96     cred_t *cr = crget();
97
98     afs_set_cr_uid(cr, current_fsuid());
99     afs_set_cr_ruid(cr, current_uid());
100     afs_set_cr_gid(cr, current_fsgid());
101     afs_set_cr_rgid(cr, current_gid());
102
103     task_lock(current);
104     get_group_info(current_group_info());
105     afs_set_cr_group_info(cr, current_group_info());
106     task_unlock(current);
107
108     return cr;
109 #endif
110 }
111
112 /* Set the cred info into the current task */
113 void
114 crset(cred_t * cr)
115 {
116 #if defined(STRUCT_TASK_STRUCT_HAS_CRED)
117     struct cred *new_creds;
118
119     /* If our current task doesn't have identical real and effective
120      * credentials, commit_cred won't let us change them, so we just
121      * bail here.
122      */
123     if (current->cred != current->real_cred)
124         return;
125     new_creds = prepare_creds();
126     /* Drop the reference to group_info - we'll overwrite it in afs_copy_creds */
127     put_group_info(new_creds->group_info);
128     afs_copy_creds(new_creds, cr);
129
130     commit_creds(new_creds);
131 #else
132     struct group_info *old_info;
133
134     current->fsuid = afs_cr_uid(cr);
135     current->uid = afs_cr_ruid(cr);
136     current->fsgid = afs_cr_gid(cr);
137     current->gid = afs_cr_rgid(cr);
138
139     get_group_info(afs_cr_group_info(cr));
140     task_lock(current);
141     old_info = current->group_info;
142     current->group_info = afs_cr_group_info(cr);
143     task_unlock(current);
144     put_group_info(old_info);
145 #endif
146 }