Commit | Line | Data |
---|---|---|
805e021f CE |
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 | } |