fm/ipmitopo: fix 64-bit compilation
[unleashed.git] / kernel / syscall / gid.c
blobecad0add3ff1e7099058ad10348b9214f8c9b7d9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/systm.h>
36 #include <sys/cred_impl.h>
37 #include <sys/errno.h>
38 #include <sys/proc.h>
39 #include <sys/debug.h>
40 #include <sys/policy.h>
43 int
44 setgid(gid_t gid)
46 proc_t *p;
47 int error;
48 int do_nocd = 0;
49 cred_t *cr, *newcr;
50 ksid_t ksid, *ksp;
51 zone_t *zone = crgetzone(CRED());
54 if (!VALID_GID(gid, zone))
55 return (set_errno(EINVAL));
57 if (gid > MAXUID) {
58 if (ksid_lookupbygid(zone, gid, &ksid) != 0)
59 return (set_errno(EINVAL));
60 ksp = &ksid;
61 } else {
62 ksp = NULL;
66 * Need to pre-allocate the new cred structure before grabbing
67 * the p_crlock mutex. We cannot hold the mutex across the
68 * secpolicy functions.
70 newcr = cralloc_ksid();
71 p = ttoproc(curthread);
72 mutex_enter(&p->p_crlock);
73 retry:
74 cr = p->p_cred;
75 crhold(cr);
76 mutex_exit(&p->p_crlock);
79 if ((gid == cr->cr_rgid || gid == cr->cr_sgid) &&
80 secpolicy_allow_setid(cr, -1, B_TRUE) != 0) {
81 mutex_enter(&p->p_crlock);
82 crfree(cr);
83 if (cr != p->p_cred)
84 goto retry;
85 error = 0;
86 crcopy_to(cr, newcr);
87 p->p_cred = newcr;
88 newcr->cr_gid = gid;
89 crsetsid(newcr, ksp, KSID_GROUP);
90 mutex_exit(&p->p_crlock);
91 } else if ((error = secpolicy_allow_setid(cr, -1, B_FALSE)) == 0) {
92 mutex_enter(&p->p_crlock);
93 crfree(cr);
94 if (cr != p->p_cred)
95 goto retry;
97 * A privileged process that makes itself look like a
98 * set-gid process must be marked to produce no core dump.
100 if (cr->cr_gid != gid ||
101 cr->cr_rgid != gid ||
102 cr->cr_sgid != gid)
103 do_nocd = 1;
104 crcopy_to(cr, newcr);
105 p->p_cred = newcr;
106 newcr->cr_gid = gid;
107 newcr->cr_rgid = gid;
108 newcr->cr_sgid = gid;
109 crsetsid(newcr, ksp, KSID_GROUP);
110 mutex_exit(&p->p_crlock);
111 } else {
112 crfree(newcr);
113 crfree(cr);
114 if (ksp != NULL)
115 ksid_rele(ksp);
119 if (error == 0) {
120 if (do_nocd) {
121 mutex_enter(&p->p_lock);
122 p->p_flag |= SNOCD;
123 mutex_exit(&p->p_lock);
125 crset(p, newcr); /* broadcast to process threads */
126 return (0);
128 return (set_errno(error));
131 int64_t
132 getgid(void)
134 rval_t r;
135 cred_t *cr;
137 cr = curthread->t_cred;
138 r.r_val1 = cr->cr_rgid;
139 r.r_val2 = cr->cr_gid;
140 return (r.r_vals);
144 setegid(gid_t gid)
146 proc_t *p;
147 cred_t *cr, *newcr;
148 int error = EPERM;
149 int do_nocd = 0;
150 ksid_t ksid, *ksp;
151 zone_t *zone = crgetzone(CRED());
153 if (!VALID_GID(gid, zone))
154 return (set_errno(EINVAL));
156 if (gid > MAXUID) {
157 if (ksid_lookupbygid(zone, gid, &ksid) != 0)
158 return (set_errno(EINVAL));
159 ksp = &ksid;
160 } else {
161 ksp = NULL;
164 * Need to pre-allocate the new cred structure before grabbing
165 * the p_crlock mutex.
167 newcr = cralloc_ksid();
168 p = ttoproc(curthread);
169 mutex_enter(&p->p_crlock);
170 retry:
171 crhold(cr = p->p_cred);
172 mutex_exit(&p->p_crlock);
174 if (gid == cr->cr_rgid || gid == cr->cr_gid || gid == cr->cr_sgid ||
175 (error = secpolicy_allow_setid(cr, -1, B_FALSE)) == 0) {
176 mutex_enter(&p->p_crlock);
177 crfree(cr);
178 if (cr != p->p_cred)
179 goto retry;
181 * A privileged process that makes itself look like a
182 * set-gid process must be marked to produce no core dump.
184 if (cr->cr_gid != gid && error == 0)
185 do_nocd = 1;
186 error = 0;
187 crcopy_to(cr, newcr);
188 p->p_cred = newcr;
189 newcr->cr_gid = gid;
190 crsetsid(newcr, ksp, KSID_GROUP);
191 mutex_exit(&p->p_crlock);
192 } else {
193 crfree(newcr);
194 crfree(cr);
195 if (ksp != NULL)
196 ksid_rele(ksp);
199 if (error == 0) {
200 if (do_nocd) {
201 mutex_enter(&p->p_lock);
202 p->p_flag |= SNOCD;
203 mutex_exit(&p->p_lock);
205 crset(p, newcr); /* broadcast to process threads */
206 return (0);
208 return (set_errno(error));
212 * Buy-back from SunOS 4.x
214 * Like setgid() and setegid() combined -except- that non-root users
215 * can change cr_rgid to cr_gid, and the semantics of cr_sgid are
216 * subtly different.
219 setregid(gid_t rgid, gid_t egid)
221 proc_t *p;
222 int error = EPERM;
223 int do_nocd = 0;
224 cred_t *cr, *newcr;
225 ksid_t ksid, *ksp;
226 zone_t *zone = crgetzone(CRED());
228 if ((rgid != -1 && !VALID_GID(rgid, zone)) ||
229 (egid != -1 && !VALID_GID(egid, zone)))
230 return (set_errno(EINVAL));
232 if (egid != -1 && egid > MAXUID) {
233 if (ksid_lookupbygid(zone, egid, &ksid) != 0)
234 return (set_errno(EINVAL));
235 ksp = &ksid;
236 } else {
237 ksp = NULL;
240 * Need to pre-allocate the new cred structure before grabbing
241 * the p_crlock mutex.
243 newcr = cralloc_ksid();
245 p = ttoproc(curthread);
246 mutex_enter(&p->p_crlock);
247 cr = p->p_cred;
249 if ((rgid == -1 ||
250 rgid == cr->cr_rgid || rgid == cr->cr_gid || rgid == cr->cr_sgid) &&
251 (egid == -1 || egid == cr->cr_rgid || egid == cr->cr_gid ||
252 egid == cr->cr_sgid) ||
253 (error = secpolicy_allow_setid(cr, -1, B_FALSE)) == 0) {
254 crhold(cr);
255 crcopy_to(cr, newcr);
256 p->p_cred = newcr;
258 if (egid != -1) {
259 newcr->cr_gid = egid;
260 crsetsid(newcr, ksp, KSID_GROUP);
262 if (rgid != -1)
263 newcr->cr_rgid = rgid;
265 * "If the real gid is being changed, or the effective gid is
266 * being changed to a value not equal to the real gid, the
267 * saved gid is set to the new effective gid."
269 if (rgid != -1 ||
270 (egid != -1 && newcr->cr_gid != newcr->cr_rgid))
271 newcr->cr_sgid = newcr->cr_gid;
273 * A privileged process that makes itself look like a
274 * set-gid process must be marked to produce no core dump.
276 if ((cr->cr_gid != newcr->cr_gid ||
277 cr->cr_rgid != newcr->cr_rgid ||
278 cr->cr_sgid != newcr->cr_sgid) && error == 0)
279 do_nocd = 1;
280 error = 0;
281 crfree(cr);
283 mutex_exit(&p->p_crlock);
285 if (error == 0) {
286 if (do_nocd) {
287 mutex_enter(&p->p_lock);
288 p->p_flag |= SNOCD;
289 mutex_exit(&p->p_lock);
291 crset(p, newcr); /* broadcast to process threads */
292 return (0);
294 crfree(newcr);
295 if (ksp != NULL)
296 ksid_rele(ksp);
297 return (set_errno(error));