]> git.proxmox.com Git - mirror_spl-debian.git/blame - module/spl/spl-cred.c
Refresh links to web site
[mirror_spl-debian.git] / module / spl / spl-cred.c
CommitLineData
716154c5
BB
1/*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
ec7d53e9
BB
6 * UCRL-CODE-235197
7 *
716154c5 8 * This file is part of the SPL, Solaris Porting Layer.
3d6af2dd 9 * For details, see <http://zfsonlinux.org/>.
ec7d53e9 10 *
716154c5
BB
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
ec7d53e9
BB
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
716154c5
BB
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 *****************************************************************************
24 * Solaris Porting Layer (SPL) Credential Implementation.
25\*****************************************************************************/
ec7d53e9
BB
26
27#include <sys/cred.h>
28
29#ifdef DEBUG_SUBSYSTEM
30#undef DEBUG_SUBSYSTEM
31#endif
32
33#define DEBUG_SUBSYSTEM S_CRED
34
35#ifdef HAVE_GROUPS_SEARCH
36/* Symbol may be exported by custom kernel patch */
37#define cr_groups_search(gi, grp) groups_search(gi, grp)
38#else
39/* Implementation from 2.6.30 kernel */
40static int
41cr_groups_search(const struct group_info *group_info, gid_t grp)
42{
43 unsigned int left, right;
44
45 if (!group_info)
46 return 0;
47
48 left = 0;
49 right = group_info->ngroups;
50 while (left < right) {
51 unsigned int mid = (left+right)/2;
52 int cmp = grp - GROUP_AT(group_info, mid);
53 if (cmp > 0)
54 left = mid + 1;
55 else if (cmp < 0)
56 right = mid;
57 else
58 return 1;
59 }
60 return 0;
61}
62#endif
63
64#ifdef HAVE_CRED_STRUCT
65
66/*
67 * As of 2.6.29 a clean credential API appears in the linux kernel.
68 * We attempt to layer the Solaris API on top of the linux API.
69 */
70
71/* Hold a reference on the credential and group info */
72void
73crhold(cred_t *cr)
74{
75 (void)get_cred((const cred_t *)cr);
76 (void)get_group_info(cr->group_info);
77}
78
79/* Free a reference on the credential and group info */
80void
81crfree(cred_t *cr)
82{
83 put_group_info(cr->group_info);
84 put_cred((const cred_t *)cr);
85}
86
ec7d53e9
BB
87/* Return the number of supplemental groups */
88int
89crgetngroups(const cred_t *cr)
90{
91 struct group_info *gi;
92 int rc;
93
94 gi = get_group_info(cr->group_info);
95 rc = gi->ngroups;
96 put_group_info(gi);
97
98 return rc;
99}
100
101/*
102 * Return an array of supplemental gids. The returned address is safe
103 * to use as long as the caller has taken a reference with crhold().
104 * The caller is responsible for releasing the reference with crfree().
105 */
106gid_t *
107crgetgroups(const cred_t *cr)
108{
109 struct group_info *gi;
110 gid_t *gids;
111
112 gi = get_group_info(cr->group_info);
113 gids = gi->blocks[0];
114 put_group_info(gi);
115
116 return gids;
117}
118
119/* Check if the passed gid is available is in supplied credential. */
120int
121groupmember(gid_t gid, const cred_t *cr)
122{
123 struct group_info *gi;
124 int rc;
125
126 gi = get_group_info(cr->group_info);
127 rc = cr_groups_search(cr->group_info, gid);
128 put_group_info(gi);
129
130 return rc;
131}
132
133#else /* HAVE_CRED_STRUCT */
134
135/*
136 * Until very recently all credential information was embedded in
137 * the linux task struct. For this reason to simulate a Solaris
138 * cred_t we need to pass the entire task structure around.
139 */
140
141/* Hold a reference on the credential and group info */
6b09f739 142void crhold(cred_t *cr) { }
ec7d53e9
BB
143
144/* Free a reference on the credential and group info */
6b09f739 145void crfree(cred_t *cr) { }
ec7d53e9 146
ec7d53e9
BB
147/* Return the number of supplemental groups */
148int
149crgetngroups(const cred_t *cr)
150{
151 int lock, rc;
152
153 lock = (cr != current);
154 if (lock)
155 task_lock((struct task_struct *)cr);
156
157 get_group_info(cr->group_info);
158 rc = cr->group_info->ngroups;
159 put_group_info(cr->group_info);
160
161 if (lock)
162 task_unlock((struct task_struct *)cr);
163
164 return rc;
165}
166
167/*
168 * Return an array of supplemental gids. The returned address is safe
169 * to use as long as the caller has taken a reference with crhold().
170 * The caller is responsible for releasing the reference with crfree().
171 */
172gid_t *
173crgetgroups(const cred_t *cr)
174{
175 gid_t *gids;
176 int lock;
177
178 lock = (cr != current);
179 if (lock)
180 task_lock((struct task_struct *)cr);
181
182 get_group_info(cr->group_info);
183 gids = cr->group_info->blocks[0];
184 put_group_info(cr->group_info);
185
186 if (lock)
187 task_unlock((struct task_struct *)cr);
188
189 return gids;
190}
191
192/* Check if the passed gid is available is in supplied credential. */
193int
194groupmember(gid_t gid, const cred_t *cr)
195{
196 int lock, rc;
197
198 lock = (cr != current);
199 if (lock)
200 task_lock((struct task_struct *)cr);
201
202 get_group_info(cr->group_info);
203 rc = cr_groups_search(cr->group_info, gid);
204 put_group_info(cr->group_info);
205
206 if (lock)
207 task_unlock((struct task_struct *)cr);
208
209 return rc;
210}
211
212#endif /* HAVE_CRED_STRUCT */
213
734fcac7
BB
214/* Return the effective user id */
215uid_t
216crgetuid(const cred_t *cr)
217{
218 return cr->euid;
219}
220
221/* Return the real user id */
222uid_t
223crgetruid(const cred_t *cr)
224{
225 return cr->uid;
226}
227
228/* Return the saved user id */
229uid_t
230crgetsuid(const cred_t *cr)
231{
232 return cr->suid;
233}
234
235/* Return the filesystem user id */
236uid_t
237crgetfsuid(const cred_t *cr)
238{
239 return cr->fsuid;
240}
241
242/* Return the effective group id */
243gid_t
244crgetgid(const cred_t *cr)
245{
246 return cr->egid;
247}
248
249/* Return the real group id */
250gid_t
251crgetrgid(const cred_t *cr)
252{
253 return cr->gid;
254}
255
256/* Return the saved group id */
257gid_t
258crgetsgid(const cred_t *cr)
259{
260 return cr->sgid;
261}
262
263/* Return the filesystem group id */
264gid_t
265crgetfsgid(const cred_t *cr)
266{
267 return cr->fsgid;
268}
269
ec7d53e9
BB
270EXPORT_SYMBOL(crhold);
271EXPORT_SYMBOL(crfree);
272EXPORT_SYMBOL(crgetuid);
273EXPORT_SYMBOL(crgetruid);
274EXPORT_SYMBOL(crgetsuid);
734fcac7 275EXPORT_SYMBOL(crgetfsuid);
ec7d53e9
BB
276EXPORT_SYMBOL(crgetgid);
277EXPORT_SYMBOL(crgetrgid);
278EXPORT_SYMBOL(crgetsgid);
734fcac7 279EXPORT_SYMBOL(crgetfsgid);
ec7d53e9
BB
280EXPORT_SYMBOL(crgetngroups);
281EXPORT_SYMBOL(crgetgroups);
282EXPORT_SYMBOL(groupmember);