]>
git.proxmox.com Git - mirror_spl-debian.git/blob - module/spl/spl-cred.c
2 * This file is part of the SPL: Solaris Porting Layer.
4 * Copyright (c) 2009 Lawrence Livermore National Security, LLC.
5 * Produced at Lawrence Livermore National Laboratory
7 * Brian Behlendorf <behlendorf1@llnl.gov>,
10 * This is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #ifdef DEBUG_SUBSYSTEM
28 #undef DEBUG_SUBSYSTEM
31 #define DEBUG_SUBSYSTEM S_CRED
33 #ifdef HAVE_GROUPS_SEARCH
34 /* Symbol may be exported by custom kernel patch */
35 #define cr_groups_search(gi, grp) groups_search(gi, grp)
37 /* Implementation from 2.6.30 kernel */
39 cr_groups_search(const struct group_info
*group_info
, gid_t grp
)
41 unsigned int left
, right
;
47 right
= group_info
->ngroups
;
48 while (left
< right
) {
49 unsigned int mid
= (left
+right
)/2;
50 int cmp
= grp
- GROUP_AT(group_info
, mid
);
62 #ifdef HAVE_CRED_STRUCT
65 * As of 2.6.29 a clean credential API appears in the linux kernel.
66 * We attempt to layer the Solaris API on top of the linux API.
69 /* Hold a reference on the credential and group info */
73 (void)get_cred((const cred_t
*)cr
);
74 (void)get_group_info(cr
->group_info
);
77 /* Free a reference on the credential and group info */
81 put_group_info(cr
->group_info
);
82 put_cred((const cred_t
*)cr
);
85 /* Return the effective user id */
87 crgetuid(const cred_t
*cr
)
92 /* Return the real user id */
94 crgetruid(const cred_t
*cr
)
99 /* Return the saved user id */
101 crgetsuid(const cred_t
*cr
)
106 /* Return the effective group id */
108 crgetgid(const cred_t
*cr
)
113 /* Return the real group id */
115 crgetrgid(const cred_t
*cr
)
120 /* Return the saved group id */
122 crgetsgid(const cred_t
*cr
)
127 /* Return the number of supplemental groups */
129 crgetngroups(const cred_t
*cr
)
131 struct group_info
*gi
;
134 gi
= get_group_info(cr
->group_info
);
142 * Return an array of supplemental gids. The returned address is safe
143 * to use as long as the caller has taken a reference with crhold().
144 * The caller is responsible for releasing the reference with crfree().
147 crgetgroups(const cred_t
*cr
)
149 struct group_info
*gi
;
152 gi
= get_group_info(cr
->group_info
);
153 gids
= gi
->blocks
[0];
159 /* Check if the passed gid is available is in supplied credential. */
161 groupmember(gid_t gid
, const cred_t
*cr
)
163 struct group_info
*gi
;
166 gi
= get_group_info(cr
->group_info
);
167 rc
= cr_groups_search(cr
->group_info
, gid
);
173 #else /* HAVE_CRED_STRUCT */
176 * Until very recently all credential information was embedded in
177 * the linux task struct. For this reason to simulate a Solaris
178 * cred_t we need to pass the entire task structure around.
181 /* Hold a reference on the credential and group info */
188 /* Free a reference on the credential and group info */
195 /* Return the effective user id */
197 crgetuid(const cred_t
*cr
) {
201 /* Return the effective real id */
203 crgetruid(const cred_t
*cr
) {
207 /* Return the effective saved id */
209 crgetsuid(const cred_t
*cr
) {
213 /* Return the effective group id */
215 crgetgid(const cred_t
*cr
) {
219 /* Return the real group id */
221 crgetrgid(const cred_t
*cr
) {
225 /* Return the saved group id */
227 crgetsgid(const cred_t
*cr
) {
231 /* Return the number of supplemental groups */
233 crgetngroups(const cred_t
*cr
)
237 lock
= (cr
!= current
);
239 task_lock((struct task_struct
*)cr
);
241 get_group_info(cr
->group_info
);
242 rc
= cr
->group_info
->ngroups
;
243 put_group_info(cr
->group_info
);
246 task_unlock((struct task_struct
*)cr
);
252 * Return an array of supplemental gids. The returned address is safe
253 * to use as long as the caller has taken a reference with crhold().
254 * The caller is responsible for releasing the reference with crfree().
257 crgetgroups(const cred_t
*cr
)
262 lock
= (cr
!= current
);
264 task_lock((struct task_struct
*)cr
);
266 get_group_info(cr
->group_info
);
267 gids
= cr
->group_info
->blocks
[0];
268 put_group_info(cr
->group_info
);
271 task_unlock((struct task_struct
*)cr
);
276 /* Check if the passed gid is available is in supplied credential. */
278 groupmember(gid_t gid
, const cred_t
*cr
)
282 lock
= (cr
!= current
);
284 task_lock((struct task_struct
*)cr
);
286 get_group_info(cr
->group_info
);
287 rc
= cr_groups_search(cr
->group_info
, gid
);
288 put_group_info(cr
->group_info
);
291 task_unlock((struct task_struct
*)cr
);
296 #endif /* HAVE_CRED_STRUCT */
298 EXPORT_SYMBOL(crhold
);
299 EXPORT_SYMBOL(crfree
);
300 EXPORT_SYMBOL(crgetuid
);
301 EXPORT_SYMBOL(crgetruid
);
302 EXPORT_SYMBOL(crgetsuid
);
303 EXPORT_SYMBOL(crgetgid
);
304 EXPORT_SYMBOL(crgetrgid
);
305 EXPORT_SYMBOL(crgetsgid
);
306 EXPORT_SYMBOL(crgetngroups
);
307 EXPORT_SYMBOL(crgetgroups
);
308 EXPORT_SYMBOL(groupmember
);