]>
Commit | Line | Data |
---|---|---|
4b393c50 | 1 | /* |
716154c5 BB |
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 | 22 | * with the SPL. If not, see <http://www.gnu.org/licenses/>. |
5461eefe | 23 | * |
716154c5 | 24 | * Solaris Porting Layer (SPL) Credential Implementation. |
4b393c50 | 25 | */ |
ec7d53e9 BB |
26 | |
27 | #include <sys/cred.h> | |
28 | ||
ec7d53e9 | 29 | static int |
f7fd6ddd RY |
30 | #ifdef HAVE_KUIDGID_T |
31 | cr_groups_search(const struct group_info *group_info, kgid_t grp) | |
32 | #else | |
ec7d53e9 | 33 | cr_groups_search(const struct group_info *group_info, gid_t grp) |
f7fd6ddd | 34 | #endif |
ec7d53e9 | 35 | { |
e19101e0 BB |
36 | unsigned int left, right, mid; |
37 | int cmp; | |
ec7d53e9 BB |
38 | |
39 | if (!group_info) | |
5461eefe | 40 | return (0); |
ec7d53e9 BB |
41 | |
42 | left = 0; | |
43 | right = group_info->ngroups; | |
44 | while (left < right) { | |
e19101e0 BB |
45 | mid = (left + right) / 2; |
46 | cmp = KGID_TO_SGID(grp) - | |
47 | KGID_TO_SGID(GROUP_AT(group_info, mid)); | |
48 | ||
ec7d53e9 BB |
49 | if (cmp > 0) |
50 | left = mid + 1; | |
51 | else if (cmp < 0) | |
52 | right = mid; | |
53 | else | |
5461eefe | 54 | return (1); |
ec7d53e9 | 55 | } |
5461eefe | 56 | return (0); |
ec7d53e9 | 57 | } |
ec7d53e9 | 58 | |
9ba3c019 | 59 | /* Hold a reference on the credential */ |
ec7d53e9 BB |
60 | void |
61 | crhold(cred_t *cr) | |
62 | { | |
5461eefe | 63 | (void) get_cred((const cred_t *)cr); |
ec7d53e9 BB |
64 | } |
65 | ||
9ba3c019 | 66 | /* Free a reference on the credential */ |
ec7d53e9 BB |
67 | void |
68 | crfree(cred_t *cr) | |
69 | { | |
ec7d53e9 BB |
70 | put_cred((const cred_t *)cr); |
71 | } | |
72 | ||
ec7d53e9 BB |
73 | /* Return the number of supplemental groups */ |
74 | int | |
75 | crgetngroups(const cred_t *cr) | |
76 | { | |
77 | struct group_info *gi; | |
78 | int rc; | |
79 | ||
9ba3c019 | 80 | gi = cr->group_info; |
ec7d53e9 | 81 | rc = gi->ngroups; |
ae7eda1d | 82 | #ifndef HAVE_GROUP_INFO_GID |
9ba3c019 | 83 | /* |
ae7eda1d | 84 | * For Linux <= 4.8, |
9ba3c019 CC |
85 | * crgetgroups will only returns gi->blocks[0], which contains only |
86 | * the first NGROUPS_PER_BLOCK groups. | |
87 | */ | |
88 | if (rc > NGROUPS_PER_BLOCK) { | |
89 | WARN_ON_ONCE(1); | |
90 | rc = NGROUPS_PER_BLOCK; | |
91 | } | |
ae7eda1d | 92 | #endif |
5461eefe | 93 | return (rc); |
ec7d53e9 BB |
94 | } |
95 | ||
96 | /* | |
97 | * Return an array of supplemental gids. The returned address is safe | |
98 | * to use as long as the caller has taken a reference with crhold(). | |
ae7eda1d CC |
99 | * |
100 | * Linux 4.9 API change, group_info changed from 2d array via ->blocks to 1d | |
101 | * array via ->gid. | |
ec7d53e9 BB |
102 | */ |
103 | gid_t * | |
104 | crgetgroups(const cred_t *cr) | |
105 | { | |
106 | struct group_info *gi; | |
9ba3c019 | 107 | gid_t *gids = NULL; |
ec7d53e9 | 108 | |
9ba3c019 | 109 | gi = cr->group_info; |
ae7eda1d CC |
110 | #ifdef HAVE_GROUP_INFO_GID |
111 | gids = KGIDP_TO_SGIDP(gi->gid); | |
112 | #else | |
9ba3c019 CC |
113 | if (gi->nblocks > 0) |
114 | gids = KGIDP_TO_SGIDP(gi->blocks[0]); | |
ae7eda1d | 115 | #endif |
5461eefe | 116 | return (gids); |
ec7d53e9 BB |
117 | } |
118 | ||
e19101e0 | 119 | /* Check if the passed gid is available in supplied credential. */ |
ec7d53e9 BB |
120 | int |
121 | groupmember(gid_t gid, const cred_t *cr) | |
122 | { | |
123 | struct group_info *gi; | |
124 | int rc; | |
125 | ||
9ba3c019 | 126 | gi = cr->group_info; |
e19101e0 | 127 | rc = cr_groups_search(gi, SGID_TO_KGID(gid)); |
ec7d53e9 | 128 | |
5461eefe | 129 | return (rc); |
ec7d53e9 BB |
130 | } |
131 | ||
734fcac7 BB |
132 | /* Return the effective user id */ |
133 | uid_t | |
134 | crgetuid(const cred_t *cr) | |
135 | { | |
5461eefe | 136 | return (KUID_TO_SUID(cr->euid)); |
734fcac7 BB |
137 | } |
138 | ||
139 | /* Return the real user id */ | |
140 | uid_t | |
141 | crgetruid(const cred_t *cr) | |
142 | { | |
5461eefe | 143 | return (KUID_TO_SUID(cr->uid)); |
734fcac7 BB |
144 | } |
145 | ||
146 | /* Return the saved user id */ | |
147 | uid_t | |
148 | crgetsuid(const cred_t *cr) | |
149 | { | |
5461eefe | 150 | return (KUID_TO_SUID(cr->suid)); |
734fcac7 BB |
151 | } |
152 | ||
153 | /* Return the filesystem user id */ | |
154 | uid_t | |
155 | crgetfsuid(const cred_t *cr) | |
156 | { | |
5461eefe | 157 | return (KUID_TO_SUID(cr->fsuid)); |
734fcac7 BB |
158 | } |
159 | ||
160 | /* Return the effective group id */ | |
161 | gid_t | |
162 | crgetgid(const cred_t *cr) | |
163 | { | |
5461eefe | 164 | return (KGID_TO_SGID(cr->egid)); |
734fcac7 BB |
165 | } |
166 | ||
167 | /* Return the real group id */ | |
168 | gid_t | |
169 | crgetrgid(const cred_t *cr) | |
170 | { | |
5461eefe | 171 | return (KGID_TO_SGID(cr->gid)); |
734fcac7 BB |
172 | } |
173 | ||
174 | /* Return the saved group id */ | |
175 | gid_t | |
176 | crgetsgid(const cred_t *cr) | |
177 | { | |
5461eefe | 178 | return (KGID_TO_SGID(cr->sgid)); |
734fcac7 BB |
179 | } |
180 | ||
181 | /* Return the filesystem group id */ | |
182 | gid_t | |
183 | crgetfsgid(const cred_t *cr) | |
184 | { | |
5461eefe | 185 | return (KGID_TO_SGID(cr->fsgid)); |
734fcac7 BB |
186 | } |
187 | ||
ec7d53e9 BB |
188 | EXPORT_SYMBOL(crhold); |
189 | EXPORT_SYMBOL(crfree); | |
190 | EXPORT_SYMBOL(crgetuid); | |
191 | EXPORT_SYMBOL(crgetruid); | |
192 | EXPORT_SYMBOL(crgetsuid); | |
734fcac7 | 193 | EXPORT_SYMBOL(crgetfsuid); |
ec7d53e9 BB |
194 | EXPORT_SYMBOL(crgetgid); |
195 | EXPORT_SYMBOL(crgetrgid); | |
196 | EXPORT_SYMBOL(crgetsgid); | |
734fcac7 | 197 | EXPORT_SYMBOL(crgetfsgid); |
ec7d53e9 BB |
198 | EXPORT_SYMBOL(crgetngroups); |
199 | EXPORT_SYMBOL(crgetgroups); | |
200 | EXPORT_SYMBOL(groupmember); |