1*43a90889SApple OSS Distributions /*
2*43a90889SApple OSS Distributions * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3*43a90889SApple OSS Distributions *
4*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*43a90889SApple OSS Distributions *
6*43a90889SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*43a90889SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*43a90889SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*43a90889SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*43a90889SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*43a90889SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*43a90889SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*43a90889SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*43a90889SApple OSS Distributions *
15*43a90889SApple OSS Distributions * Please obtain a copy of the License at
16*43a90889SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*43a90889SApple OSS Distributions *
18*43a90889SApple OSS Distributions * The Original Code and all software distributed under the License are
19*43a90889SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*43a90889SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*43a90889SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*43a90889SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*43a90889SApple OSS Distributions * Please see the License for the specific language governing rights and
24*43a90889SApple OSS Distributions * limitations under the License.
25*43a90889SApple OSS Distributions *
26*43a90889SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*43a90889SApple OSS Distributions *
28*43a90889SApple OSS Distributions *
29*43a90889SApple OSS Distributions * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
30*43a90889SApple OSS Distributions *
31*43a90889SApple OSS Distributions *
32*43a90889SApple OSS Distributions * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993
33*43a90889SApple OSS Distributions * The Regents of the University of California. All rights reserved.
34*43a90889SApple OSS Distributions * (c) UNIX System Laboratories, Inc.
35*43a90889SApple OSS Distributions * All or some portions of this file are derived from material licensed
36*43a90889SApple OSS Distributions * to the University of California by American Telephone and Telegraph
37*43a90889SApple OSS Distributions * Co. or Unix System Laboratories, Inc. and are reproduced herein with
38*43a90889SApple OSS Distributions * the permission of UNIX System Laboratories, Inc.
39*43a90889SApple OSS Distributions *
40*43a90889SApple OSS Distributions * Redistribution and use in source and binary forms, with or without
41*43a90889SApple OSS Distributions * modification, are permitted provided that the following conditions
42*43a90889SApple OSS Distributions * are met:
43*43a90889SApple OSS Distributions * 1. Redistributions of source code must retain the above copyright
44*43a90889SApple OSS Distributions * notice, this list of conditions and the following disclaimer.
45*43a90889SApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright
46*43a90889SApple OSS Distributions * notice, this list of conditions and the following disclaimer in the
47*43a90889SApple OSS Distributions * documentation and/or other materials provided with the distribution.
48*43a90889SApple OSS Distributions * 3. All advertising materials mentioning features or use of this software
49*43a90889SApple OSS Distributions * must display the following acknowledgement:
50*43a90889SApple OSS Distributions * This product includes software developed by the University of
51*43a90889SApple OSS Distributions * California, Berkeley and its contributors.
52*43a90889SApple OSS Distributions * 4. Neither the name of the University nor the names of its contributors
53*43a90889SApple OSS Distributions * may be used to endorse or promote products derived from this software
54*43a90889SApple OSS Distributions * without specific prior written permission.
55*43a90889SApple OSS Distributions *
56*43a90889SApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57*43a90889SApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58*43a90889SApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59*43a90889SApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60*43a90889SApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61*43a90889SApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62*43a90889SApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63*43a90889SApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64*43a90889SApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65*43a90889SApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66*43a90889SApple OSS Distributions * SUCH DAMAGE.
67*43a90889SApple OSS Distributions *
68*43a90889SApple OSS Distributions * @(#)kern_prot.c 8.9 (Berkeley) 2/14/95
69*43a90889SApple OSS Distributions *
70*43a90889SApple OSS Distributions *
71*43a90889SApple OSS Distributions * NOTICE: This file was modified by McAfee Research in 2004 to introduce
72*43a90889SApple OSS Distributions * support for mandatory and extensible security protections. This notice
73*43a90889SApple OSS Distributions * is included in support of clause 2.2 (b) of the Apple Public License,
74*43a90889SApple OSS Distributions * Version 2.0.
75*43a90889SApple OSS Distributions *
76*43a90889SApple OSS Distributions *
77*43a90889SApple OSS Distributions * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
78*43a90889SApple OSS Distributions * support for mandatory and extensible security protections. This notice
79*43a90889SApple OSS Distributions * is included in support of clause 2.2 (b) of the Apple Public License,
80*43a90889SApple OSS Distributions * Version 2.0.
81*43a90889SApple OSS Distributions *
82*43a90889SApple OSS Distributions */
83*43a90889SApple OSS Distributions
84*43a90889SApple OSS Distributions /*
85*43a90889SApple OSS Distributions * System calls related to processes and protection
86*43a90889SApple OSS Distributions */
87*43a90889SApple OSS Distributions
88*43a90889SApple OSS Distributions #include <sys/param.h>
89*43a90889SApple OSS Distributions #include <sys/acct.h>
90*43a90889SApple OSS Distributions #include <sys/systm.h>
91*43a90889SApple OSS Distributions #include <sys/ucred.h>
92*43a90889SApple OSS Distributions #include <sys/proc_internal.h>
93*43a90889SApple OSS Distributions #include <sys/user.h>
94*43a90889SApple OSS Distributions #include <sys/kauth.h>
95*43a90889SApple OSS Distributions #include <sys/timeb.h>
96*43a90889SApple OSS Distributions #include <sys/times.h>
97*43a90889SApple OSS Distributions #include <sys/malloc.h>
98*43a90889SApple OSS Distributions #include <sys/persona.h>
99*43a90889SApple OSS Distributions
100*43a90889SApple OSS Distributions #include <security/audit/audit.h>
101*43a90889SApple OSS Distributions
102*43a90889SApple OSS Distributions #if CONFIG_MACF
103*43a90889SApple OSS Distributions #include <security/mac_framework.h>
104*43a90889SApple OSS Distributions #endif
105*43a90889SApple OSS Distributions
106*43a90889SApple OSS Distributions #include <sys/mount_internal.h>
107*43a90889SApple OSS Distributions #include <sys/sysproto.h>
108*43a90889SApple OSS Distributions #include <mach/message.h>
109*43a90889SApple OSS Distributions
110*43a90889SApple OSS Distributions #include <kern/host.h>
111*43a90889SApple OSS Distributions #include <kern/task.h> /* for current_task() */
112*43a90889SApple OSS Distributions #include <kern/assert.h>
113*43a90889SApple OSS Distributions
114*43a90889SApple OSS Distributions #if DEVELOPMENT || DEBUG
115*43a90889SApple OSS Distributions extern void task_importance_update_owner_info(task_t);
116*43a90889SApple OSS Distributions #endif
117*43a90889SApple OSS Distributions
118*43a90889SApple OSS Distributions /* Used by pmap.c to copy kauth_cred_t structs */
119*43a90889SApple OSS Distributions void kauth_cred_copy(const uintptr_t kv, const uintptr_t new_data);
120*43a90889SApple OSS Distributions
121*43a90889SApple OSS Distributions /*
122*43a90889SApple OSS Distributions * setprivexec
123*43a90889SApple OSS Distributions *
124*43a90889SApple OSS Distributions * Description: (dis)allow this process to hold task, thread, or execption
125*43a90889SApple OSS Distributions * ports of processes about to exec.
126*43a90889SApple OSS Distributions *
127*43a90889SApple OSS Distributions * Parameters: uap->flag New value for flag
128*43a90889SApple OSS Distributions *
129*43a90889SApple OSS Distributions * Returns: int Previous value of flag
130*43a90889SApple OSS Distributions *
131*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
132*43a90889SApple OSS Distributions */
133*43a90889SApple OSS Distributions int
setprivexec(proc_t p,struct setprivexec_args * uap,int32_t * retval)134*43a90889SApple OSS Distributions setprivexec(proc_t p, struct setprivexec_args *uap, int32_t *retval)
135*43a90889SApple OSS Distributions {
136*43a90889SApple OSS Distributions AUDIT_ARG(value32, uap->flag);
137*43a90889SApple OSS Distributions *retval = p->p_debugger;
138*43a90889SApple OSS Distributions p->p_debugger = (uap->flag != 0);
139*43a90889SApple OSS Distributions return 0;
140*43a90889SApple OSS Distributions }
141*43a90889SApple OSS Distributions
142*43a90889SApple OSS Distributions
143*43a90889SApple OSS Distributions /*
144*43a90889SApple OSS Distributions * getpid
145*43a90889SApple OSS Distributions *
146*43a90889SApple OSS Distributions * Description: get the process ID
147*43a90889SApple OSS Distributions *
148*43a90889SApple OSS Distributions * Parameters: (void)
149*43a90889SApple OSS Distributions *
150*43a90889SApple OSS Distributions * Returns: pid_t Current process ID
151*43a90889SApple OSS Distributions *
152*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
153*43a90889SApple OSS Distributions */
154*43a90889SApple OSS Distributions int
getpid(proc_t p,__unused struct getpid_args * uap,int32_t * retval)155*43a90889SApple OSS Distributions getpid(proc_t p, __unused struct getpid_args *uap, int32_t *retval)
156*43a90889SApple OSS Distributions {
157*43a90889SApple OSS Distributions *retval = proc_getpid(p);
158*43a90889SApple OSS Distributions return 0;
159*43a90889SApple OSS Distributions }
160*43a90889SApple OSS Distributions
161*43a90889SApple OSS Distributions
162*43a90889SApple OSS Distributions /*
163*43a90889SApple OSS Distributions * getppid
164*43a90889SApple OSS Distributions *
165*43a90889SApple OSS Distributions * Description: get the parent process ID
166*43a90889SApple OSS Distributions *
167*43a90889SApple OSS Distributions * Parameters: (void)
168*43a90889SApple OSS Distributions *
169*43a90889SApple OSS Distributions * Returns: pid_t Parent process ID
170*43a90889SApple OSS Distributions *
171*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
172*43a90889SApple OSS Distributions */
173*43a90889SApple OSS Distributions int
getppid(proc_t p,__unused struct getppid_args * uap,int32_t * retval)174*43a90889SApple OSS Distributions getppid(proc_t p, __unused struct getppid_args *uap, int32_t *retval)
175*43a90889SApple OSS Distributions {
176*43a90889SApple OSS Distributions *retval = p->p_ppid;
177*43a90889SApple OSS Distributions return 0;
178*43a90889SApple OSS Distributions }
179*43a90889SApple OSS Distributions
180*43a90889SApple OSS Distributions
181*43a90889SApple OSS Distributions /*
182*43a90889SApple OSS Distributions * getpgrp
183*43a90889SApple OSS Distributions *
184*43a90889SApple OSS Distributions * Description: get the process group ID of the calling process
185*43a90889SApple OSS Distributions *
186*43a90889SApple OSS Distributions * Parameters: (void)
187*43a90889SApple OSS Distributions *
188*43a90889SApple OSS Distributions * Returns: pid_t Process group ID
189*43a90889SApple OSS Distributions *
190*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
191*43a90889SApple OSS Distributions */
192*43a90889SApple OSS Distributions int
getpgrp(proc_t p,__unused struct getpgrp_args * uap,int32_t * retval)193*43a90889SApple OSS Distributions getpgrp(proc_t p, __unused struct getpgrp_args *uap, int32_t *retval)
194*43a90889SApple OSS Distributions {
195*43a90889SApple OSS Distributions *retval = p->p_pgrpid;
196*43a90889SApple OSS Distributions return 0;
197*43a90889SApple OSS Distributions }
198*43a90889SApple OSS Distributions
199*43a90889SApple OSS Distributions
200*43a90889SApple OSS Distributions /*
201*43a90889SApple OSS Distributions * getpgid
202*43a90889SApple OSS Distributions *
203*43a90889SApple OSS Distributions * Description: Get an arbitary pid's process group id
204*43a90889SApple OSS Distributions *
205*43a90889SApple OSS Distributions * Parameters: uap->pid The target pid
206*43a90889SApple OSS Distributions *
207*43a90889SApple OSS Distributions * Returns: 0 Success
208*43a90889SApple OSS Distributions * ESRCH No such process
209*43a90889SApple OSS Distributions *
210*43a90889SApple OSS Distributions * Notes: We are permitted to return EPERM in the case that the target
211*43a90889SApple OSS Distributions * process is not in the same session as the calling process,
212*43a90889SApple OSS Distributions * which could be a security consideration
213*43a90889SApple OSS Distributions *
214*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
215*43a90889SApple OSS Distributions */
216*43a90889SApple OSS Distributions int
getpgid(proc_t p,struct getpgid_args * uap,int32_t * retval)217*43a90889SApple OSS Distributions getpgid(proc_t p, struct getpgid_args *uap, int32_t *retval)
218*43a90889SApple OSS Distributions {
219*43a90889SApple OSS Distributions proc_t pt;
220*43a90889SApple OSS Distributions int refheld = 0;
221*43a90889SApple OSS Distributions
222*43a90889SApple OSS Distributions pt = p;
223*43a90889SApple OSS Distributions if (uap->pid == 0) {
224*43a90889SApple OSS Distributions goto found;
225*43a90889SApple OSS Distributions }
226*43a90889SApple OSS Distributions
227*43a90889SApple OSS Distributions if ((pt = proc_find(uap->pid)) == 0) {
228*43a90889SApple OSS Distributions return ESRCH;
229*43a90889SApple OSS Distributions }
230*43a90889SApple OSS Distributions refheld = 1;
231*43a90889SApple OSS Distributions found:
232*43a90889SApple OSS Distributions *retval = pt->p_pgrpid;
233*43a90889SApple OSS Distributions if (refheld != 0) {
234*43a90889SApple OSS Distributions proc_rele(pt);
235*43a90889SApple OSS Distributions }
236*43a90889SApple OSS Distributions return 0;
237*43a90889SApple OSS Distributions }
238*43a90889SApple OSS Distributions
239*43a90889SApple OSS Distributions
240*43a90889SApple OSS Distributions /*
241*43a90889SApple OSS Distributions * getsid
242*43a90889SApple OSS Distributions *
243*43a90889SApple OSS Distributions * Description: Get an arbitary pid's session leaders process group ID
244*43a90889SApple OSS Distributions *
245*43a90889SApple OSS Distributions * Parameters: uap->pid The target pid
246*43a90889SApple OSS Distributions *
247*43a90889SApple OSS Distributions * Returns: 0 Success
248*43a90889SApple OSS Distributions * ESRCH No such process
249*43a90889SApple OSS Distributions *
250*43a90889SApple OSS Distributions * Notes: We are permitted to return EPERM in the case that the target
251*43a90889SApple OSS Distributions * process is not in the same session as the calling process,
252*43a90889SApple OSS Distributions * which could be a security consideration
253*43a90889SApple OSS Distributions *
254*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
255*43a90889SApple OSS Distributions */
256*43a90889SApple OSS Distributions int
getsid(proc_t p,struct getsid_args * uap,int32_t * retval)257*43a90889SApple OSS Distributions getsid(proc_t p, struct getsid_args *uap, int32_t *retval)
258*43a90889SApple OSS Distributions {
259*43a90889SApple OSS Distributions proc_t pt;
260*43a90889SApple OSS Distributions
261*43a90889SApple OSS Distributions if (uap->pid == 0) {
262*43a90889SApple OSS Distributions *retval = proc_sessionid(p);
263*43a90889SApple OSS Distributions return 0;
264*43a90889SApple OSS Distributions }
265*43a90889SApple OSS Distributions
266*43a90889SApple OSS Distributions if ((pt = proc_find(uap->pid)) != PROC_NULL) {
267*43a90889SApple OSS Distributions *retval = proc_sessionid(pt);
268*43a90889SApple OSS Distributions proc_rele(pt);
269*43a90889SApple OSS Distributions return 0;
270*43a90889SApple OSS Distributions }
271*43a90889SApple OSS Distributions
272*43a90889SApple OSS Distributions return ESRCH;
273*43a90889SApple OSS Distributions }
274*43a90889SApple OSS Distributions
275*43a90889SApple OSS Distributions
276*43a90889SApple OSS Distributions /*
277*43a90889SApple OSS Distributions * getuid
278*43a90889SApple OSS Distributions *
279*43a90889SApple OSS Distributions * Description: get real user ID for caller
280*43a90889SApple OSS Distributions *
281*43a90889SApple OSS Distributions * Parameters: (void)
282*43a90889SApple OSS Distributions *
283*43a90889SApple OSS Distributions * Returns: uid_t The real uid of the caller
284*43a90889SApple OSS Distributions */
285*43a90889SApple OSS Distributions int
getuid(__unused proc_t p,__unused struct getuid_args * uap,int32_t * retval)286*43a90889SApple OSS Distributions getuid(__unused proc_t p, __unused struct getuid_args *uap, int32_t *retval)
287*43a90889SApple OSS Distributions {
288*43a90889SApple OSS Distributions *retval = kauth_getruid();
289*43a90889SApple OSS Distributions return 0;
290*43a90889SApple OSS Distributions }
291*43a90889SApple OSS Distributions
292*43a90889SApple OSS Distributions
293*43a90889SApple OSS Distributions /*
294*43a90889SApple OSS Distributions * geteuid
295*43a90889SApple OSS Distributions *
296*43a90889SApple OSS Distributions * Description: get effective user ID for caller
297*43a90889SApple OSS Distributions *
298*43a90889SApple OSS Distributions * Parameters: (void)
299*43a90889SApple OSS Distributions *
300*43a90889SApple OSS Distributions * Returns: uid_t The effective uid of the caller
301*43a90889SApple OSS Distributions */
302*43a90889SApple OSS Distributions int
geteuid(__unused proc_t p,__unused struct geteuid_args * uap,int32_t * retval)303*43a90889SApple OSS Distributions geteuid(__unused proc_t p, __unused struct geteuid_args *uap, int32_t *retval)
304*43a90889SApple OSS Distributions {
305*43a90889SApple OSS Distributions *retval = kauth_getuid();
306*43a90889SApple OSS Distributions return 0;
307*43a90889SApple OSS Distributions }
308*43a90889SApple OSS Distributions
309*43a90889SApple OSS Distributions
310*43a90889SApple OSS Distributions /*
311*43a90889SApple OSS Distributions * gettid
312*43a90889SApple OSS Distributions *
313*43a90889SApple OSS Distributions * Description: Return the per-thread override identity.
314*43a90889SApple OSS Distributions *
315*43a90889SApple OSS Distributions * Parameters: uap->uidp Address of uid_t to get uid
316*43a90889SApple OSS Distributions * uap->gidp Address of gid_t to get gid
317*43a90889SApple OSS Distributions *
318*43a90889SApple OSS Distributions * Returns: 0 Success
319*43a90889SApple OSS Distributions * ESRCH No per thread identity active
320*43a90889SApple OSS Distributions */
321*43a90889SApple OSS Distributions int
gettid(__unused proc_t p,struct gettid_args * uap,int32_t * retval)322*43a90889SApple OSS Distributions gettid(__unused proc_t p, struct gettid_args *uap, int32_t *retval)
323*43a90889SApple OSS Distributions {
324*43a90889SApple OSS Distributions thread_ro_t tro = current_thread_ro();
325*43a90889SApple OSS Distributions kauth_cred_t tro_cred = tro->tro_cred;
326*43a90889SApple OSS Distributions int error;
327*43a90889SApple OSS Distributions
328*43a90889SApple OSS Distributions /*
329*43a90889SApple OSS Distributions * If this thread is not running with an override identity, we can't
330*43a90889SApple OSS Distributions * return one to the caller, so return an error instead.
331*43a90889SApple OSS Distributions */
332*43a90889SApple OSS Distributions if (tro->tro_realcred == tro->tro_cred) {
333*43a90889SApple OSS Distributions return ESRCH;
334*43a90889SApple OSS Distributions }
335*43a90889SApple OSS Distributions
336*43a90889SApple OSS Distributions if ((error = suword(uap->uidp, kauth_cred_getruid(tro_cred)))) {
337*43a90889SApple OSS Distributions return error;
338*43a90889SApple OSS Distributions }
339*43a90889SApple OSS Distributions if ((error = suword(uap->gidp, kauth_cred_getrgid(tro_cred)))) {
340*43a90889SApple OSS Distributions return error;
341*43a90889SApple OSS Distributions }
342*43a90889SApple OSS Distributions
343*43a90889SApple OSS Distributions *retval = 0;
344*43a90889SApple OSS Distributions return 0;
345*43a90889SApple OSS Distributions }
346*43a90889SApple OSS Distributions
347*43a90889SApple OSS Distributions
348*43a90889SApple OSS Distributions /*
349*43a90889SApple OSS Distributions * getgid
350*43a90889SApple OSS Distributions *
351*43a90889SApple OSS Distributions * Description: get the real group ID for the calling process
352*43a90889SApple OSS Distributions *
353*43a90889SApple OSS Distributions * Parameters: (void)
354*43a90889SApple OSS Distributions *
355*43a90889SApple OSS Distributions * Returns: gid_t The real gid of the caller
356*43a90889SApple OSS Distributions */
357*43a90889SApple OSS Distributions int
getgid(__unused proc_t p,__unused struct getgid_args * uap,int32_t * retval)358*43a90889SApple OSS Distributions getgid(__unused proc_t p, __unused struct getgid_args *uap, int32_t *retval)
359*43a90889SApple OSS Distributions {
360*43a90889SApple OSS Distributions *retval = kauth_getrgid();
361*43a90889SApple OSS Distributions return 0;
362*43a90889SApple OSS Distributions }
363*43a90889SApple OSS Distributions
364*43a90889SApple OSS Distributions
365*43a90889SApple OSS Distributions /*
366*43a90889SApple OSS Distributions * getegid
367*43a90889SApple OSS Distributions *
368*43a90889SApple OSS Distributions * Description: get the effective group ID for the calling process
369*43a90889SApple OSS Distributions *
370*43a90889SApple OSS Distributions * Parameters: (void)
371*43a90889SApple OSS Distributions *
372*43a90889SApple OSS Distributions * Returns: gid_t The effective gid of the caller
373*43a90889SApple OSS Distributions *
374*43a90889SApple OSS Distributions * Notes: As an implementation detail, the effective gid is stored as
375*43a90889SApple OSS Distributions * the first element of the supplementary group list.
376*43a90889SApple OSS Distributions *
377*43a90889SApple OSS Distributions * This could be implemented in Libc instead because of the above
378*43a90889SApple OSS Distributions * detail.
379*43a90889SApple OSS Distributions */
380*43a90889SApple OSS Distributions int
getegid(__unused proc_t p,__unused struct getegid_args * uap,int32_t * retval)381*43a90889SApple OSS Distributions getegid(__unused proc_t p, __unused struct getegid_args *uap, int32_t *retval)
382*43a90889SApple OSS Distributions {
383*43a90889SApple OSS Distributions *retval = kauth_getgid();
384*43a90889SApple OSS Distributions return 0;
385*43a90889SApple OSS Distributions }
386*43a90889SApple OSS Distributions
387*43a90889SApple OSS Distributions
388*43a90889SApple OSS Distributions /*
389*43a90889SApple OSS Distributions * getgroups
390*43a90889SApple OSS Distributions *
391*43a90889SApple OSS Distributions * Description: get the list of supplementary groups for the calling process
392*43a90889SApple OSS Distributions *
393*43a90889SApple OSS Distributions * Parameters: uap->gidsetsize # of gid_t's in user buffer
394*43a90889SApple OSS Distributions * uap->gidset Pointer to user buffer
395*43a90889SApple OSS Distributions *
396*43a90889SApple OSS Distributions * Returns: 0 Success
397*43a90889SApple OSS Distributions * EINVAL User buffer too small
398*43a90889SApple OSS Distributions * copyout:EFAULT User buffer invalid
399*43a90889SApple OSS Distributions *
400*43a90889SApple OSS Distributions * Retval: -1 Error
401*43a90889SApple OSS Distributions * !0 # of groups
402*43a90889SApple OSS Distributions *
403*43a90889SApple OSS Distributions * Notes: The caller may specify a 0 value for gidsetsize, and we will
404*43a90889SApple OSS Distributions * then return how large a buffer is required (in gid_t's) to
405*43a90889SApple OSS Distributions * contain the answer at the time of the call. Otherwise, we
406*43a90889SApple OSS Distributions * return the number of gid_t's catually copied to user space.
407*43a90889SApple OSS Distributions *
408*43a90889SApple OSS Distributions * When called with a 0 gidsetsize from a multithreaded program,
409*43a90889SApple OSS Distributions * there is no guarantee that another thread may not change the
410*43a90889SApple OSS Distributions * number of supplementary groups, and therefore a subsequent
411*43a90889SApple OSS Distributions * call could still fail, unless the maximum possible buffer
412*43a90889SApple OSS Distributions * size is supplied by the user.
413*43a90889SApple OSS Distributions *
414*43a90889SApple OSS Distributions * As an implementation detail, the effective gid is stored as
415*43a90889SApple OSS Distributions * the first element of the supplementary group list, and will
416*43a90889SApple OSS Distributions * be returned by this call.
417*43a90889SApple OSS Distributions */
418*43a90889SApple OSS Distributions int
getgroups(__unused proc_t p,struct getgroups_args * uap,int32_t * retval)419*43a90889SApple OSS Distributions getgroups(__unused proc_t p, struct getgroups_args *uap, int32_t *retval)
420*43a90889SApple OSS Distributions {
421*43a90889SApple OSS Distributions int ngrp;
422*43a90889SApple OSS Distributions int error;
423*43a90889SApple OSS Distributions kauth_cred_t cred;
424*43a90889SApple OSS Distributions posix_cred_t pcred;
425*43a90889SApple OSS Distributions
426*43a90889SApple OSS Distributions /* grab reference while we muck around with the credential */
427*43a90889SApple OSS Distributions cred = kauth_cred_get_with_ref();
428*43a90889SApple OSS Distributions pcred = posix_cred_get(cred);
429*43a90889SApple OSS Distributions
430*43a90889SApple OSS Distributions if ((ngrp = uap->gidsetsize) == 0) {
431*43a90889SApple OSS Distributions *retval = pcred->cr_ngroups;
432*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
433*43a90889SApple OSS Distributions return 0;
434*43a90889SApple OSS Distributions }
435*43a90889SApple OSS Distributions if (ngrp < pcred->cr_ngroups) {
436*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
437*43a90889SApple OSS Distributions return EINVAL;
438*43a90889SApple OSS Distributions }
439*43a90889SApple OSS Distributions ngrp = pcred->cr_ngroups;
440*43a90889SApple OSS Distributions if ((error = copyout((caddr_t)pcred->cr_groups,
441*43a90889SApple OSS Distributions uap->gidset,
442*43a90889SApple OSS Distributions ngrp * sizeof(gid_t)))) {
443*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
444*43a90889SApple OSS Distributions return error;
445*43a90889SApple OSS Distributions }
446*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
447*43a90889SApple OSS Distributions *retval = ngrp;
448*43a90889SApple OSS Distributions return 0;
449*43a90889SApple OSS Distributions }
450*43a90889SApple OSS Distributions
451*43a90889SApple OSS Distributions
452*43a90889SApple OSS Distributions /*
453*43a90889SApple OSS Distributions * Return the per-thread/per-process supplementary groups list.
454*43a90889SApple OSS Distributions *
455*43a90889SApple OSS Distributions * XXX implement getsgroups
456*43a90889SApple OSS Distributions *
457*43a90889SApple OSS Distributions */
458*43a90889SApple OSS Distributions
459*43a90889SApple OSS Distributions int
getsgroups(__unused proc_t p,__unused struct getsgroups_args * uap,__unused int32_t * retval)460*43a90889SApple OSS Distributions getsgroups(__unused proc_t p, __unused struct getsgroups_args *uap, __unused int32_t *retval)
461*43a90889SApple OSS Distributions {
462*43a90889SApple OSS Distributions return ENOTSUP;
463*43a90889SApple OSS Distributions }
464*43a90889SApple OSS Distributions
465*43a90889SApple OSS Distributions /*
466*43a90889SApple OSS Distributions * Return the per-thread/per-process whiteout groups list.
467*43a90889SApple OSS Distributions *
468*43a90889SApple OSS Distributions * XXX implement getwgroups
469*43a90889SApple OSS Distributions *
470*43a90889SApple OSS Distributions */
471*43a90889SApple OSS Distributions
472*43a90889SApple OSS Distributions int
getwgroups(__unused proc_t p,__unused struct getwgroups_args * uap,__unused int32_t * retval)473*43a90889SApple OSS Distributions getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused int32_t *retval)
474*43a90889SApple OSS Distributions {
475*43a90889SApple OSS Distributions return ENOTSUP;
476*43a90889SApple OSS Distributions }
477*43a90889SApple OSS Distributions
478*43a90889SApple OSS Distributions /*
479*43a90889SApple OSS Distributions * setsid_internal
480*43a90889SApple OSS Distributions *
481*43a90889SApple OSS Distributions * Description: Core implementation of setsid().
482*43a90889SApple OSS Distributions */
483*43a90889SApple OSS Distributions int
setsid_internal(proc_t p)484*43a90889SApple OSS Distributions setsid_internal(proc_t p)
485*43a90889SApple OSS Distributions {
486*43a90889SApple OSS Distributions struct pgrp * pg = PGRP_NULL;
487*43a90889SApple OSS Distributions
488*43a90889SApple OSS Distributions if (p->p_pgrpid == proc_getpid(p) ||
489*43a90889SApple OSS Distributions (pg = pgrp_find(proc_getpid(p)))) {
490*43a90889SApple OSS Distributions pgrp_rele(pg);
491*43a90889SApple OSS Distributions return EPERM;
492*43a90889SApple OSS Distributions }
493*43a90889SApple OSS Distributions
494*43a90889SApple OSS Distributions /* enter pgrp works with its own pgrp refcount */
495*43a90889SApple OSS Distributions (void)enterpgrp(p, proc_getpid(p), 1);
496*43a90889SApple OSS Distributions return 0;
497*43a90889SApple OSS Distributions }
498*43a90889SApple OSS Distributions
499*43a90889SApple OSS Distributions /*
500*43a90889SApple OSS Distributions * setsid
501*43a90889SApple OSS Distributions *
502*43a90889SApple OSS Distributions * Description: Create a new session and set the process group ID to the
503*43a90889SApple OSS Distributions * session ID
504*43a90889SApple OSS Distributions *
505*43a90889SApple OSS Distributions * Parameters: (void)
506*43a90889SApple OSS Distributions *
507*43a90889SApple OSS Distributions * Returns: 0 Success
508*43a90889SApple OSS Distributions * EPERM Permission denied
509*43a90889SApple OSS Distributions *
510*43a90889SApple OSS Distributions * Notes: If the calling process is not the process group leader; there
511*43a90889SApple OSS Distributions * is no existing process group with its ID, then this function will
512*43a90889SApple OSS Distributions * create a new session, a new process group, and put the caller in the
513*43a90889SApple OSS Distributions * process group (as the sole member) and make it the session
514*43a90889SApple OSS Distributions * leader (as the sole process in the session).
515*43a90889SApple OSS Distributions *
516*43a90889SApple OSS Distributions * The existing controlling tty (if any) will be dissociated
517*43a90889SApple OSS Distributions * from the process, and the next non-O_NOCTTY open of a tty
518*43a90889SApple OSS Distributions * will establish a new controlling tty.
519*43a90889SApple OSS Distributions *
520*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
521*43a90889SApple OSS Distributions */
522*43a90889SApple OSS Distributions int
setsid(proc_t p,__unused struct setsid_args * uap,int32_t * retval)523*43a90889SApple OSS Distributions setsid(proc_t p, __unused struct setsid_args *uap, int32_t *retval)
524*43a90889SApple OSS Distributions {
525*43a90889SApple OSS Distributions int rc = setsid_internal(p);
526*43a90889SApple OSS Distributions if (rc == 0) {
527*43a90889SApple OSS Distributions *retval = proc_getpid(p);
528*43a90889SApple OSS Distributions }
529*43a90889SApple OSS Distributions return rc;
530*43a90889SApple OSS Distributions }
531*43a90889SApple OSS Distributions
532*43a90889SApple OSS Distributions
533*43a90889SApple OSS Distributions /*
534*43a90889SApple OSS Distributions * setpgid
535*43a90889SApple OSS Distributions *
536*43a90889SApple OSS Distributions * Description: set process group ID for job control
537*43a90889SApple OSS Distributions *
538*43a90889SApple OSS Distributions * Parameters: uap->pid Process to change
539*43a90889SApple OSS Distributions * uap->pgid Process group to join or create
540*43a90889SApple OSS Distributions *
541*43a90889SApple OSS Distributions * Returns: 0 Success
542*43a90889SApple OSS Distributions * ESRCH pid is not the caller or a child of
543*43a90889SApple OSS Distributions * the caller
544*43a90889SApple OSS Distributions * enterpgrp:ESRCH No such process
545*43a90889SApple OSS Distributions * EACCES Permission denied due to exec
546*43a90889SApple OSS Distributions * EINVAL Invalid argument
547*43a90889SApple OSS Distributions * EPERM The target process is not in the same
548*43a90889SApple OSS Distributions * session as the calling process
549*43a90889SApple OSS Distributions * EPERM The target process is a session leader
550*43a90889SApple OSS Distributions * EPERM pid and pgid are not the same, and
551*43a90889SApple OSS Distributions * there is no process in the calling
552*43a90889SApple OSS Distributions * process whose process group ID matches
553*43a90889SApple OSS Distributions * pgid
554*43a90889SApple OSS Distributions *
555*43a90889SApple OSS Distributions * Notes: This function will cause the target process to either join
556*43a90889SApple OSS Distributions * an existing process process group, or create a new process
557*43a90889SApple OSS Distributions * group in the session of the calling process. It cannot be
558*43a90889SApple OSS Distributions * used to change the process group ID of a process which is
559*43a90889SApple OSS Distributions * already a session leader.
560*43a90889SApple OSS Distributions *
561*43a90889SApple OSS Distributions * If the target pid is 0, the pid of the calling process is
562*43a90889SApple OSS Distributions * substituted as the new target; if pgid is 0, the target pid
563*43a90889SApple OSS Distributions * is used as the target process group ID.
564*43a90889SApple OSS Distributions *
565*43a90889SApple OSS Distributions * Legacy: This system call entry point is also used to implement the
566*43a90889SApple OSS Distributions * legacy library routine setpgrp(), which under POSIX
567*43a90889SApple OSS Distributions *
568*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
569*43a90889SApple OSS Distributions */
570*43a90889SApple OSS Distributions int
setpgid(proc_t curp,struct setpgid_args * uap,__unused int32_t * retval)571*43a90889SApple OSS Distributions setpgid(proc_t curp, struct setpgid_args *uap, __unused int32_t *retval)
572*43a90889SApple OSS Distributions {
573*43a90889SApple OSS Distributions proc_t targp = PROC_NULL; /* target process */
574*43a90889SApple OSS Distributions struct pgrp *curp_pg = PGRP_NULL;
575*43a90889SApple OSS Distributions struct pgrp *targp_pg = PGRP_NULL;
576*43a90889SApple OSS Distributions int error = 0;
577*43a90889SApple OSS Distributions int refheld = 0;
578*43a90889SApple OSS Distributions int samesess = 0;
579*43a90889SApple OSS Distributions
580*43a90889SApple OSS Distributions curp_pg = proc_pgrp(curp, NULL);
581*43a90889SApple OSS Distributions
582*43a90889SApple OSS Distributions if (uap->pid != 0 && uap->pid != proc_getpid(curp)) {
583*43a90889SApple OSS Distributions if ((targp = proc_find(uap->pid)) == 0 || !inferior(targp)) {
584*43a90889SApple OSS Distributions if (targp != PROC_NULL) {
585*43a90889SApple OSS Distributions refheld = 1;
586*43a90889SApple OSS Distributions }
587*43a90889SApple OSS Distributions error = ESRCH;
588*43a90889SApple OSS Distributions goto out;
589*43a90889SApple OSS Distributions }
590*43a90889SApple OSS Distributions refheld = 1;
591*43a90889SApple OSS Distributions targp_pg = proc_pgrp(targp, NULL);
592*43a90889SApple OSS Distributions if (targp_pg->pg_session != curp_pg->pg_session) {
593*43a90889SApple OSS Distributions error = EPERM;
594*43a90889SApple OSS Distributions goto out;
595*43a90889SApple OSS Distributions }
596*43a90889SApple OSS Distributions if (targp->p_flag & P_EXEC) {
597*43a90889SApple OSS Distributions error = EACCES;
598*43a90889SApple OSS Distributions goto out;
599*43a90889SApple OSS Distributions }
600*43a90889SApple OSS Distributions } else {
601*43a90889SApple OSS Distributions targp = curp;
602*43a90889SApple OSS Distributions targp_pg = proc_pgrp(targp, NULL);
603*43a90889SApple OSS Distributions }
604*43a90889SApple OSS Distributions
605*43a90889SApple OSS Distributions if (SESS_LEADER(targp, targp_pg->pg_session)) {
606*43a90889SApple OSS Distributions error = EPERM;
607*43a90889SApple OSS Distributions goto out;
608*43a90889SApple OSS Distributions }
609*43a90889SApple OSS Distributions
610*43a90889SApple OSS Distributions if (uap->pgid < 0) {
611*43a90889SApple OSS Distributions error = EINVAL;
612*43a90889SApple OSS Distributions goto out;
613*43a90889SApple OSS Distributions }
614*43a90889SApple OSS Distributions if (uap->pgid == 0) {
615*43a90889SApple OSS Distributions uap->pgid = proc_getpid(targp);
616*43a90889SApple OSS Distributions } else if (uap->pgid != proc_getpid(targp)) {
617*43a90889SApple OSS Distributions struct pgrp *pg = PGRP_NULL;
618*43a90889SApple OSS Distributions
619*43a90889SApple OSS Distributions if ((pg = pgrp_find(uap->pgid)) == PGRP_NULL) {
620*43a90889SApple OSS Distributions error = EPERM;
621*43a90889SApple OSS Distributions goto out;
622*43a90889SApple OSS Distributions }
623*43a90889SApple OSS Distributions samesess = (pg->pg_session != curp_pg->pg_session);
624*43a90889SApple OSS Distributions pgrp_rele(pg);
625*43a90889SApple OSS Distributions if (samesess != 0) {
626*43a90889SApple OSS Distributions error = EPERM;
627*43a90889SApple OSS Distributions goto out;
628*43a90889SApple OSS Distributions }
629*43a90889SApple OSS Distributions }
630*43a90889SApple OSS Distributions error = enterpgrp(targp, uap->pgid, 0);
631*43a90889SApple OSS Distributions out:
632*43a90889SApple OSS Distributions pgrp_rele(curp_pg);
633*43a90889SApple OSS Distributions pgrp_rele(targp_pg);
634*43a90889SApple OSS Distributions if (refheld != 0) {
635*43a90889SApple OSS Distributions proc_rele(targp);
636*43a90889SApple OSS Distributions }
637*43a90889SApple OSS Distributions return error;
638*43a90889SApple OSS Distributions }
639*43a90889SApple OSS Distributions
640*43a90889SApple OSS Distributions
641*43a90889SApple OSS Distributions /*
642*43a90889SApple OSS Distributions * issetugid
643*43a90889SApple OSS Distributions *
644*43a90889SApple OSS Distributions * Description: Is current process tainted by uid or gid changes system call
645*43a90889SApple OSS Distributions *
646*43a90889SApple OSS Distributions * Parameters: (void)
647*43a90889SApple OSS Distributions *
648*43a90889SApple OSS Distributions * Returns: 0 Not tainted
649*43a90889SApple OSS Distributions * 1 Tainted
650*43a90889SApple OSS Distributions *
651*43a90889SApple OSS Distributions * Notes: A process is considered tainted if it was created as a retult
652*43a90889SApple OSS Distributions * of an execve call from an imnage that had either the SUID or
653*43a90889SApple OSS Distributions * SGID bit set on the executable, or if it has changed any of its
654*43a90889SApple OSS Distributions * real, effective, or saved user or group IDs since beginning
655*43a90889SApple OSS Distributions * execution.
656*43a90889SApple OSS Distributions */
657*43a90889SApple OSS Distributions int
proc_issetugid(proc_t p)658*43a90889SApple OSS Distributions proc_issetugid(proc_t p)
659*43a90889SApple OSS Distributions {
660*43a90889SApple OSS Distributions return (p->p_flag & P_SUGID) ? 1 : 0;
661*43a90889SApple OSS Distributions }
662*43a90889SApple OSS Distributions
663*43a90889SApple OSS Distributions int
issetugid(proc_t p,__unused struct issetugid_args * uap,int32_t * retval)664*43a90889SApple OSS Distributions issetugid(proc_t p, __unused struct issetugid_args *uap, int32_t *retval)
665*43a90889SApple OSS Distributions {
666*43a90889SApple OSS Distributions /*
667*43a90889SApple OSS Distributions * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
668*43a90889SApple OSS Distributions * we use P_SUGID because we consider changing the owners as
669*43a90889SApple OSS Distributions * "tainting" as well.
670*43a90889SApple OSS Distributions * This is significant for procs that start as root and "become"
671*43a90889SApple OSS Distributions * a user without an exec - programs cannot know *everything*
672*43a90889SApple OSS Distributions * that libc *might* have put in their data segment.
673*43a90889SApple OSS Distributions */
674*43a90889SApple OSS Distributions
675*43a90889SApple OSS Distributions *retval = proc_issetugid(p);
676*43a90889SApple OSS Distributions return 0;
677*43a90889SApple OSS Distributions }
678*43a90889SApple OSS Distributions
679*43a90889SApple OSS Distributions /*
680*43a90889SApple OSS Distributions * setuid
681*43a90889SApple OSS Distributions *
682*43a90889SApple OSS Distributions * Description: Set user ID system call
683*43a90889SApple OSS Distributions *
684*43a90889SApple OSS Distributions * Parameters: uap->uid uid to set
685*43a90889SApple OSS Distributions *
686*43a90889SApple OSS Distributions * Returns: 0 Success
687*43a90889SApple OSS Distributions * suser:EPERM Permission denied
688*43a90889SApple OSS Distributions *
689*43a90889SApple OSS Distributions * Notes: If called by a privileged process, this function will set the
690*43a90889SApple OSS Distributions * real, effective, and saved uid to the requested value.
691*43a90889SApple OSS Distributions *
692*43a90889SApple OSS Distributions * If called from an unprivileged process, but uid is equal to the
693*43a90889SApple OSS Distributions * real or saved uid, then the effective uid will be set to the
694*43a90889SApple OSS Distributions * requested value, but the real and saved uid will not change.
695*43a90889SApple OSS Distributions *
696*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
697*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
698*43a90889SApple OSS Distributions */
699*43a90889SApple OSS Distributions int
setuid(proc_t p,struct setuid_args * uap,__unused int32_t * retval)700*43a90889SApple OSS Distributions setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval)
701*43a90889SApple OSS Distributions {
702*43a90889SApple OSS Distributions __block int error = 0;
703*43a90889SApple OSS Distributions __block uid_t old_ruid;
704*43a90889SApple OSS Distributions __block uid_t ruid;
705*43a90889SApple OSS Distributions uid_t want_uid;
706*43a90889SApple OSS Distributions bool changed;
707*43a90889SApple OSS Distributions
708*43a90889SApple OSS Distributions want_uid = uap->uid;
709*43a90889SApple OSS Distributions AUDIT_ARG(uid, want_uid);
710*43a90889SApple OSS Distributions
711*43a90889SApple OSS Distributions changed = kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
712*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
713*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
714*43a90889SApple OSS Distributions uid_t svuid = KAUTH_UID_NONE;
715*43a90889SApple OSS Distributions uid_t gmuid = KAUTH_UID_NONE;
716*43a90889SApple OSS Distributions
717*43a90889SApple OSS Distributions ruid = KAUTH_UID_NONE;
718*43a90889SApple OSS Distributions old_ruid = cur_pcred->cr_ruid;
719*43a90889SApple OSS Distributions
720*43a90889SApple OSS Distributions #if CONFIG_MACF
721*43a90889SApple OSS Distributions if ((error = mac_proc_check_setuid(p, parent, want_uid)) != 0) {
722*43a90889SApple OSS Distributions return false;
723*43a90889SApple OSS Distributions }
724*43a90889SApple OSS Distributions #endif
725*43a90889SApple OSS Distributions
726*43a90889SApple OSS Distributions if (want_uid != cur_pcred->cr_ruid && /* allow setuid(getuid()) */
727*43a90889SApple OSS Distributions want_uid != cur_pcred->cr_svuid && /* allow setuid(saved uid) */
728*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) {
729*43a90889SApple OSS Distributions return false;
730*43a90889SApple OSS Distributions }
731*43a90889SApple OSS Distributions
732*43a90889SApple OSS Distributions /*
733*43a90889SApple OSS Distributions * If we are privileged, then set the saved and real UID too;
734*43a90889SApple OSS Distributions * otherwise, just set the effective UID
735*43a90889SApple OSS Distributions */
736*43a90889SApple OSS Distributions if (suser(parent, &p->p_acflag) == 0) {
737*43a90889SApple OSS Distributions svuid = want_uid;
738*43a90889SApple OSS Distributions ruid = want_uid;
739*43a90889SApple OSS Distributions }
740*43a90889SApple OSS Distributions
741*43a90889SApple OSS Distributions /*
742*43a90889SApple OSS Distributions * Only set the gmuid if the current cred has not opt'ed out;
743*43a90889SApple OSS Distributions * this normally only happens when calling setgroups() instead
744*43a90889SApple OSS Distributions * of initgroups() to set an explicit group list, or one of the
745*43a90889SApple OSS Distributions * other group manipulation functions is invoked and results in
746*43a90889SApple OSS Distributions * a dislocation (i.e. the credential group membership changes
747*43a90889SApple OSS Distributions * to something other than the default list for the user, as
748*43a90889SApple OSS Distributions * in entering a group or leaving an exclusion group).
749*43a90889SApple OSS Distributions */
750*43a90889SApple OSS Distributions if (!(cur_pcred->cr_flags & CRF_NOMEMBERD)) {
751*43a90889SApple OSS Distributions gmuid = want_uid;
752*43a90889SApple OSS Distributions }
753*43a90889SApple OSS Distributions
754*43a90889SApple OSS Distributions return kauth_cred_model_setresuid(model,
755*43a90889SApple OSS Distributions ruid, want_uid, svuid, gmuid);
756*43a90889SApple OSS Distributions });
757*43a90889SApple OSS Distributions
758*43a90889SApple OSS Distributions if (changed && ruid != KAUTH_UID_NONE && old_ruid != ruid &&
759*43a90889SApple OSS Distributions !proc_has_persona(p)) {
760*43a90889SApple OSS Distributions (void)chgproccnt(ruid, 1);
761*43a90889SApple OSS Distributions (void)chgproccnt(old_ruid, -1);
762*43a90889SApple OSS Distributions }
763*43a90889SApple OSS Distributions
764*43a90889SApple OSS Distributions return error;
765*43a90889SApple OSS Distributions }
766*43a90889SApple OSS Distributions
767*43a90889SApple OSS Distributions
768*43a90889SApple OSS Distributions /*
769*43a90889SApple OSS Distributions * seteuid
770*43a90889SApple OSS Distributions *
771*43a90889SApple OSS Distributions * Description: Set effective user ID system call
772*43a90889SApple OSS Distributions *
773*43a90889SApple OSS Distributions * Parameters: uap->euid effective uid to set
774*43a90889SApple OSS Distributions *
775*43a90889SApple OSS Distributions * Returns: 0 Success
776*43a90889SApple OSS Distributions * suser:EPERM Permission denied
777*43a90889SApple OSS Distributions *
778*43a90889SApple OSS Distributions * Notes: If called by a privileged process, or called from an
779*43a90889SApple OSS Distributions * unprivileged process but euid is equal to the real or saved
780*43a90889SApple OSS Distributions * uid, then the effective uid will be set to the requested
781*43a90889SApple OSS Distributions * value, but the real and saved uid will not change.
782*43a90889SApple OSS Distributions *
783*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
784*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
785*43a90889SApple OSS Distributions */
786*43a90889SApple OSS Distributions int
seteuid(proc_t p,struct seteuid_args * uap,__unused int32_t * retval)787*43a90889SApple OSS Distributions seteuid(proc_t p, struct seteuid_args *uap, __unused int32_t *retval)
788*43a90889SApple OSS Distributions {
789*43a90889SApple OSS Distributions __block int error = 0;
790*43a90889SApple OSS Distributions uid_t want_euid;
791*43a90889SApple OSS Distributions
792*43a90889SApple OSS Distributions want_euid = uap->euid;
793*43a90889SApple OSS Distributions AUDIT_ARG(euid, want_euid);
794*43a90889SApple OSS Distributions
795*43a90889SApple OSS Distributions kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
796*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
797*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
798*43a90889SApple OSS Distributions
799*43a90889SApple OSS Distributions #if CONFIG_MACF
800*43a90889SApple OSS Distributions if ((error = mac_proc_check_seteuid(p, parent, want_euid)) != 0) {
801*43a90889SApple OSS Distributions return false;
802*43a90889SApple OSS Distributions }
803*43a90889SApple OSS Distributions #endif
804*43a90889SApple OSS Distributions
805*43a90889SApple OSS Distributions if (want_euid != cur_pcred->cr_ruid && want_euid != cur_pcred->cr_svuid &&
806*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) {
807*43a90889SApple OSS Distributions return false;
808*43a90889SApple OSS Distributions }
809*43a90889SApple OSS Distributions
810*43a90889SApple OSS Distributions return kauth_cred_model_setresuid(model,
811*43a90889SApple OSS Distributions KAUTH_UID_NONE, want_euid,
812*43a90889SApple OSS Distributions KAUTH_UID_NONE, cur_pcred->cr_gmuid);
813*43a90889SApple OSS Distributions });
814*43a90889SApple OSS Distributions
815*43a90889SApple OSS Distributions return error;
816*43a90889SApple OSS Distributions }
817*43a90889SApple OSS Distributions
818*43a90889SApple OSS Distributions
819*43a90889SApple OSS Distributions /*
820*43a90889SApple OSS Distributions * setreuid
821*43a90889SApple OSS Distributions *
822*43a90889SApple OSS Distributions * Description: Set real and effective user ID system call
823*43a90889SApple OSS Distributions *
824*43a90889SApple OSS Distributions * Parameters: uap->ruid real uid to set
825*43a90889SApple OSS Distributions * uap->euid effective uid to set
826*43a90889SApple OSS Distributions *
827*43a90889SApple OSS Distributions * Returns: 0 Success
828*43a90889SApple OSS Distributions * suser:EPERM Permission denied
829*43a90889SApple OSS Distributions *
830*43a90889SApple OSS Distributions * Notes: A value of -1 is a special case indicating that the uid for
831*43a90889SApple OSS Distributions * which that value is specified not be changed. If both values
832*43a90889SApple OSS Distributions * are specified as -1, no action is taken.
833*43a90889SApple OSS Distributions *
834*43a90889SApple OSS Distributions * If called by a privileged process, the real and effective uid
835*43a90889SApple OSS Distributions * will be set to the new value(s) specified.
836*43a90889SApple OSS Distributions *
837*43a90889SApple OSS Distributions * If called from an unprivileged process, the real uid may be
838*43a90889SApple OSS Distributions * set to the current value of the real uid, or to the current
839*43a90889SApple OSS Distributions * value of the saved uid. The effective uid may be set to the
840*43a90889SApple OSS Distributions * current value of any of the effective, real, or saved uid.
841*43a90889SApple OSS Distributions *
842*43a90889SApple OSS Distributions * If the newly requested real uid or effective uid does not
843*43a90889SApple OSS Distributions * match the saved uid, then set the saved uid to the new
844*43a90889SApple OSS Distributions * effective uid (potentially unrecoverably dropping saved
845*43a90889SApple OSS Distributions * privilege).
846*43a90889SApple OSS Distributions *
847*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
848*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
849*43a90889SApple OSS Distributions */
850*43a90889SApple OSS Distributions int
setreuid(proc_t p,struct setreuid_args * uap,__unused int32_t * retval)851*43a90889SApple OSS Distributions setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval)
852*43a90889SApple OSS Distributions {
853*43a90889SApple OSS Distributions __block int error = 0;
854*43a90889SApple OSS Distributions __block uid_t old_ruid;
855*43a90889SApple OSS Distributions uid_t want_ruid, want_euid;
856*43a90889SApple OSS Distributions bool changed;
857*43a90889SApple OSS Distributions
858*43a90889SApple OSS Distributions want_ruid = uap->ruid;
859*43a90889SApple OSS Distributions want_euid = uap->euid;
860*43a90889SApple OSS Distributions
861*43a90889SApple OSS Distributions if (want_ruid == (uid_t)-1) {
862*43a90889SApple OSS Distributions want_ruid = KAUTH_UID_NONE;
863*43a90889SApple OSS Distributions }
864*43a90889SApple OSS Distributions
865*43a90889SApple OSS Distributions if (want_euid == (uid_t)-1) {
866*43a90889SApple OSS Distributions want_euid = KAUTH_UID_NONE;
867*43a90889SApple OSS Distributions }
868*43a90889SApple OSS Distributions
869*43a90889SApple OSS Distributions AUDIT_ARG(euid, want_euid);
870*43a90889SApple OSS Distributions AUDIT_ARG(ruid, want_ruid);
871*43a90889SApple OSS Distributions
872*43a90889SApple OSS Distributions changed = kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
873*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
874*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
875*43a90889SApple OSS Distributions uid_t svuid = KAUTH_UID_NONE;
876*43a90889SApple OSS Distributions
877*43a90889SApple OSS Distributions #if CONFIG_MACF
878*43a90889SApple OSS Distributions if ((error = mac_proc_check_setreuid(p, parent, want_ruid, want_euid)) != 0) {
879*43a90889SApple OSS Distributions return false;
880*43a90889SApple OSS Distributions }
881*43a90889SApple OSS Distributions #endif
882*43a90889SApple OSS Distributions
883*43a90889SApple OSS Distributions if (((want_ruid != KAUTH_UID_NONE && /* allow no change of ruid */
884*43a90889SApple OSS Distributions want_ruid != cur_pcred->cr_ruid && /* allow ruid = ruid */
885*43a90889SApple OSS Distributions want_ruid != cur_pcred->cr_uid && /* allow ruid = euid */
886*43a90889SApple OSS Distributions want_ruid != cur_pcred->cr_svuid) || /* allow ruid = svuid */
887*43a90889SApple OSS Distributions (want_euid != KAUTH_UID_NONE && /* allow no change of euid */
888*43a90889SApple OSS Distributions want_euid != cur_pcred->cr_uid && /* allow euid = euid */
889*43a90889SApple OSS Distributions want_euid != cur_pcred->cr_ruid && /* allow euid = ruid */
890*43a90889SApple OSS Distributions want_euid != cur_pcred->cr_svuid)) && /* allow euid = svuid */
891*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) { /* allow root user any */
892*43a90889SApple OSS Distributions return false;
893*43a90889SApple OSS Distributions }
894*43a90889SApple OSS Distributions
895*43a90889SApple OSS Distributions uid_t new_euid = cur_pcred->cr_uid;
896*43a90889SApple OSS Distributions
897*43a90889SApple OSS Distributions if (want_euid != KAUTH_UID_NONE && cur_pcred->cr_uid != want_euid) {
898*43a90889SApple OSS Distributions new_euid = want_euid;
899*43a90889SApple OSS Distributions }
900*43a90889SApple OSS Distributions
901*43a90889SApple OSS Distributions old_ruid = cur_pcred->cr_ruid;
902*43a90889SApple OSS Distributions
903*43a90889SApple OSS Distributions /*
904*43a90889SApple OSS Distributions * If the newly requested real uid or effective uid does
905*43a90889SApple OSS Distributions * not match the saved uid, then set the saved uid to the
906*43a90889SApple OSS Distributions * new effective uid. We are protected from escalation
907*43a90889SApple OSS Distributions * by the prechecking.
908*43a90889SApple OSS Distributions */
909*43a90889SApple OSS Distributions if (cur_pcred->cr_svuid != uap->ruid &&
910*43a90889SApple OSS Distributions cur_pcred->cr_svuid != uap->euid) {
911*43a90889SApple OSS Distributions svuid = new_euid;
912*43a90889SApple OSS Distributions }
913*43a90889SApple OSS Distributions
914*43a90889SApple OSS Distributions return kauth_cred_model_setresuid(model, want_ruid, want_euid,
915*43a90889SApple OSS Distributions svuid, cur_pcred->cr_gmuid);
916*43a90889SApple OSS Distributions });
917*43a90889SApple OSS Distributions
918*43a90889SApple OSS Distributions if (changed && want_ruid != KAUTH_UID_NONE && want_ruid != old_ruid &&
919*43a90889SApple OSS Distributions !proc_has_persona(p)) {
920*43a90889SApple OSS Distributions (void)chgproccnt(want_ruid, 1);
921*43a90889SApple OSS Distributions (void)chgproccnt(old_ruid, -1);
922*43a90889SApple OSS Distributions }
923*43a90889SApple OSS Distributions
924*43a90889SApple OSS Distributions return error;
925*43a90889SApple OSS Distributions }
926*43a90889SApple OSS Distributions
927*43a90889SApple OSS Distributions
928*43a90889SApple OSS Distributions /*
929*43a90889SApple OSS Distributions * setgid
930*43a90889SApple OSS Distributions *
931*43a90889SApple OSS Distributions * Description: Set group ID system call
932*43a90889SApple OSS Distributions *
933*43a90889SApple OSS Distributions * Parameters: uap->gid gid to set
934*43a90889SApple OSS Distributions *
935*43a90889SApple OSS Distributions * Returns: 0 Success
936*43a90889SApple OSS Distributions * suser:EPERM Permission denied
937*43a90889SApple OSS Distributions *
938*43a90889SApple OSS Distributions * Notes: If called by a privileged process, this function will set the
939*43a90889SApple OSS Distributions * real, effective, and saved gid to the requested value.
940*43a90889SApple OSS Distributions *
941*43a90889SApple OSS Distributions * If called from an unprivileged process, but gid is equal to the
942*43a90889SApple OSS Distributions * real or saved gid, then the effective gid will be set to the
943*43a90889SApple OSS Distributions * requested value, but the real and saved gid will not change.
944*43a90889SApple OSS Distributions *
945*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
946*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
947*43a90889SApple OSS Distributions *
948*43a90889SApple OSS Distributions * As an implementation detail, the effective gid is stored as
949*43a90889SApple OSS Distributions * the first element of the supplementary group list, and
950*43a90889SApple OSS Distributions * therefore the effective group list may be reordered to keep
951*43a90889SApple OSS Distributions * the supplementary group list unchanged.
952*43a90889SApple OSS Distributions */
953*43a90889SApple OSS Distributions int
setgid(proc_t p,struct setgid_args * uap,__unused int32_t * retval)954*43a90889SApple OSS Distributions setgid(proc_t p, struct setgid_args *uap, __unused int32_t *retval)
955*43a90889SApple OSS Distributions {
956*43a90889SApple OSS Distributions __block int error = 0;
957*43a90889SApple OSS Distributions gid_t want_gid;
958*43a90889SApple OSS Distributions
959*43a90889SApple OSS Distributions want_gid = uap->gid;
960*43a90889SApple OSS Distributions AUDIT_ARG(gid, want_gid);
961*43a90889SApple OSS Distributions
962*43a90889SApple OSS Distributions kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
963*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
964*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
965*43a90889SApple OSS Distributions gid_t rgid = KAUTH_GID_NONE;
966*43a90889SApple OSS Distributions gid_t svgid = KAUTH_GID_NONE;
967*43a90889SApple OSS Distributions
968*43a90889SApple OSS Distributions #if CONFIG_MACF
969*43a90889SApple OSS Distributions if ((error = mac_proc_check_setgid(p, parent, want_gid)) != 0) {
970*43a90889SApple OSS Distributions return false;
971*43a90889SApple OSS Distributions }
972*43a90889SApple OSS Distributions #endif
973*43a90889SApple OSS Distributions
974*43a90889SApple OSS Distributions if (want_gid != cur_pcred->cr_rgid && /* allow setgid(getgid()) */
975*43a90889SApple OSS Distributions want_gid != cur_pcred->cr_svgid && /* allow setgid(saved gid) */
976*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) {
977*43a90889SApple OSS Distributions return false;
978*43a90889SApple OSS Distributions }
979*43a90889SApple OSS Distributions
980*43a90889SApple OSS Distributions /*
981*43a90889SApple OSS Distributions * If we are privileged, then set the saved and real GID too;
982*43a90889SApple OSS Distributions * otherwise, just set the effective GID
983*43a90889SApple OSS Distributions */
984*43a90889SApple OSS Distributions if (suser(parent, &p->p_acflag) == 0) {
985*43a90889SApple OSS Distributions svgid = want_gid;
986*43a90889SApple OSS Distributions rgid = want_gid;
987*43a90889SApple OSS Distributions }
988*43a90889SApple OSS Distributions
989*43a90889SApple OSS Distributions return kauth_cred_model_setresgid(model, rgid, want_gid, svgid);
990*43a90889SApple OSS Distributions });
991*43a90889SApple OSS Distributions
992*43a90889SApple OSS Distributions return error;
993*43a90889SApple OSS Distributions }
994*43a90889SApple OSS Distributions
995*43a90889SApple OSS Distributions
996*43a90889SApple OSS Distributions /*
997*43a90889SApple OSS Distributions * setegid
998*43a90889SApple OSS Distributions *
999*43a90889SApple OSS Distributions * Description: Set effective group ID system call
1000*43a90889SApple OSS Distributions *
1001*43a90889SApple OSS Distributions * Parameters: uap->egid effective gid to set
1002*43a90889SApple OSS Distributions *
1003*43a90889SApple OSS Distributions * Returns: 0 Success
1004*43a90889SApple OSS Distributions * suser:EPERM
1005*43a90889SApple OSS Distributions *
1006*43a90889SApple OSS Distributions * Notes: If called by a privileged process, or called from an
1007*43a90889SApple OSS Distributions * unprivileged process but egid is equal to the real or saved
1008*43a90889SApple OSS Distributions * gid, then the effective gid will be set to the requested
1009*43a90889SApple OSS Distributions * value, but the real and saved gid will not change.
1010*43a90889SApple OSS Distributions *
1011*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
1012*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
1013*43a90889SApple OSS Distributions *
1014*43a90889SApple OSS Distributions * As an implementation detail, the effective gid is stored as
1015*43a90889SApple OSS Distributions * the first element of the supplementary group list, and
1016*43a90889SApple OSS Distributions * therefore the effective group list may be reordered to keep
1017*43a90889SApple OSS Distributions * the supplementary group list unchanged.
1018*43a90889SApple OSS Distributions */
1019*43a90889SApple OSS Distributions int
setegid(proc_t p,struct setegid_args * uap,__unused int32_t * retval)1020*43a90889SApple OSS Distributions setegid(proc_t p, struct setegid_args *uap, __unused int32_t *retval)
1021*43a90889SApple OSS Distributions {
1022*43a90889SApple OSS Distributions __block int error = 0;
1023*43a90889SApple OSS Distributions gid_t want_egid;
1024*43a90889SApple OSS Distributions
1025*43a90889SApple OSS Distributions want_egid = uap->egid;
1026*43a90889SApple OSS Distributions AUDIT_ARG(egid, want_egid);
1027*43a90889SApple OSS Distributions
1028*43a90889SApple OSS Distributions kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
1029*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
1030*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
1031*43a90889SApple OSS Distributions
1032*43a90889SApple OSS Distributions #if CONFIG_MACF
1033*43a90889SApple OSS Distributions if ((error = mac_proc_check_setegid(p, parent, want_egid)) != 0) {
1034*43a90889SApple OSS Distributions return false;
1035*43a90889SApple OSS Distributions }
1036*43a90889SApple OSS Distributions #endif
1037*43a90889SApple OSS Distributions
1038*43a90889SApple OSS Distributions if (want_egid != cur_pcred->cr_rgid &&
1039*43a90889SApple OSS Distributions want_egid != cur_pcred->cr_svgid &&
1040*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) {
1041*43a90889SApple OSS Distributions return false;
1042*43a90889SApple OSS Distributions }
1043*43a90889SApple OSS Distributions
1044*43a90889SApple OSS Distributions return kauth_cred_model_setresgid(model, KAUTH_GID_NONE,
1045*43a90889SApple OSS Distributions want_egid, KAUTH_GID_NONE);
1046*43a90889SApple OSS Distributions });
1047*43a90889SApple OSS Distributions
1048*43a90889SApple OSS Distributions return error;
1049*43a90889SApple OSS Distributions }
1050*43a90889SApple OSS Distributions
1051*43a90889SApple OSS Distributions /*
1052*43a90889SApple OSS Distributions * setregid
1053*43a90889SApple OSS Distributions *
1054*43a90889SApple OSS Distributions * Description: Set real and effective group ID system call
1055*43a90889SApple OSS Distributions *
1056*43a90889SApple OSS Distributions * Parameters: uap->rgid real gid to set
1057*43a90889SApple OSS Distributions * uap->egid effective gid to set
1058*43a90889SApple OSS Distributions *
1059*43a90889SApple OSS Distributions * Returns: 0 Success
1060*43a90889SApple OSS Distributions * suser:EPERM Permission denied
1061*43a90889SApple OSS Distributions *
1062*43a90889SApple OSS Distributions * Notes: A value of -1 is a special case indicating that the gid for
1063*43a90889SApple OSS Distributions * which that value is specified not be changed. If both values
1064*43a90889SApple OSS Distributions * are specified as -1, no action is taken.
1065*43a90889SApple OSS Distributions *
1066*43a90889SApple OSS Distributions * If called by a privileged process, the real and effective gid
1067*43a90889SApple OSS Distributions * will be set to the new value(s) specified.
1068*43a90889SApple OSS Distributions *
1069*43a90889SApple OSS Distributions * If called from an unprivileged process, the real gid may be
1070*43a90889SApple OSS Distributions * set to the current value of the real gid, or to the current
1071*43a90889SApple OSS Distributions * value of the saved gid. The effective gid may be set to the
1072*43a90889SApple OSS Distributions * current value of any of the effective, real, or saved gid.
1073*43a90889SApple OSS Distributions *
1074*43a90889SApple OSS Distributions * If the new real and effective gid will not be equal, or the
1075*43a90889SApple OSS Distributions * new real or effective gid is not the same as the saved gid,
1076*43a90889SApple OSS Distributions * then the saved gid will be updated to reflect the new
1077*43a90889SApple OSS Distributions * effective gid (potentially unrecoverably dropping saved
1078*43a90889SApple OSS Distributions * privilege).
1079*43a90889SApple OSS Distributions *
1080*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
1081*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
1082*43a90889SApple OSS Distributions *
1083*43a90889SApple OSS Distributions * As an implementation detail, the effective gid is stored as
1084*43a90889SApple OSS Distributions * the first element of the supplementary group list, and
1085*43a90889SApple OSS Distributions * therefore the effective group list may be reordered to keep
1086*43a90889SApple OSS Distributions * the supplementary group list unchanged.
1087*43a90889SApple OSS Distributions */
1088*43a90889SApple OSS Distributions int
setregid(proc_t p,struct setregid_args * uap,__unused int32_t * retval)1089*43a90889SApple OSS Distributions setregid(proc_t p, struct setregid_args *uap, __unused int32_t *retval)
1090*43a90889SApple OSS Distributions {
1091*43a90889SApple OSS Distributions __block int error = 0;
1092*43a90889SApple OSS Distributions gid_t want_rgid;
1093*43a90889SApple OSS Distributions gid_t want_egid;
1094*43a90889SApple OSS Distributions
1095*43a90889SApple OSS Distributions want_rgid = uap->rgid;
1096*43a90889SApple OSS Distributions want_egid = uap->egid;
1097*43a90889SApple OSS Distributions
1098*43a90889SApple OSS Distributions if (want_rgid == (gid_t)-1) {
1099*43a90889SApple OSS Distributions want_rgid = KAUTH_GID_NONE;
1100*43a90889SApple OSS Distributions }
1101*43a90889SApple OSS Distributions
1102*43a90889SApple OSS Distributions if (want_egid == (gid_t)-1) {
1103*43a90889SApple OSS Distributions want_egid = KAUTH_GID_NONE;
1104*43a90889SApple OSS Distributions }
1105*43a90889SApple OSS Distributions
1106*43a90889SApple OSS Distributions AUDIT_ARG(egid, want_egid);
1107*43a90889SApple OSS Distributions AUDIT_ARG(rgid, want_rgid);
1108*43a90889SApple OSS Distributions
1109*43a90889SApple OSS Distributions kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID,
1110*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent, kauth_cred_t model) {
1111*43a90889SApple OSS Distributions posix_cred_t cur_pcred = posix_cred_get(parent);
1112*43a90889SApple OSS Distributions uid_t svgid = KAUTH_UID_NONE;
1113*43a90889SApple OSS Distributions
1114*43a90889SApple OSS Distributions #if CONFIG_MACF
1115*43a90889SApple OSS Distributions if ((error = mac_proc_check_setregid(p, parent, want_rgid,
1116*43a90889SApple OSS Distributions want_egid)) != 0) {
1117*43a90889SApple OSS Distributions return false;
1118*43a90889SApple OSS Distributions }
1119*43a90889SApple OSS Distributions #endif
1120*43a90889SApple OSS Distributions
1121*43a90889SApple OSS Distributions if (((want_rgid != KAUTH_UID_NONE && /* allow no change of rgid */
1122*43a90889SApple OSS Distributions want_rgid != cur_pcred->cr_rgid && /* allow rgid = rgid */
1123*43a90889SApple OSS Distributions want_rgid != cur_pcred->cr_gid && /* allow rgid = egid */
1124*43a90889SApple OSS Distributions want_rgid != cur_pcred->cr_svgid) || /* allow rgid = svgid */
1125*43a90889SApple OSS Distributions (want_egid != KAUTH_UID_NONE && /* allow no change of egid */
1126*43a90889SApple OSS Distributions want_egid != cur_pcred->cr_groups[0] && /* allow no change of egid */
1127*43a90889SApple OSS Distributions want_egid != cur_pcred->cr_gid && /* allow egid = egid */
1128*43a90889SApple OSS Distributions want_egid != cur_pcred->cr_rgid && /* allow egid = rgid */
1129*43a90889SApple OSS Distributions want_egid != cur_pcred->cr_svgid)) && /* allow egid = svgid */
1130*43a90889SApple OSS Distributions (error = suser(parent, &p->p_acflag))) { /* allow root user any */
1131*43a90889SApple OSS Distributions return false;
1132*43a90889SApple OSS Distributions }
1133*43a90889SApple OSS Distributions
1134*43a90889SApple OSS Distributions uid_t new_egid = cur_pcred->cr_gid;
1135*43a90889SApple OSS Distributions if (want_egid != KAUTH_UID_NONE && cur_pcred->cr_gid != want_egid) {
1136*43a90889SApple OSS Distributions /* changing the effective GID */
1137*43a90889SApple OSS Distributions new_egid = want_egid;
1138*43a90889SApple OSS Distributions }
1139*43a90889SApple OSS Distributions
1140*43a90889SApple OSS Distributions /*
1141*43a90889SApple OSS Distributions * If the newly requested real gid or effective gid does
1142*43a90889SApple OSS Distributions * not match the saved gid, then set the saved gid to the
1143*43a90889SApple OSS Distributions * new effective gid. We are protected from escalation
1144*43a90889SApple OSS Distributions * by the prechecking.
1145*43a90889SApple OSS Distributions */
1146*43a90889SApple OSS Distributions if (cur_pcred->cr_svgid != want_rgid &&
1147*43a90889SApple OSS Distributions cur_pcred->cr_svgid != want_egid) {
1148*43a90889SApple OSS Distributions svgid = new_egid;
1149*43a90889SApple OSS Distributions }
1150*43a90889SApple OSS Distributions
1151*43a90889SApple OSS Distributions return kauth_cred_model_setresgid(model, want_rgid, want_egid, svgid);
1152*43a90889SApple OSS Distributions });
1153*43a90889SApple OSS Distributions
1154*43a90889SApple OSS Distributions return error;
1155*43a90889SApple OSS Distributions }
1156*43a90889SApple OSS Distributions
1157*43a90889SApple OSS Distributions
1158*43a90889SApple OSS Distributions static void
kern_settid_assume_cred(thread_ro_t tro,kauth_cred_t tmp)1159*43a90889SApple OSS Distributions kern_settid_assume_cred(thread_ro_t tro, kauth_cred_t tmp)
1160*43a90889SApple OSS Distributions {
1161*43a90889SApple OSS Distributions kauth_cred_t cred = tro->tro_cred;
1162*43a90889SApple OSS Distributions
1163*43a90889SApple OSS Distributions kauth_cred_set(&cred, tmp);
1164*43a90889SApple OSS Distributions zalloc_ro_update_field(ZONE_ID_THREAD_RO, tro, tro_cred, &cred);
1165*43a90889SApple OSS Distributions }
1166*43a90889SApple OSS Distributions
1167*43a90889SApple OSS Distributions /*
1168*43a90889SApple OSS Distributions * Set the per-thread override identity. The first parameter can be the
1169*43a90889SApple OSS Distributions * current real UID, KAUTH_UID_NONE, or, if the caller is privileged, it
1170*43a90889SApple OSS Distributions * can be any UID. If it is KAUTH_UID_NONE, then as a special case, this
1171*43a90889SApple OSS Distributions * means "revert to the per process credential"; otherwise, if permitted,
1172*43a90889SApple OSS Distributions * it changes the effective, real, and saved UIDs and GIDs for the current
1173*43a90889SApple OSS Distributions * thread to the requested UID and single GID, and clears all other GIDs.
1174*43a90889SApple OSS Distributions */
1175*43a90889SApple OSS Distributions static int
kern_settid(proc_t p,uid_t uid,gid_t gid)1176*43a90889SApple OSS Distributions kern_settid(proc_t p, uid_t uid, gid_t gid)
1177*43a90889SApple OSS Distributions {
1178*43a90889SApple OSS Distributions kauth_cred_t cred;
1179*43a90889SApple OSS Distributions struct thread_ro *tro = current_thread_ro();
1180*43a90889SApple OSS Distributions #if CONFIG_MACF
1181*43a90889SApple OSS Distributions int error;
1182*43a90889SApple OSS Distributions
1183*43a90889SApple OSS Distributions if ((error = mac_proc_check_settid(p, uid, gid)) != 0) {
1184*43a90889SApple OSS Distributions return error;
1185*43a90889SApple OSS Distributions }
1186*43a90889SApple OSS Distributions #endif
1187*43a90889SApple OSS Distributions
1188*43a90889SApple OSS Distributions if (proc_suser(p) != 0) {
1189*43a90889SApple OSS Distributions return EPERM;
1190*43a90889SApple OSS Distributions }
1191*43a90889SApple OSS Distributions
1192*43a90889SApple OSS Distributions if (uid == KAUTH_UID_NONE) {
1193*43a90889SApple OSS Distributions /* must already be assuming another identity in order to revert back */
1194*43a90889SApple OSS Distributions if (tro->tro_realcred == tro->tro_cred) {
1195*43a90889SApple OSS Distributions return EPERM;
1196*43a90889SApple OSS Distributions }
1197*43a90889SApple OSS Distributions
1198*43a90889SApple OSS Distributions /* revert to delayed binding of process credential */
1199*43a90889SApple OSS Distributions kern_settid_assume_cred(tro, tro->tro_realcred);
1200*43a90889SApple OSS Distributions } else {
1201*43a90889SApple OSS Distributions /* cannot already be assuming another identity */
1202*43a90889SApple OSS Distributions if (tro->tro_realcred != tro->tro_cred) {
1203*43a90889SApple OSS Distributions return EPERM;
1204*43a90889SApple OSS Distributions }
1205*43a90889SApple OSS Distributions
1206*43a90889SApple OSS Distributions /*
1207*43a90889SApple OSS Distributions * Get a new credential instance from the old if this one
1208*43a90889SApple OSS Distributions * changes; otherwise kauth_cred_setuidgid() returns the
1209*43a90889SApple OSS Distributions * same credential. We take an extra reference on the
1210*43a90889SApple OSS Distributions * current credential while we muck with it, so we can do
1211*43a90889SApple OSS Distributions * the post-compare for changes by pointer.
1212*43a90889SApple OSS Distributions */
1213*43a90889SApple OSS Distributions cred = kauth_cred_derive(tro->tro_cred,
1214*43a90889SApple OSS Distributions ^bool (kauth_cred_t parent __unused, kauth_cred_t model) {
1215*43a90889SApple OSS Distributions return kauth_cred_model_setuidgid(model, uid, gid);
1216*43a90889SApple OSS Distributions });
1217*43a90889SApple OSS Distributions kern_settid_assume_cred(tro, cred);
1218*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
1219*43a90889SApple OSS Distributions }
1220*43a90889SApple OSS Distributions
1221*43a90889SApple OSS Distributions /*
1222*43a90889SApple OSS Distributions * XXX should potentially set per thread security token (there is
1223*43a90889SApple OSS Distributions * XXX none).
1224*43a90889SApple OSS Distributions * XXX it is unclear whether P_SUGID should be st at this point;
1225*43a90889SApple OSS Distributions * XXX in theory, it is being deprecated.
1226*43a90889SApple OSS Distributions */
1227*43a90889SApple OSS Distributions return 0;
1228*43a90889SApple OSS Distributions }
1229*43a90889SApple OSS Distributions
1230*43a90889SApple OSS Distributions int
sys_settid(proc_t p,struct settid_args * uap,__unused int32_t * retval)1231*43a90889SApple OSS Distributions sys_settid(proc_t p, struct settid_args *uap, __unused int32_t *retval)
1232*43a90889SApple OSS Distributions {
1233*43a90889SApple OSS Distributions AUDIT_ARG(uid, uap->uid);
1234*43a90889SApple OSS Distributions AUDIT_ARG(gid, uap->gid);
1235*43a90889SApple OSS Distributions
1236*43a90889SApple OSS Distributions return kern_settid(p, uap->uid, uap->gid);
1237*43a90889SApple OSS Distributions }
1238*43a90889SApple OSS Distributions
1239*43a90889SApple OSS Distributions
1240*43a90889SApple OSS Distributions /*
1241*43a90889SApple OSS Distributions * Set the per-thread override identity. Use this system call for a thread to
1242*43a90889SApple OSS Distributions * assume the identity of another process or to revert back to normal identity
1243*43a90889SApple OSS Distributions * of the current process.
1244*43a90889SApple OSS Distributions *
1245*43a90889SApple OSS Distributions * When the "assume" argument is non zero the current thread will assume the
1246*43a90889SApple OSS Distributions * identity of the process represented by the pid argument.
1247*43a90889SApple OSS Distributions *
1248*43a90889SApple OSS Distributions * When the assume argument is zero we revert back to our normal identity.
1249*43a90889SApple OSS Distributions */
1250*43a90889SApple OSS Distributions int
sys_settid_with_pid(proc_t p,struct settid_with_pid_args * uap,__unused int32_t * retval)1251*43a90889SApple OSS Distributions sys_settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused int32_t *retval)
1252*43a90889SApple OSS Distributions {
1253*43a90889SApple OSS Distributions uid_t uid;
1254*43a90889SApple OSS Distributions gid_t gid;
1255*43a90889SApple OSS Distributions
1256*43a90889SApple OSS Distributions AUDIT_ARG(pid, uap->pid);
1257*43a90889SApple OSS Distributions AUDIT_ARG(value32, uap->assume);
1258*43a90889SApple OSS Distributions
1259*43a90889SApple OSS Distributions /*
1260*43a90889SApple OSS Distributions * XXX should potentially set per thread security token (there is
1261*43a90889SApple OSS Distributions * XXX none).
1262*43a90889SApple OSS Distributions * XXX it is unclear whether P_SUGID should be st at this point;
1263*43a90889SApple OSS Distributions * XXX in theory, it is being deprecated.
1264*43a90889SApple OSS Distributions */
1265*43a90889SApple OSS Distributions
1266*43a90889SApple OSS Distributions /*
1267*43a90889SApple OSS Distributions * assume argument tells us to assume the identity of the process with the
1268*43a90889SApple OSS Distributions * id passed in the pid argument.
1269*43a90889SApple OSS Distributions */
1270*43a90889SApple OSS Distributions if (uap->assume != 0) {
1271*43a90889SApple OSS Distributions kauth_cred_t cred;
1272*43a90889SApple OSS Distributions
1273*43a90889SApple OSS Distributions if (uap->pid == 0) {
1274*43a90889SApple OSS Distributions return ESRCH;
1275*43a90889SApple OSS Distributions }
1276*43a90889SApple OSS Distributions
1277*43a90889SApple OSS Distributions cred = kauth_cred_proc_ref_for_pid(uap->pid);
1278*43a90889SApple OSS Distributions if (cred == NOCRED) {
1279*43a90889SApple OSS Distributions return ESRCH;
1280*43a90889SApple OSS Distributions }
1281*43a90889SApple OSS Distributions
1282*43a90889SApple OSS Distributions uid = kauth_cred_getuid(cred);
1283*43a90889SApple OSS Distributions gid = kauth_cred_getgid(cred);
1284*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
1285*43a90889SApple OSS Distributions } else {
1286*43a90889SApple OSS Distributions /*
1287*43a90889SApple OSS Distributions * Otherwise, we are reverting back to normal mode of operation
1288*43a90889SApple OSS Distributions * where delayed binding of the process credential sets the
1289*43a90889SApple OSS Distributions * credential in the thread_ro (tro_cred)
1290*43a90889SApple OSS Distributions */
1291*43a90889SApple OSS Distributions uid = KAUTH_UID_NONE;
1292*43a90889SApple OSS Distributions gid = KAUTH_GID_NONE;
1293*43a90889SApple OSS Distributions }
1294*43a90889SApple OSS Distributions
1295*43a90889SApple OSS Distributions return kern_settid(p, uid, gid);
1296*43a90889SApple OSS Distributions }
1297*43a90889SApple OSS Distributions
1298*43a90889SApple OSS Distributions
1299*43a90889SApple OSS Distributions /*
1300*43a90889SApple OSS Distributions * setgroups1
1301*43a90889SApple OSS Distributions *
1302*43a90889SApple OSS Distributions * Description: Internal implementation for both the setgroups and initgroups
1303*43a90889SApple OSS Distributions * system calls
1304*43a90889SApple OSS Distributions *
1305*43a90889SApple OSS Distributions * Parameters: gidsetsize Number of groups in set
1306*43a90889SApple OSS Distributions * gidset Pointer to group list
1307*43a90889SApple OSS Distributions * gmuid Base gid (initgroups only!)
1308*43a90889SApple OSS Distributions *
1309*43a90889SApple OSS Distributions * Returns: 0 Success
1310*43a90889SApple OSS Distributions * suser:EPERM Permision denied
1311*43a90889SApple OSS Distributions * EINVAL Invalid gidsetsize value
1312*43a90889SApple OSS Distributions * copyin:EFAULT Bad gidset or gidsetsize is
1313*43a90889SApple OSS Distributions * too large
1314*43a90889SApple OSS Distributions *
1315*43a90889SApple OSS Distributions * Notes: When called from a thread running under an assumed per-thread
1316*43a90889SApple OSS Distributions * identity, this function will operate against the per-thread
1317*43a90889SApple OSS Distributions * credential, rather than against the process credential. In
1318*43a90889SApple OSS Distributions * this specific case, the process credential is verified to
1319*43a90889SApple OSS Distributions * still be privileged at the time of the call, rather than the
1320*43a90889SApple OSS Distributions * per-thread credential for this operation to be permitted.
1321*43a90889SApple OSS Distributions *
1322*43a90889SApple OSS Distributions * This effectively means that setgroups/initigroups calls in
1323*43a90889SApple OSS Distributions * a thread running a per-thread credential should occur *after*
1324*43a90889SApple OSS Distributions * the settid call that created it, not before (unlike setuid,
1325*43a90889SApple OSS Distributions * which must be called after, since it will result in privilege
1326*43a90889SApple OSS Distributions * being dropped).
1327*43a90889SApple OSS Distributions *
1328*43a90889SApple OSS Distributions * When called normally (i.e. no per-thread assumed identity),
1329*43a90889SApple OSS Distributions * the per process credential is updated per POSIX.
1330*43a90889SApple OSS Distributions *
1331*43a90889SApple OSS Distributions * If the credential is changed as a result of this call, then we
1332*43a90889SApple OSS Distributions * flag the process as having set privilege since the last exec.
1333*43a90889SApple OSS Distributions */
1334*43a90889SApple OSS Distributions static int
setgroups1(proc_t p,u_int ngrp,user_addr_t gidset,uid_t gmuid,__unused int32_t * retval)1335*43a90889SApple OSS Distributions setgroups1(proc_t p, u_int ngrp, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval)
1336*43a90889SApple OSS Distributions {
1337*43a90889SApple OSS Distributions gid_t newgroups[NGROUPS] = { 0 };
1338*43a90889SApple OSS Distributions int error;
1339*43a90889SApple OSS Distributions
1340*43a90889SApple OSS Distributions if (ngrp > NGROUPS) {
1341*43a90889SApple OSS Distributions return EINVAL;
1342*43a90889SApple OSS Distributions }
1343*43a90889SApple OSS Distributions
1344*43a90889SApple OSS Distributions if (ngrp >= 1) {
1345*43a90889SApple OSS Distributions error = copyin(gidset,
1346*43a90889SApple OSS Distributions (caddr_t)newgroups, ngrp * sizeof(gid_t));
1347*43a90889SApple OSS Distributions if (error) {
1348*43a90889SApple OSS Distributions return error;
1349*43a90889SApple OSS Distributions }
1350*43a90889SApple OSS Distributions }
1351*43a90889SApple OSS Distributions return setgroups_internal(p, ngrp, newgroups, gmuid);
1352*43a90889SApple OSS Distributions }
1353*43a90889SApple OSS Distributions
1354*43a90889SApple OSS Distributions int
setgroups_internal(proc_t p,u_int ngrp,gid_t * newgroups,uid_t gmuid)1355*43a90889SApple OSS Distributions setgroups_internal(proc_t p, u_int ngrp, gid_t *newgroups, uid_t gmuid)
1356*43a90889SApple OSS Distributions {
1357*43a90889SApple OSS Distributions thread_ro_t tro = current_thread_ro();
1358*43a90889SApple OSS Distributions kauth_cred_t cred;
1359*43a90889SApple OSS Distributions int error;
1360*43a90889SApple OSS Distributions
1361*43a90889SApple OSS Distributions error = proc_suser(p);
1362*43a90889SApple OSS Distributions if (error) {
1363*43a90889SApple OSS Distributions return error;
1364*43a90889SApple OSS Distributions }
1365*43a90889SApple OSS Distributions
1366*43a90889SApple OSS Distributions if (ngrp < 1) {
1367*43a90889SApple OSS Distributions ngrp = 1;
1368*43a90889SApple OSS Distributions newgroups[0] = 0;
1369*43a90889SApple OSS Distributions }
1370*43a90889SApple OSS Distributions
1371*43a90889SApple OSS Distributions kauth_cred_derive_t fn = ^bool (kauth_cred_t parent __unused, kauth_cred_t model) {
1372*43a90889SApple OSS Distributions return kauth_cred_model_setgroups(model, newgroups, ngrp, gmuid);
1373*43a90889SApple OSS Distributions };
1374*43a90889SApple OSS Distributions
1375*43a90889SApple OSS Distributions if (tro->tro_realcred != tro->tro_cred) {
1376*43a90889SApple OSS Distributions /*
1377*43a90889SApple OSS Distributions * If this thread is under an assumed identity, set the
1378*43a90889SApple OSS Distributions * supplementary grouplist on the thread credential instead
1379*43a90889SApple OSS Distributions * of the process one. If we were the only reference holder,
1380*43a90889SApple OSS Distributions * the credential is updated in place, otherwise, our reference
1381*43a90889SApple OSS Distributions * is dropped and we get back a different cred with a reference
1382*43a90889SApple OSS Distributions * already held on it. Because this is per-thread, we don't
1383*43a90889SApple OSS Distributions * need the referencing/locking/retry required for per-process.
1384*43a90889SApple OSS Distributions */
1385*43a90889SApple OSS Distributions cred = kauth_cred_derive(tro->tro_cred, fn);
1386*43a90889SApple OSS Distributions kern_settid_assume_cred(tro, cred);
1387*43a90889SApple OSS Distributions kauth_cred_unref(&cred);
1388*43a90889SApple OSS Distributions } else {
1389*43a90889SApple OSS Distributions kauth_cred_proc_update(p, PROC_SETTOKEN_SETUGID, fn);
1390*43a90889SApple OSS Distributions AUDIT_ARG(groupset, &newgroups[0], ngrp);
1391*43a90889SApple OSS Distributions }
1392*43a90889SApple OSS Distributions
1393*43a90889SApple OSS Distributions return 0;
1394*43a90889SApple OSS Distributions }
1395*43a90889SApple OSS Distributions
1396*43a90889SApple OSS Distributions
1397*43a90889SApple OSS Distributions /*
1398*43a90889SApple OSS Distributions * initgroups
1399*43a90889SApple OSS Distributions *
1400*43a90889SApple OSS Distributions * Description: Initialize the default supplementary groups list and set the
1401*43a90889SApple OSS Distributions * gmuid for use by the external group resolver (if any)
1402*43a90889SApple OSS Distributions *
1403*43a90889SApple OSS Distributions * Parameters: uap->gidsetsize Number of groups in set
1404*43a90889SApple OSS Distributions * uap->gidset Pointer to group list
1405*43a90889SApple OSS Distributions * uap->gmuid Base gid
1406*43a90889SApple OSS Distributions *
1407*43a90889SApple OSS Distributions * Returns: 0 Success
1408*43a90889SApple OSS Distributions * setgroups1:EPERM Permision denied
1409*43a90889SApple OSS Distributions * setgroups1:EINVAL Invalid gidsetsize value
1410*43a90889SApple OSS Distributions * setgroups1:EFAULT Bad gidset or gidsetsize is
1411*43a90889SApple OSS Distributions *
1412*43a90889SApple OSS Distributions * Notes: This function opts *IN* to memberd participation
1413*43a90889SApple OSS Distributions *
1414*43a90889SApple OSS Distributions * The normal purpose of this function is for a privileged
1415*43a90889SApple OSS Distributions * process to indicate supplementary groups and identity for
1416*43a90889SApple OSS Distributions * participation in extended group membership resolution prior
1417*43a90889SApple OSS Distributions * to dropping privilege by assuming a specific user identity.
1418*43a90889SApple OSS Distributions *
1419*43a90889SApple OSS Distributions * It is the first half of the primary mechanism whereby user
1420*43a90889SApple OSS Distributions * identity is established to the system by programs such as
1421*43a90889SApple OSS Distributions * /usr/bin/login. The second half is the drop of uid privilege
1422*43a90889SApple OSS Distributions * for a specific uid corresponding to the user.
1423*43a90889SApple OSS Distributions *
1424*43a90889SApple OSS Distributions * See also: setgroups1()
1425*43a90889SApple OSS Distributions */
1426*43a90889SApple OSS Distributions int
initgroups(proc_t p,struct initgroups_args * uap,__unused int32_t * retval)1427*43a90889SApple OSS Distributions initgroups(proc_t p, struct initgroups_args *uap, __unused int32_t *retval)
1428*43a90889SApple OSS Distributions {
1429*43a90889SApple OSS Distributions return setgroups1(p, uap->gidsetsize, uap->gidset, uap->gmuid, retval);
1430*43a90889SApple OSS Distributions }
1431*43a90889SApple OSS Distributions
1432*43a90889SApple OSS Distributions
1433*43a90889SApple OSS Distributions /*
1434*43a90889SApple OSS Distributions * setgroups
1435*43a90889SApple OSS Distributions *
1436*43a90889SApple OSS Distributions * Description: Initialize the default supplementary groups list
1437*43a90889SApple OSS Distributions *
1438*43a90889SApple OSS Distributions * Parameters: gidsetsize Number of groups in set
1439*43a90889SApple OSS Distributions * gidset Pointer to group list
1440*43a90889SApple OSS Distributions *
1441*43a90889SApple OSS Distributions * Returns: 0 Success
1442*43a90889SApple OSS Distributions * setgroups1:EPERM Permision denied
1443*43a90889SApple OSS Distributions * setgroups1:EINVAL Invalid gidsetsize value
1444*43a90889SApple OSS Distributions * setgroups1:EFAULT Bad gidset or gidsetsize is
1445*43a90889SApple OSS Distributions *
1446*43a90889SApple OSS Distributions * Notes: This functions opts *OUT* of memberd participation.
1447*43a90889SApple OSS Distributions *
1448*43a90889SApple OSS Distributions * This function exists for compatibility with POSIX. Most user
1449*43a90889SApple OSS Distributions * programs should use initgroups() instead to ensure correct
1450*43a90889SApple OSS Distributions * participation in group membership resolution when utilizing
1451*43a90889SApple OSS Distributions * a directory service for authentication.
1452*43a90889SApple OSS Distributions *
1453*43a90889SApple OSS Distributions * It is identical to an initgroups() call with a gmuid argument
1454*43a90889SApple OSS Distributions * of KAUTH_UID_NONE.
1455*43a90889SApple OSS Distributions *
1456*43a90889SApple OSS Distributions * See also: setgroups1()
1457*43a90889SApple OSS Distributions */
1458*43a90889SApple OSS Distributions int
setgroups(proc_t p,struct setgroups_args * uap,__unused int32_t * retval)1459*43a90889SApple OSS Distributions setgroups(proc_t p, struct setgroups_args *uap, __unused int32_t *retval)
1460*43a90889SApple OSS Distributions {
1461*43a90889SApple OSS Distributions return setgroups1(p, uap->gidsetsize, uap->gidset, KAUTH_UID_NONE, retval);
1462*43a90889SApple OSS Distributions }
1463*43a90889SApple OSS Distributions
1464*43a90889SApple OSS Distributions
1465*43a90889SApple OSS Distributions /*
1466*43a90889SApple OSS Distributions * Set the per-thread/per-process supplementary groups list.
1467*43a90889SApple OSS Distributions *
1468*43a90889SApple OSS Distributions * XXX implement setsgroups
1469*43a90889SApple OSS Distributions *
1470*43a90889SApple OSS Distributions */
1471*43a90889SApple OSS Distributions
1472*43a90889SApple OSS Distributions int
setsgroups(__unused proc_t p,__unused struct setsgroups_args * uap,__unused int32_t * retval)1473*43a90889SApple OSS Distributions setsgroups(__unused proc_t p, __unused struct setsgroups_args *uap, __unused int32_t *retval)
1474*43a90889SApple OSS Distributions {
1475*43a90889SApple OSS Distributions return ENOTSUP;
1476*43a90889SApple OSS Distributions }
1477*43a90889SApple OSS Distributions
1478*43a90889SApple OSS Distributions /*
1479*43a90889SApple OSS Distributions * Set the per-thread/per-process whiteout groups list.
1480*43a90889SApple OSS Distributions *
1481*43a90889SApple OSS Distributions * XXX implement setwgroups
1482*43a90889SApple OSS Distributions *
1483*43a90889SApple OSS Distributions */
1484*43a90889SApple OSS Distributions
1485*43a90889SApple OSS Distributions int
setwgroups(__unused proc_t p,__unused struct setwgroups_args * uap,__unused int32_t * retval)1486*43a90889SApple OSS Distributions setwgroups(__unused proc_t p, __unused struct setwgroups_args *uap, __unused int32_t *retval)
1487*43a90889SApple OSS Distributions {
1488*43a90889SApple OSS Distributions return ENOTSUP;
1489*43a90889SApple OSS Distributions }
1490*43a90889SApple OSS Distributions
1491*43a90889SApple OSS Distributions
1492*43a90889SApple OSS Distributions /*
1493*43a90889SApple OSS Distributions * Check if gid is a member of the group set.
1494*43a90889SApple OSS Distributions *
1495*43a90889SApple OSS Distributions * XXX This interface is going away; use kauth_cred_ismember_gid() directly
1496*43a90889SApple OSS Distributions * XXX instead.
1497*43a90889SApple OSS Distributions */
1498*43a90889SApple OSS Distributions int
groupmember(gid_t gid,kauth_cred_t cred)1499*43a90889SApple OSS Distributions groupmember(gid_t gid, kauth_cred_t cred)
1500*43a90889SApple OSS Distributions {
1501*43a90889SApple OSS Distributions int is_member;
1502*43a90889SApple OSS Distributions
1503*43a90889SApple OSS Distributions if (kauth_cred_ismember_gid(cred, gid, &is_member) == 0 && is_member) {
1504*43a90889SApple OSS Distributions return 1;
1505*43a90889SApple OSS Distributions }
1506*43a90889SApple OSS Distributions return 0;
1507*43a90889SApple OSS Distributions }
1508*43a90889SApple OSS Distributions
1509*43a90889SApple OSS Distributions
1510*43a90889SApple OSS Distributions /*
1511*43a90889SApple OSS Distributions * Test whether the specified credentials imply "super-user"
1512*43a90889SApple OSS Distributions * privilege; if so, and we have accounting info, set the flag
1513*43a90889SApple OSS Distributions * indicating use of super-powers.
1514*43a90889SApple OSS Distributions * Returns 0 or error.
1515*43a90889SApple OSS Distributions *
1516*43a90889SApple OSS Distributions * XXX This interface is going away; use kauth_cred_issuser() directly
1517*43a90889SApple OSS Distributions * XXX instead.
1518*43a90889SApple OSS Distributions *
1519*43a90889SApple OSS Distributions * Note: This interface exists to implement the "has used privilege"
1520*43a90889SApple OSS Distributions * bit (ASU) in the p_acflags field of the process, which is
1521*43a90889SApple OSS Distributions * only externalized via private sysctl and in process accounting
1522*43a90889SApple OSS Distributions * records. The flag is technically not required in either case.
1523*43a90889SApple OSS Distributions */
1524*43a90889SApple OSS Distributions int
suser(kauth_cred_t cred,u_short * acflag)1525*43a90889SApple OSS Distributions suser(kauth_cred_t cred, u_short *acflag)
1526*43a90889SApple OSS Distributions {
1527*43a90889SApple OSS Distributions if (kauth_cred_getuid(cred) == 0) {
1528*43a90889SApple OSS Distributions if (acflag) {
1529*43a90889SApple OSS Distributions *acflag |= ASU;
1530*43a90889SApple OSS Distributions }
1531*43a90889SApple OSS Distributions return 0;
1532*43a90889SApple OSS Distributions }
1533*43a90889SApple OSS Distributions return EPERM;
1534*43a90889SApple OSS Distributions }
1535*43a90889SApple OSS Distributions
1536*43a90889SApple OSS Distributions
1537*43a90889SApple OSS Distributions /*
1538*43a90889SApple OSS Distributions * getlogin
1539*43a90889SApple OSS Distributions *
1540*43a90889SApple OSS Distributions * Description: Get login name, if available.
1541*43a90889SApple OSS Distributions *
1542*43a90889SApple OSS Distributions * Parameters: uap->namebuf User buffer for return
1543*43a90889SApple OSS Distributions * uap->namelen User buffer length
1544*43a90889SApple OSS Distributions *
1545*43a90889SApple OSS Distributions * Returns: 0 Success
1546*43a90889SApple OSS Distributions * copyout:EFAULT
1547*43a90889SApple OSS Distributions *
1548*43a90889SApple OSS Distributions * Notes: Intended to obtain a string containing the user name of the
1549*43a90889SApple OSS Distributions * user associated with the controlling terminal for the calling
1550*43a90889SApple OSS Distributions * process.
1551*43a90889SApple OSS Distributions *
1552*43a90889SApple OSS Distributions * Not very useful on modern systems, due to inherent length
1553*43a90889SApple OSS Distributions * limitations for the static array in the session structure
1554*43a90889SApple OSS Distributions * which is used to store the login name.
1555*43a90889SApple OSS Distributions *
1556*43a90889SApple OSS Distributions * Permitted to return NULL
1557*43a90889SApple OSS Distributions *
1558*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
1559*43a90889SApple OSS Distributions */
1560*43a90889SApple OSS Distributions int
getlogin(proc_t p,struct getlogin_args * uap,__unused int32_t * retval)1561*43a90889SApple OSS Distributions getlogin(proc_t p, struct getlogin_args *uap, __unused int32_t *retval)
1562*43a90889SApple OSS Distributions {
1563*43a90889SApple OSS Distributions char buffer[MAXLOGNAME];
1564*43a90889SApple OSS Distributions struct session *sessp;
1565*43a90889SApple OSS Distributions struct pgrp *pg;
1566*43a90889SApple OSS Distributions
1567*43a90889SApple OSS Distributions if (uap->namelen > MAXLOGNAME) {
1568*43a90889SApple OSS Distributions uap->namelen = MAXLOGNAME;
1569*43a90889SApple OSS Distributions }
1570*43a90889SApple OSS Distributions
1571*43a90889SApple OSS Distributions if ((pg = proc_pgrp(p, &sessp)) != PGRP_NULL) {
1572*43a90889SApple OSS Distributions session_lock(sessp);
1573*43a90889SApple OSS Distributions bcopy(sessp->s_login, buffer, uap->namelen);
1574*43a90889SApple OSS Distributions session_unlock(sessp);
1575*43a90889SApple OSS Distributions pgrp_rele(pg);
1576*43a90889SApple OSS Distributions } else {
1577*43a90889SApple OSS Distributions bzero(buffer, uap->namelen);
1578*43a90889SApple OSS Distributions }
1579*43a90889SApple OSS Distributions
1580*43a90889SApple OSS Distributions return copyout((caddr_t)buffer, uap->namebuf, uap->namelen);
1581*43a90889SApple OSS Distributions }
1582*43a90889SApple OSS Distributions
1583*43a90889SApple OSS Distributions void
setlogin_internal(proc_t p,const char login[static MAXLOGNAME])1584*43a90889SApple OSS Distributions setlogin_internal(proc_t p, const char login[static MAXLOGNAME])
1585*43a90889SApple OSS Distributions {
1586*43a90889SApple OSS Distributions struct session *sessp;
1587*43a90889SApple OSS Distributions struct pgrp *pg;
1588*43a90889SApple OSS Distributions
1589*43a90889SApple OSS Distributions if ((pg = proc_pgrp(p, &sessp)) != PGRP_NULL) {
1590*43a90889SApple OSS Distributions session_lock(sessp);
1591*43a90889SApple OSS Distributions bcopy(login, sessp->s_login, MAXLOGNAME);
1592*43a90889SApple OSS Distributions session_unlock(sessp);
1593*43a90889SApple OSS Distributions pgrp_rele(pg);
1594*43a90889SApple OSS Distributions }
1595*43a90889SApple OSS Distributions }
1596*43a90889SApple OSS Distributions
1597*43a90889SApple OSS Distributions /*
1598*43a90889SApple OSS Distributions * setlogin
1599*43a90889SApple OSS Distributions *
1600*43a90889SApple OSS Distributions * Description: Set login name.
1601*43a90889SApple OSS Distributions *
1602*43a90889SApple OSS Distributions * Parameters: uap->namebuf User buffer containing name
1603*43a90889SApple OSS Distributions *
1604*43a90889SApple OSS Distributions * Returns: 0 Success
1605*43a90889SApple OSS Distributions * suser:EPERM Permission denied
1606*43a90889SApple OSS Distributions * copyinstr:EFAULT User buffer invalid
1607*43a90889SApple OSS Distributions * copyinstr:EINVAL Supplied name was too long
1608*43a90889SApple OSS Distributions *
1609*43a90889SApple OSS Distributions * Notes: This is a utility system call to support getlogin().
1610*43a90889SApple OSS Distributions *
1611*43a90889SApple OSS Distributions * XXX: Belongs in kern_proc.c
1612*43a90889SApple OSS Distributions */
1613*43a90889SApple OSS Distributions int
setlogin(proc_t p,struct setlogin_args * uap,__unused int32_t * retval)1614*43a90889SApple OSS Distributions setlogin(proc_t p, struct setlogin_args *uap, __unused int32_t *retval)
1615*43a90889SApple OSS Distributions {
1616*43a90889SApple OSS Distributions int error;
1617*43a90889SApple OSS Distributions size_t dummy = 0;
1618*43a90889SApple OSS Distributions char buffer[MAXLOGNAME + 1];
1619*43a90889SApple OSS Distributions
1620*43a90889SApple OSS Distributions if ((error = proc_suser(p))) {
1621*43a90889SApple OSS Distributions return error;
1622*43a90889SApple OSS Distributions }
1623*43a90889SApple OSS Distributions
1624*43a90889SApple OSS Distributions bzero(&buffer[0], MAXLOGNAME + 1);
1625*43a90889SApple OSS Distributions
1626*43a90889SApple OSS Distributions
1627*43a90889SApple OSS Distributions error = copyinstr(uap->namebuf,
1628*43a90889SApple OSS Distributions (caddr_t) &buffer[0],
1629*43a90889SApple OSS Distributions MAXLOGNAME - 1, (size_t *)&dummy);
1630*43a90889SApple OSS Distributions
1631*43a90889SApple OSS Distributions setlogin_internal(p, buffer);
1632*43a90889SApple OSS Distributions
1633*43a90889SApple OSS Distributions if (!error) {
1634*43a90889SApple OSS Distributions AUDIT_ARG(text, buffer);
1635*43a90889SApple OSS Distributions } else if (error == ENAMETOOLONG) {
1636*43a90889SApple OSS Distributions error = EINVAL;
1637*43a90889SApple OSS Distributions }
1638*43a90889SApple OSS Distributions return error;
1639*43a90889SApple OSS Distributions }
1640*43a90889SApple OSS Distributions
1641*43a90889SApple OSS Distributions
1642*43a90889SApple OSS Distributions static void
proc_calc_audit_token(proc_t p,kauth_cred_t my_cred,audit_token_t * audit_token)1643*43a90889SApple OSS Distributions proc_calc_audit_token(proc_t p, kauth_cred_t my_cred, audit_token_t *audit_token)
1644*43a90889SApple OSS Distributions {
1645*43a90889SApple OSS Distributions posix_cred_t my_pcred = posix_cred_get(my_cred);
1646*43a90889SApple OSS Distributions
1647*43a90889SApple OSS Distributions /*
1648*43a90889SApple OSS Distributions * The current layout of the Mach audit token explicitly
1649*43a90889SApple OSS Distributions * adds these fields. But nobody should rely on such
1650*43a90889SApple OSS Distributions * a literal representation. Instead, the BSM library
1651*43a90889SApple OSS Distributions * provides a function to convert an audit token into
1652*43a90889SApple OSS Distributions * a BSM subject. Use of that mechanism will isolate
1653*43a90889SApple OSS Distributions * the user of the trailer from future representation
1654*43a90889SApple OSS Distributions * changes.
1655*43a90889SApple OSS Distributions */
1656*43a90889SApple OSS Distributions audit_token->val[0] = my_cred->cr_audit.as_aia_p->ai_auid;
1657*43a90889SApple OSS Distributions audit_token->val[1] = my_pcred->cr_uid;
1658*43a90889SApple OSS Distributions audit_token->val[2] = my_pcred->cr_gid;
1659*43a90889SApple OSS Distributions audit_token->val[3] = my_pcred->cr_ruid;
1660*43a90889SApple OSS Distributions audit_token->val[4] = my_pcred->cr_rgid;
1661*43a90889SApple OSS Distributions audit_token->val[5] = proc_getpid(p);
1662*43a90889SApple OSS Distributions audit_token->val[6] = my_cred->cr_audit.as_aia_p->ai_asid;
1663*43a90889SApple OSS Distributions audit_token->val[7] = proc_pidversion(p);
1664*43a90889SApple OSS Distributions }
1665*43a90889SApple OSS Distributions
1666*43a90889SApple OSS Distributions /* Set the secrity token of the task with current euid and eguid */
1667*43a90889SApple OSS Distributions int
set_security_token(proc_t p,struct ucred * my_cred)1668*43a90889SApple OSS Distributions set_security_token(proc_t p, struct ucred *my_cred)
1669*43a90889SApple OSS Distributions {
1670*43a90889SApple OSS Distributions security_token_t sec_token;
1671*43a90889SApple OSS Distributions audit_token_t audit_token;
1672*43a90889SApple OSS Distributions host_priv_t host_priv;
1673*43a90889SApple OSS Distributions task_t task = proc_task(p);
1674*43a90889SApple OSS Distributions
1675*43a90889SApple OSS Distributions proc_calc_audit_token(p, my_cred, &audit_token);
1676*43a90889SApple OSS Distributions
1677*43a90889SApple OSS Distributions sec_token.val[0] = kauth_cred_getuid(my_cred);
1678*43a90889SApple OSS Distributions sec_token.val[1] = kauth_cred_getgid(my_cred);
1679*43a90889SApple OSS Distributions
1680*43a90889SApple OSS Distributions host_priv = (sec_token.val[0]) ? HOST_PRIV_NULL : host_priv_self();
1681*43a90889SApple OSS Distributions #if CONFIG_MACF
1682*43a90889SApple OSS Distributions if (host_priv != HOST_PRIV_NULL && mac_system_check_host_priv(my_cred)) {
1683*43a90889SApple OSS Distributions host_priv = HOST_PRIV_NULL;
1684*43a90889SApple OSS Distributions }
1685*43a90889SApple OSS Distributions #endif
1686*43a90889SApple OSS Distributions
1687*43a90889SApple OSS Distributions #if DEVELOPMENT || DEBUG
1688*43a90889SApple OSS Distributions /*
1689*43a90889SApple OSS Distributions * Update the pid an proc name for importance base if any
1690*43a90889SApple OSS Distributions */
1691*43a90889SApple OSS Distributions task_importance_update_owner_info(task);
1692*43a90889SApple OSS Distributions #endif
1693*43a90889SApple OSS Distributions
1694*43a90889SApple OSS Distributions return task_set_security_tokens(task, sec_token, audit_token,
1695*43a90889SApple OSS Distributions host_priv) != KERN_SUCCESS;
1696*43a90889SApple OSS Distributions }
1697*43a90889SApple OSS Distributions
1698*43a90889SApple OSS Distributions void
proc_parent_audit_token(proc_t p,audit_token_t * token_out)1699*43a90889SApple OSS Distributions proc_parent_audit_token(proc_t p, audit_token_t *token_out)
1700*43a90889SApple OSS Distributions {
1701*43a90889SApple OSS Distributions proc_t parent;
1702*43a90889SApple OSS Distributions kauth_cred_t my_cred;
1703*43a90889SApple OSS Distributions
1704*43a90889SApple OSS Distributions proc_list_lock();
1705*43a90889SApple OSS Distributions
1706*43a90889SApple OSS Distributions parent = p->p_pptr;
1707*43a90889SApple OSS Distributions my_cred = kauth_cred_proc_ref(parent);
1708*43a90889SApple OSS Distributions proc_calc_audit_token(parent, my_cred, token_out);
1709*43a90889SApple OSS Distributions kauth_cred_unref(&my_cred);
1710*43a90889SApple OSS Distributions
1711*43a90889SApple OSS Distributions proc_list_unlock();
1712*43a90889SApple OSS Distributions }
1713*43a90889SApple OSS Distributions
1714*43a90889SApple OSS Distributions
1715*43a90889SApple OSS Distributions int get_audit_token_pid(audit_token_t *audit_token);
1716*43a90889SApple OSS Distributions
1717*43a90889SApple OSS Distributions int
get_audit_token_pid(audit_token_t * audit_token)1718*43a90889SApple OSS Distributions get_audit_token_pid(audit_token_t *audit_token)
1719*43a90889SApple OSS Distributions {
1720*43a90889SApple OSS Distributions /* keep in-sync with set_security_token (above) */
1721*43a90889SApple OSS Distributions if (audit_token) {
1722*43a90889SApple OSS Distributions return (int)audit_token->val[5];
1723*43a90889SApple OSS Distributions }
1724*43a90889SApple OSS Distributions return -1;
1725*43a90889SApple OSS Distributions }
1726*43a90889SApple OSS Distributions
1727*43a90889SApple OSS Distributions
1728*43a90889SApple OSS Distributions /*
1729*43a90889SApple OSS Distributions * Fill in a struct xucred based on a kauth_cred_t.
1730*43a90889SApple OSS Distributions */
1731*43a90889SApple OSS Distributions void
cru2x(kauth_cred_t cr,struct xucred * xcr)1732*43a90889SApple OSS Distributions cru2x(kauth_cred_t cr, struct xucred *xcr)
1733*43a90889SApple OSS Distributions {
1734*43a90889SApple OSS Distributions posix_cred_t pcr = posix_cred_get(cr);
1735*43a90889SApple OSS Distributions
1736*43a90889SApple OSS Distributions bzero(xcr, sizeof(*xcr));
1737*43a90889SApple OSS Distributions xcr->cr_version = XUCRED_VERSION;
1738*43a90889SApple OSS Distributions xcr->cr_uid = kauth_cred_getuid(cr);
1739*43a90889SApple OSS Distributions xcr->cr_ngroups = pcr->cr_ngroups;
1740*43a90889SApple OSS Distributions bcopy(pcr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups));
1741*43a90889SApple OSS Distributions }
1742*43a90889SApple OSS Distributions
1743*43a90889SApple OSS Distributions /*
1744*43a90889SApple OSS Distributions * Copy kauth_cred into a virtual address by assignment.
1745*43a90889SApple OSS Distributions * Needed because elements of kauth_cred are PACed
1746*43a90889SApple OSS Distributions * so memcpy doesn't work.
1747*43a90889SApple OSS Distributions */
1748*43a90889SApple OSS Distributions void
kauth_cred_copy(const uintptr_t kv,const uintptr_t new_data)1749*43a90889SApple OSS Distributions kauth_cred_copy(const uintptr_t kv, const uintptr_t new_data)
1750*43a90889SApple OSS Distributions {
1751*43a90889SApple OSS Distributions *(kauth_cred_t)kv = *(kauth_cred_t)new_data;
1752*43a90889SApple OSS Distributions }
1753