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]
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>
39 #include <sys/debug.h>
40 #include <sys/policy.h>
51 zone_t
*zone
= crgetzone(CRED());
54 if (!VALID_GID(gid
, zone
))
55 return (set_errno(EINVAL
));
58 if (ksid_lookupbygid(zone
, gid
, &ksid
) != 0)
59 return (set_errno(EINVAL
));
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
);
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
);
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
);
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
||
104 crcopy_to(cr
, newcr
);
107 newcr
->cr_rgid
= gid
;
108 newcr
->cr_sgid
= gid
;
109 crsetsid(newcr
, ksp
, KSID_GROUP
);
110 mutex_exit(&p
->p_crlock
);
121 mutex_enter(&p
->p_lock
);
123 mutex_exit(&p
->p_lock
);
125 crset(p
, newcr
); /* broadcast to process threads */
128 return (set_errno(error
));
137 cr
= curthread
->t_cred
;
138 r
.r_val1
= cr
->cr_rgid
;
139 r
.r_val2
= cr
->cr_gid
;
151 zone_t
*zone
= crgetzone(CRED());
153 if (!VALID_GID(gid
, zone
))
154 return (set_errno(EINVAL
));
157 if (ksid_lookupbygid(zone
, gid
, &ksid
) != 0)
158 return (set_errno(EINVAL
));
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
);
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
);
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)
187 crcopy_to(cr
, newcr
);
190 crsetsid(newcr
, ksp
, KSID_GROUP
);
191 mutex_exit(&p
->p_crlock
);
201 mutex_enter(&p
->p_lock
);
203 mutex_exit(&p
->p_lock
);
205 crset(p
, newcr
); /* broadcast to process threads */
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
219 setregid(gid_t rgid
, gid_t egid
)
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
));
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
);
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) {
255 crcopy_to(cr
, newcr
);
259 newcr
->cr_gid
= egid
;
260 crsetsid(newcr
, ksp
, KSID_GROUP
);
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."
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)
283 mutex_exit(&p
->p_crlock
);
287 mutex_enter(&p
->p_lock
);
289 mutex_exit(&p
->p_lock
);
291 crset(p
, newcr
); /* broadcast to process threads */
297 return (set_errno(error
));