xref: /xnu-8796.101.5/bsd/sys/persona.h (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1*aca3beaaSApple OSS Distributions /*
2*aca3beaaSApple OSS Distributions  * Copyright (c) 2015 Apple Inc. All rights reserved.
3*aca3beaaSApple OSS Distributions  *
4*aca3beaaSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*aca3beaaSApple OSS Distributions  *
6*aca3beaaSApple OSS Distributions  * This file contains Original Code and/or Modifications of Original Code
7*aca3beaaSApple OSS Distributions  * as defined in and that are subject to the Apple Public Source License
8*aca3beaaSApple OSS Distributions  * Version 2.0 (the 'License'). You may not use this file except in
9*aca3beaaSApple OSS Distributions  * compliance with the License. The rights granted to you under the License
10*aca3beaaSApple OSS Distributions  * may not be used to create, or enable the creation or redistribution of,
11*aca3beaaSApple OSS Distributions  * unlawful or unlicensed copies of an Apple operating system, or to
12*aca3beaaSApple OSS Distributions  * circumvent, violate, or enable the circumvention or violation of, any
13*aca3beaaSApple OSS Distributions  * terms of an Apple operating system software license agreement.
14*aca3beaaSApple OSS Distributions  *
15*aca3beaaSApple OSS Distributions  * Please obtain a copy of the License at
16*aca3beaaSApple OSS Distributions  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*aca3beaaSApple OSS Distributions  *
18*aca3beaaSApple OSS Distributions  * The Original Code and all software distributed under the License are
19*aca3beaaSApple OSS Distributions  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*aca3beaaSApple OSS Distributions  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*aca3beaaSApple OSS Distributions  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*aca3beaaSApple OSS Distributions  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*aca3beaaSApple OSS Distributions  * Please see the License for the specific language governing rights and
24*aca3beaaSApple OSS Distributions  * limitations under the License.
25*aca3beaaSApple OSS Distributions  *
26*aca3beaaSApple OSS Distributions  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*aca3beaaSApple OSS Distributions  */
28*aca3beaaSApple OSS Distributions #ifndef _SYS_PERSONA_H_
29*aca3beaaSApple OSS Distributions #define _SYS_PERSONA_H_
30*aca3beaaSApple OSS Distributions 
31*aca3beaaSApple OSS Distributions #ifdef PRIVATE
32*aca3beaaSApple OSS Distributions #include <sys/param.h>
33*aca3beaaSApple OSS Distributions 
34*aca3beaaSApple OSS Distributions #ifdef KERNEL
35*aca3beaaSApple OSS Distributions __enum_decl(persona_type_t, int, {
36*aca3beaaSApple OSS Distributions #else /* !KERNEL */
37*aca3beaaSApple OSS Distributions enum {
38*aca3beaaSApple OSS Distributions #endif /* KERNEL */
39*aca3beaaSApple OSS Distributions 	PERSONA_INVALID      = 0,
40*aca3beaaSApple OSS Distributions 	PERSONA_GUEST        = 1,
41*aca3beaaSApple OSS Distributions 	PERSONA_MANAGED      = 2,
42*aca3beaaSApple OSS Distributions 	PERSONA_PRIV         = 3,
43*aca3beaaSApple OSS Distributions 	PERSONA_SYSTEM       = 4,
44*aca3beaaSApple OSS Distributions 	PERSONA_DEFAULT      = 5,
45*aca3beaaSApple OSS Distributions 	PERSONA_SYSTEM_PROXY = 6,
46*aca3beaaSApple OSS Distributions 	PERSONA_SYS_EXT      = 7,
47*aca3beaaSApple OSS Distributions 	PERSONA_ENTERPRISE   = 8,
48*aca3beaaSApple OSS Distributions 
49*aca3beaaSApple OSS Distributions 	PERSONA_TYPE_MAX     = PERSONA_ENTERPRISE,
50*aca3beaaSApple OSS Distributions #ifdef KERNEL
51*aca3beaaSApple OSS Distributions });
52*aca3beaaSApple OSS Distributions #else /* !KERNEL */
53*aca3beaaSApple OSS Distributions };
54*aca3beaaSApple OSS Distributions #endif /* KERNEL */
55*aca3beaaSApple OSS Distributions 
56*aca3beaaSApple OSS Distributions #define PERSONA_ID_NONE ((uid_t)-1)
57*aca3beaaSApple OSS Distributions 
58*aca3beaaSApple OSS Distributions struct kpersona_info {
59*aca3beaaSApple OSS Distributions 	/* v1 fields */
60*aca3beaaSApple OSS Distributions 	uint32_t persona_info_version;
61*aca3beaaSApple OSS Distributions 
62*aca3beaaSApple OSS Distributions 	uid_t    persona_id;
63*aca3beaaSApple OSS Distributions 	int      persona_type;
64*aca3beaaSApple OSS Distributions 	gid_t    persona_gid; /* unused */
65*aca3beaaSApple OSS Distributions 	uint32_t persona_ngroups; /* unused */
66*aca3beaaSApple OSS Distributions 	gid_t    persona_groups[NGROUPS]; /* unused */
67*aca3beaaSApple OSS Distributions 	uid_t    persona_gmuid; /* unused */
68*aca3beaaSApple OSS Distributions 	char     persona_name[MAXLOGNAME + 1];
69*aca3beaaSApple OSS Distributions 
70*aca3beaaSApple OSS Distributions 	/* v2 fields */
71*aca3beaaSApple OSS Distributions 	uid_t    persona_uid;
72*aca3beaaSApple OSS Distributions } __attribute__((packed));
73*aca3beaaSApple OSS Distributions 
74*aca3beaaSApple OSS Distributions #define PERSONA_INFO_V1       1
75*aca3beaaSApple OSS Distributions #define PERSONA_INFO_V2       2
76*aca3beaaSApple OSS Distributions 
77*aca3beaaSApple OSS Distributions // Userspace and the kernel must see the same struct layout. Assert that in
78*aca3beaaSApple OSS Distributions // either case sizeof() is equal to the same pre-determined value.
79*aca3beaaSApple OSS Distributions _Static_assert(sizeof(struct kpersona_info) == 348, "sizeof(kpersona_info) == 348");
80*aca3beaaSApple OSS Distributions 
81*aca3beaaSApple OSS Distributions #define PERSONA_OP_ALLOC    1
82*aca3beaaSApple OSS Distributions #define PERSONA_OP_PALLOC   2
83*aca3beaaSApple OSS Distributions #define PERSONA_OP_DEALLOC  3
84*aca3beaaSApple OSS Distributions #define PERSONA_OP_GET      4
85*aca3beaaSApple OSS Distributions #define PERSONA_OP_INFO     5
86*aca3beaaSApple OSS Distributions #define PERSONA_OP_PIDINFO  6
87*aca3beaaSApple OSS Distributions #define PERSONA_OP_FIND     7
88*aca3beaaSApple OSS Distributions #define PERSONA_OP_GETPATH  8
89*aca3beaaSApple OSS Distributions #define PERSONA_OP_FIND_BY_TYPE  9
90*aca3beaaSApple OSS Distributions 
91*aca3beaaSApple OSS Distributions #define PERSONA_MGMT_ENTITLEMENT "com.apple.private.persona-mgmt"
92*aca3beaaSApple OSS Distributions 
93*aca3beaaSApple OSS Distributions #ifndef KERNEL
94*aca3beaaSApple OSS Distributions /*
95*aca3beaaSApple OSS Distributions  * user space persona interface
96*aca3beaaSApple OSS Distributions  */
97*aca3beaaSApple OSS Distributions 
98*aca3beaaSApple OSS Distributions /*
99*aca3beaaSApple OSS Distributions  * kpersona_alloc: Allocate a new in-kernel persona
100*aca3beaaSApple OSS Distributions  *
101*aca3beaaSApple OSS Distributions  * Parameters:
102*aca3beaaSApple OSS Distributions  *       info: Pointer to persona info structure describing the
103*aca3beaaSApple OSS Distributions  *             attributes of the persona to create / allocate.
104*aca3beaaSApple OSS Distributions  *
105*aca3beaaSApple OSS Distributions  *         id: output: set to the ID of the created persona
106*aca3beaaSApple OSS Distributions  *
107*aca3beaaSApple OSS Distributions  * Note:
108*aca3beaaSApple OSS Distributions  *      The 'persona_id' field of the 'info' parameter is ignored.
109*aca3beaaSApple OSS Distributions  *
110*aca3beaaSApple OSS Distributions  * Return:
111*aca3beaaSApple OSS Distributions  *        != 0: ERROR
112*aca3beaaSApple OSS Distributions  *        == 0: Success
113*aca3beaaSApple OSS Distributions  */
114*aca3beaaSApple OSS Distributions int kpersona_alloc(struct kpersona_info *info, uid_t *id);
115*aca3beaaSApple OSS Distributions 
116*aca3beaaSApple OSS Distributions /*
117*aca3beaaSApple OSS Distributions  * kpersona_palloc: Allocate a new in-kernel persona with a directory
118*aca3beaaSApple OSS Distributions  *                 pathname
119*aca3beaaSApple OSS Distributions  *
120*aca3beaaSApple OSS Distributions  * Parameters:
121*aca3beaaSApple OSS Distributions  *       info: Pointer to persona info structure describing the
122*aca3beaaSApple OSS Distributions  *             attributes of the persona to create / allocate.
123*aca3beaaSApple OSS Distributions  *
124*aca3beaaSApple OSS Distributions  *       path: Pointer to directory name that stores persona specific
125*aca3beaaSApple OSS Distributions  *             data. Assumes path buffer length = MAXPATHLEN and is a
126*aca3beaaSApple OSS Distributions  *             null-terminated string.
127*aca3beaaSApple OSS Distributions  *
128*aca3beaaSApple OSS Distributions  *         id: output: set to the ID of the created persona
129*aca3beaaSApple OSS Distributions  *
130*aca3beaaSApple OSS Distributions  * Note:
131*aca3beaaSApple OSS Distributions  *      The 'persona_id' field of the 'info' parameter is ignored.
132*aca3beaaSApple OSS Distributions  *
133*aca3beaaSApple OSS Distributions  * Return:
134*aca3beaaSApple OSS Distributions  *        != 0: ERROR
135*aca3beaaSApple OSS Distributions  *        == 0: Success
136*aca3beaaSApple OSS Distributions  */
137*aca3beaaSApple OSS Distributions int kpersona_palloc(struct kpersona_info *info, uid_t *id, char path[MAXPATHLEN]);
138*aca3beaaSApple OSS Distributions 
139*aca3beaaSApple OSS Distributions /*
140*aca3beaaSApple OSS Distributions  * kpersona_dealloc: delete / destroy an in-kernel persona
141*aca3beaaSApple OSS Distributions  *
142*aca3beaaSApple OSS Distributions  * Parameters:
143*aca3beaaSApple OSS Distributions  *         id: the ID of the persona to destroy
144*aca3beaaSApple OSS Distributions  *
145*aca3beaaSApple OSS Distributions  * Return:
146*aca3beaaSApple OSS Distributions  *        < 0: ERROR
147*aca3beaaSApple OSS Distributions  *          0: Success
148*aca3beaaSApple OSS Distributions  */
149*aca3beaaSApple OSS Distributions int kpersona_dealloc(uid_t id);
150*aca3beaaSApple OSS Distributions 
151*aca3beaaSApple OSS Distributions /*
152*aca3beaaSApple OSS Distributions  * kpersona_get: retrieve the persona with which the current thread is running
153*aca3beaaSApple OSS Distributions  *
154*aca3beaaSApple OSS Distributions  * To find the proc's persona id use kpersona_pidinfo
155*aca3beaaSApple OSS Distributions  *
156*aca3beaaSApple OSS Distributions  * Parameters:
157*aca3beaaSApple OSS Distributions  *         id: output: will be filled with the persona id from the voucher adopted
158*aca3beaaSApple OSS Distributions  *             on the current thread. If that voucher contains no persona information
159*aca3beaaSApple OSS Distributions  *             or there is no such voucher, then it defaults to the proc's persona id.
160*aca3beaaSApple OSS Distributions  *
161*aca3beaaSApple OSS Distributions  * Return:
162*aca3beaaSApple OSS Distributions  *        < 0: Thread is not running under any persona
163*aca3beaaSApple OSS Distributions  *          0: Success (uuid is filled with running persona UUID)
164*aca3beaaSApple OSS Distributions  */
165*aca3beaaSApple OSS Distributions int kpersona_get(uid_t *id);
166*aca3beaaSApple OSS Distributions 
167*aca3beaaSApple OSS Distributions /*
168*aca3beaaSApple OSS Distributions  * kpersona_get_path: retrieve the given persona's path
169*aca3beaaSApple OSS Distributions  *
170*aca3beaaSApple OSS Distributions  * Parameters:
171*aca3beaaSApple OSS Distributions  *         id: ID of the persona
172*aca3beaaSApple OSS Distributions  *
173*aca3beaaSApple OSS Distributions  *         path: output: filled in with path on success.
174*aca3beaaSApple OSS Distributions  *               Assumes path buffer length = MAXPATHLEN
175*aca3beaaSApple OSS Distributions  *
176*aca3beaaSApple OSS Distributions  * Return:
177*aca3beaaSApple OSS Distributions  *        < 0: Error
178*aca3beaaSApple OSS Distributions  *          0: Success
179*aca3beaaSApple OSS Distributions  */
180*aca3beaaSApple OSS Distributions int kpersona_getpath(uid_t id, char path[MAXPATHLEN]);
181*aca3beaaSApple OSS Distributions 
182*aca3beaaSApple OSS Distributions /*
183*aca3beaaSApple OSS Distributions  * kpersona_info: gather info about the given persona
184*aca3beaaSApple OSS Distributions  *
185*aca3beaaSApple OSS Distributions  * Parameters:
186*aca3beaaSApple OSS Distributions  *         id: ID of the persona to investigate
187*aca3beaaSApple OSS Distributions  *             If set to 0, it uses persona id from the voucher adopted on the current
188*aca3beaaSApple OSS Distributions  *             thread. If that voucher contains no persona information or there is no
189*aca3beaaSApple OSS Distributions  *             such voucher, then it defaults to the proc's persona id.
190*aca3beaaSApple OSS Distributions  *
191*aca3beaaSApple OSS Distributions  *       info: output: filled in with persona attributes on success.
192*aca3beaaSApple OSS Distributions  *
193*aca3beaaSApple OSS Distributions  * Return:
194*aca3beaaSApple OSS Distributions  *        < 0: ERROR
195*aca3beaaSApple OSS Distributions  *          0: Success
196*aca3beaaSApple OSS Distributions  */
197*aca3beaaSApple OSS Distributions int kpersona_info(uid_t id, struct kpersona_info *info);
198*aca3beaaSApple OSS Distributions 
199*aca3beaaSApple OSS Distributions /*
200*aca3beaaSApple OSS Distributions  * kpersona_pidinfo: gather persona info about the given PID
201*aca3beaaSApple OSS Distributions  *
202*aca3beaaSApple OSS Distributions  * Parameters:
203*aca3beaaSApple OSS Distributions  *        pid: PID of the process whose persona info we're to return
204*aca3beaaSApple OSS Distributions  *
205*aca3beaaSApple OSS Distributions  *       info: output: filled in with persona attributes on success.
206*aca3beaaSApple OSS Distributions  *
207*aca3beaaSApple OSS Distributions  * Return:
208*aca3beaaSApple OSS Distributions  *        < 0: ERROR
209*aca3beaaSApple OSS Distributions  *          0: Success
210*aca3beaaSApple OSS Distributions  */
211*aca3beaaSApple OSS Distributions int kpersona_pidinfo(pid_t pid, struct kpersona_info *info);
212*aca3beaaSApple OSS Distributions 
213*aca3beaaSApple OSS Distributions /*
214*aca3beaaSApple OSS Distributions  * kpersona_find: lookup the kernel's UUID of a persona
215*aca3beaaSApple OSS Distributions  *
216*aca3beaaSApple OSS Distributions  * Parameters:
217*aca3beaaSApple OSS Distributions  *       name: Local login name of the persona.
218*aca3beaaSApple OSS Distributions  *             Set this to NULL to find personas by 'uid'.
219*aca3beaaSApple OSS Distributions  *
220*aca3beaaSApple OSS Distributions  *        uid: UID of the persona.
221*aca3beaaSApple OSS Distributions  *             Set this to -1 to find personas by 'name'
222*aca3beaaSApple OSS Distributions  *
223*aca3beaaSApple OSS Distributions  *         id: output: the ID(s) matching the input parameters
224*aca3beaaSApple OSS Distributions  *             This can be NULL
225*aca3beaaSApple OSS Distributions  *
226*aca3beaaSApple OSS Distributions  *      idlen: input - size of 'id' buffer (in number of IDs)
227*aca3beaaSApple OSS Distributions  *             output - the total required size of the 'id' buffer
228*aca3beaaSApple OSS Distributions  *                      (in number of IDs) - may be larger than input size
229*aca3beaaSApple OSS Distributions  * Note:
230*aca3beaaSApple OSS Distributions  *      At least one of 'name' or 'uid' must be set.
231*aca3beaaSApple OSS Distributions  *
232*aca3beaaSApple OSS Distributions  * Return:
233*aca3beaaSApple OSS Distributions  *         < 0: ERROR
234*aca3beaaSApple OSS Distributions  *        >= 0: Output value of idlen - may be larger than input size
235*aca3beaaSApple OSS Distributions  */
236*aca3beaaSApple OSS Distributions int kpersona_find(const char *name, uid_t uid, uid_t *id, size_t *idlen);
237*aca3beaaSApple OSS Distributions 
238*aca3beaaSApple OSS Distributions /*
239*aca3beaaSApple OSS Distributions  * kpersona_find_by_type: lookup the persona ids by type
240*aca3beaaSApple OSS Distributions  *
241*aca3beaaSApple OSS Distributions  * Parameters:
242*aca3beaaSApple OSS Distributions  *  persona_type: Type of persona id (see enum)
243*aca3beaaSApple OSS Distributions  *
244*aca3beaaSApple OSS Distributions  *           id: output: the ID(s) matching the input parameters
245*aca3beaaSApple OSS Distributions  *               This can be NULL
246*aca3beaaSApple OSS Distributions  *
247*aca3beaaSApple OSS Distributions  *        idlen: input - size of 'id' buffer (in number of IDs)
248*aca3beaaSApple OSS Distributions  *               output - the total required size of the 'id' buffer
249*aca3beaaSApple OSS Distributions  *                      (in number of IDs) - may be larger than input size
250*aca3beaaSApple OSS Distributions  * Return:
251*aca3beaaSApple OSS Distributions  *         < 0: ERROR
252*aca3beaaSApple OSS Distributions  *        >= 0: Output value of idlen - may be larger than input size
253*aca3beaaSApple OSS Distributions  */
254*aca3beaaSApple OSS Distributions int kpersona_find_by_type(int persona_type, uid_t *id, size_t *idlen);
255*aca3beaaSApple OSS Distributions #endif /* !KERNEL */
256*aca3beaaSApple OSS Distributions 
257*aca3beaaSApple OSS Distributions #ifdef KERNEL_PRIVATE
258*aca3beaaSApple OSS Distributions /* XNU + kext private interface */
259*aca3beaaSApple OSS Distributions #include <sys/cdefs.h>
260*aca3beaaSApple OSS Distributions #include <sys/kauth.h>
261*aca3beaaSApple OSS Distributions #include <libkern/libkern.h>
262*aca3beaaSApple OSS Distributions #include <os/refcnt.h>
263*aca3beaaSApple OSS Distributions 
264*aca3beaaSApple OSS Distributions #ifdef PERSONA_DEBUG
265*aca3beaaSApple OSS Distributions #include <os/log.h>
266*aca3beaaSApple OSS Distributions #define persona_dbg(fmt, ...) \
267*aca3beaaSApple OSS Distributions 	os_log(OS_LOG_DEFAULT, "[%4d] %s:  " fmt "\n", \
268*aca3beaaSApple OSS Distributions 	       current_proc() ? proc_getpid(current_proc()) : -1, \
269*aca3beaaSApple OSS Distributions 	       __func__, ## __VA_ARGS__)
270*aca3beaaSApple OSS Distributions #else
271*aca3beaaSApple OSS Distributions #define persona_dbg(fmt, ...) do { } while (0)
272*aca3beaaSApple OSS Distributions #endif
273*aca3beaaSApple OSS Distributions 
274*aca3beaaSApple OSS Distributions /*
275*aca3beaaSApple OSS Distributions  * Persona
276*aca3beaaSApple OSS Distributions  */
277*aca3beaaSApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
278*aca3beaaSApple OSS Distributions /* only XNU proper needs to see the persona structure */
279*aca3beaaSApple OSS Distributions struct persona {
280*aca3beaaSApple OSS Distributions 	os_refcnt_t  pna_refcount;
281*aca3beaaSApple OSS Distributions 	int32_t      pna_valid;
282*aca3beaaSApple OSS Distributions 
283*aca3beaaSApple OSS Distributions 	uid_t        pna_id;
284*aca3beaaSApple OSS Distributions 	persona_type_t pna_type;
285*aca3beaaSApple OSS Distributions 	char         pna_login[MAXLOGNAME + 1];
286*aca3beaaSApple OSS Distributions 	char         *pna_path;
287*aca3beaaSApple OSS Distributions 	uid_t        pna_uid;
288*aca3beaaSApple OSS Distributions 
289*aca3beaaSApple OSS Distributions 	LIST_ENTRY(persona) pna_list;
290*aca3beaaSApple OSS Distributions 
291*aca3beaaSApple OSS Distributions 	/* this could go away if we used a coalition */
292*aca3beaaSApple OSS Distributions 	LIST_HEAD(, proc)   pna_members;
293*aca3beaaSApple OSS Distributions 
294*aca3beaaSApple OSS Distributions 	lck_mtx_t    pna_lock;
295*aca3beaaSApple OSS Distributions 
296*aca3beaaSApple OSS Distributions 	/*
297*aca3beaaSApple OSS Distributions 	 * We can add things here such as PID maps, UID maps, etc.
298*aca3beaaSApple OSS Distributions 	 */
299*aca3beaaSApple OSS Distributions #ifdef PERSONA_DEBUG
300*aca3beaaSApple OSS Distributions 	char         pna_desc[128];
301*aca3beaaSApple OSS Distributions #endif
302*aca3beaaSApple OSS Distributions };
303*aca3beaaSApple OSS Distributions 
304*aca3beaaSApple OSS Distributions #define persona_lock(persona)     lck_mtx_lock(&(persona)->pna_lock)
305*aca3beaaSApple OSS Distributions #define persona_unlock(persona)   lck_mtx_unlock(&(persona)->pna_lock)
306*aca3beaaSApple OSS Distributions #define persona_try_lock(persona) lck_mtx_try_lock(&(persona)->pna_lock)
307*aca3beaaSApple OSS Distributions 
308*aca3beaaSApple OSS Distributions #define persona_lock_assert_held(persona) \
309*aca3beaaSApple OSS Distributions 	LCK_MTX_ASSERT(&(persona)->pna_lock, LCK_MTX_ASSERT_OWNED)
310*aca3beaaSApple OSS Distributions 
311*aca3beaaSApple OSS Distributions #ifdef PERSONA_DEBUG
312*aca3beaaSApple OSS Distributions static inline const char *
persona_desc(struct persona * persona,int locked)313*aca3beaaSApple OSS Distributions persona_desc(struct persona *persona, int locked)
314*aca3beaaSApple OSS Distributions {
315*aca3beaaSApple OSS Distributions 	if (!persona) {
316*aca3beaaSApple OSS Distributions 		return "<none>";
317*aca3beaaSApple OSS Distributions 	}
318*aca3beaaSApple OSS Distributions 
319*aca3beaaSApple OSS Distributions 	if (persona->pna_desc[0] != 0) {
320*aca3beaaSApple OSS Distributions 		return persona->pna_desc;
321*aca3beaaSApple OSS Distributions 	}
322*aca3beaaSApple OSS Distributions 
323*aca3beaaSApple OSS Distributions 	if (!locked) {
324*aca3beaaSApple OSS Distributions 		persona_lock(persona);
325*aca3beaaSApple OSS Distributions 	}
326*aca3beaaSApple OSS Distributions 	if (persona->pna_desc[0] != 0) {
327*aca3beaaSApple OSS Distributions 		goto out_unlock;
328*aca3beaaSApple OSS Distributions 	}
329*aca3beaaSApple OSS Distributions 
330*aca3beaaSApple OSS Distributions 	char *p = &persona->pna_desc[0];
331*aca3beaaSApple OSS Distributions 	char *end = p + sizeof(persona->pna_desc) - 1;
332*aca3beaaSApple OSS Distributions 
333*aca3beaaSApple OSS Distributions 	*end = 0;
334*aca3beaaSApple OSS Distributions 	p += scnprintf(p, end - p, "%s/%d",
335*aca3beaaSApple OSS Distributions 	    persona->pna_login,
336*aca3beaaSApple OSS Distributions 	    persona->pna_id);
337*aca3beaaSApple OSS Distributions 
338*aca3beaaSApple OSS Distributions 	if (p <= end) {
339*aca3beaaSApple OSS Distributions 		*p = 0;
340*aca3beaaSApple OSS Distributions 	}
341*aca3beaaSApple OSS Distributions out_unlock:
342*aca3beaaSApple OSS Distributions 	if (!locked) {
343*aca3beaaSApple OSS Distributions 		persona_unlock(persona);
344*aca3beaaSApple OSS Distributions 	}
345*aca3beaaSApple OSS Distributions 
346*aca3beaaSApple OSS Distributions 	return persona->pna_desc;
347*aca3beaaSApple OSS Distributions }
348*aca3beaaSApple OSS Distributions #else /* !PERSONA_DEBUG */
349*aca3beaaSApple OSS Distributions static inline const char *
persona_desc(struct persona * persona,int locked)350*aca3beaaSApple OSS Distributions persona_desc(struct persona *persona, int locked)
351*aca3beaaSApple OSS Distributions {
352*aca3beaaSApple OSS Distributions 	(void)persona;
353*aca3beaaSApple OSS Distributions 	(void)locked;
354*aca3beaaSApple OSS Distributions 	return "<persona>";
355*aca3beaaSApple OSS Distributions }
356*aca3beaaSApple OSS Distributions #endif
357*aca3beaaSApple OSS Distributions 
358*aca3beaaSApple OSS Distributions #else /* !XNU_KERNEL_PRIVATE */
359*aca3beaaSApple OSS Distributions /* kexts should only see an opaque persona structure */
360*aca3beaaSApple OSS Distributions struct persona;
361*aca3beaaSApple OSS Distributions #endif
362*aca3beaaSApple OSS Distributions 
363*aca3beaaSApple OSS Distributions __BEGIN_DECLS
364*aca3beaaSApple OSS Distributions 
365*aca3beaaSApple OSS Distributions #ifndef _KAUTH_CRED_T
366*aca3beaaSApple OSS Distributions #define _KAUTH_CRED_T
367*aca3beaaSApple OSS Distributions typedef struct ucred *kauth_cred_t;
368*aca3beaaSApple OSS Distributions #endif  /* !_KAUTH_CRED_T */
369*aca3beaaSApple OSS Distributions 
370*aca3beaaSApple OSS Distributions /* returns the persona ID for the given pesona structure */
371*aca3beaaSApple OSS Distributions uid_t persona_get_id(struct persona *persona);
372*aca3beaaSApple OSS Distributions 
373*aca3beaaSApple OSS Distributions /* returns the persona UID for the given pesona structure */
374*aca3beaaSApple OSS Distributions uid_t persona_get_uid(struct persona *persona);
375*aca3beaaSApple OSS Distributions 
376*aca3beaaSApple OSS Distributions /* returns the type of the persona (see enum above: PERSONA_GUEST, etc.) */
377*aca3beaaSApple OSS Distributions int persona_get_type(struct persona *persona);
378*aca3beaaSApple OSS Distributions 
379*aca3beaaSApple OSS Distributions /* returns a reference that must be released with persona_put() */
380*aca3beaaSApple OSS Distributions struct persona *persona_lookup(uid_t id);
381*aca3beaaSApple OSS Distributions 
382*aca3beaaSApple OSS Distributions /*
383*aca3beaaSApple OSS Distributions  * Search for personas based on name or uid
384*aca3beaaSApple OSS Distributions  *
385*aca3beaaSApple OSS Distributions  * Parameters:
386*aca3beaaSApple OSS Distributions  *       name: Local login name of the persona.
387*aca3beaaSApple OSS Distributions  *             Set this to NULL to find personas by 'uid'.
388*aca3beaaSApple OSS Distributions  *
389*aca3beaaSApple OSS Distributions  *        uid: UID of the persona.
390*aca3beaaSApple OSS Distributions  *             Set this to -1 to find personas by 'name'
391*aca3beaaSApple OSS Distributions  *
392*aca3beaaSApple OSS Distributions  *    persona: output - array of persona pointers. Each non-NULL value
393*aca3beaaSApple OSS Distributions  *             must* be released with persona_put. This can be NULL.
394*aca3beaaSApple OSS Distributions  *
395*aca3beaaSApple OSS Distributions  *       plen: input - size of 'persona' buffer (in number of pointers)
396*aca3beaaSApple OSS Distributions  *             output - the total required size of the 'persona' buffer (could be larger than input value)
397*aca3beaaSApple OSS Distributions  *
398*aca3beaaSApple OSS Distributions  * Return:
399*aca3beaaSApple OSS Distributions  *           0: Success
400*aca3beaaSApple OSS Distributions  *        != 0: failure (BSD errno value ESRCH or EINVAL)
401*aca3beaaSApple OSS Distributions  */
402*aca3beaaSApple OSS Distributions int persona_find(const char *login, uid_t uid,
403*aca3beaaSApple OSS Distributions     struct persona **persona, size_t *plen);
404*aca3beaaSApple OSS Distributions 
405*aca3beaaSApple OSS Distributions /* returns a reference that must be released with persona_put() */
406*aca3beaaSApple OSS Distributions struct persona *persona_proc_get(pid_t pid);
407*aca3beaaSApple OSS Distributions 
408*aca3beaaSApple OSS Distributions /* returns the persona id tied to the current thread (also uses adopted voucher) */
409*aca3beaaSApple OSS Distributions uid_t current_persona_get_id(void);
410*aca3beaaSApple OSS Distributions 
411*aca3beaaSApple OSS Distributions /* returns a reference to the persona tied to the current thread (also uses adopted voucher) */
412*aca3beaaSApple OSS Distributions struct persona *current_persona_get(void);
413*aca3beaaSApple OSS Distributions 
414*aca3beaaSApple OSS Distributions /* get a reference to a persona structure */
415*aca3beaaSApple OSS Distributions struct persona *persona_get(struct persona *persona);
416*aca3beaaSApple OSS Distributions 
417*aca3beaaSApple OSS Distributions /* returns a reference to proc's persona that must be released with persona_put() */
418*aca3beaaSApple OSS Distributions struct persona *proc_persona_get(proc_t p);
419*aca3beaaSApple OSS Distributions 
420*aca3beaaSApple OSS Distributions /* release a reference to a persona structure */
421*aca3beaaSApple OSS Distributions void persona_put(struct persona *persona);
422*aca3beaaSApple OSS Distributions 
423*aca3beaaSApple OSS Distributions /*
424*aca3beaaSApple OSS Distributions  * Search for personas of a given type, 'persona_type'.
425*aca3beaaSApple OSS Distributions  *
426*aca3beaaSApple OSS Distributions  * Parameters:
427*aca3beaaSApple OSS Distributions  *   persona_type: Type of persona (see enum)
428*aca3beaaSApple OSS Distributions  *
429*aca3beaaSApple OSS Distributions  *        persona: output - array of persona pointers. Each non-NULL value
430*aca3beaaSApple OSS Distributions  *        must* be released with persona_put. This can be NULL.
431*aca3beaaSApple OSS Distributions  *
432*aca3beaaSApple OSS Distributions  *           plen: input - size of 'persona' buffer (in number of pointers)
433*aca3beaaSApple OSS Distributions  *                 output - the total required size of the 'persona' buffer (could be larger than input value)
434*aca3beaaSApple OSS Distributions  *
435*aca3beaaSApple OSS Distributions  * Return:
436*aca3beaaSApple OSS Distributions  *           0: Success
437*aca3beaaSApple OSS Distributions  *        != 0: failure (BSD errno value ESRCH or EINVAL)
438*aca3beaaSApple OSS Distributions  */
439*aca3beaaSApple OSS Distributions int persona_find_by_type(persona_type_t persona_type, struct persona **persona,
440*aca3beaaSApple OSS Distributions     size_t *plen);
441*aca3beaaSApple OSS Distributions 
442*aca3beaaSApple OSS Distributions boolean_t persona_is_adoption_allowed(struct persona *persona);
443*aca3beaaSApple OSS Distributions 
444*aca3beaaSApple OSS Distributions #ifdef XNU_KERNEL_PRIVATE
445*aca3beaaSApple OSS Distributions 
446*aca3beaaSApple OSS Distributions #if CONFIG_PERSONAS
447*aca3beaaSApple OSS Distributions #include <sys/proc_internal.h>
448*aca3beaaSApple OSS Distributions 
449*aca3beaaSApple OSS Distributions /*
450*aca3beaaSApple OSS Distributions  * In-kernel persona API
451*aca3beaaSApple OSS Distributions  */
452*aca3beaaSApple OSS Distributions extern const uint32_t g_max_personas;
453*aca3beaaSApple OSS Distributions 
454*aca3beaaSApple OSS Distributions struct persona *persona_alloc(uid_t id, const char *login,
455*aca3beaaSApple OSS Distributions     persona_type_t type, char *path, uid_t uid, int *error);
456*aca3beaaSApple OSS Distributions 
457*aca3beaaSApple OSS Distributions int persona_init_begin(struct persona *persona);
458*aca3beaaSApple OSS Distributions void persona_init_end(struct persona *persona, int error);
459*aca3beaaSApple OSS Distributions 
460*aca3beaaSApple OSS Distributions struct persona *persona_lookup_and_invalidate(uid_t id);
461*aca3beaaSApple OSS Distributions 
462*aca3beaaSApple OSS Distributions static inline int
proc_has_persona(proc_t p)463*aca3beaaSApple OSS Distributions proc_has_persona(proc_t p)
464*aca3beaaSApple OSS Distributions {
465*aca3beaaSApple OSS Distributions 	if (p && p->p_persona) {
466*aca3beaaSApple OSS Distributions 		return 1;
467*aca3beaaSApple OSS Distributions 	}
468*aca3beaaSApple OSS Distributions 	return 0;
469*aca3beaaSApple OSS Distributions }
470*aca3beaaSApple OSS Distributions 
471*aca3beaaSApple OSS Distributions static inline uid_t
persona_id_from_proc(proc_t p)472*aca3beaaSApple OSS Distributions persona_id_from_proc(proc_t p)
473*aca3beaaSApple OSS Distributions {
474*aca3beaaSApple OSS Distributions 	if (p && p->p_persona) {
475*aca3beaaSApple OSS Distributions 		return p->p_persona->pna_id;
476*aca3beaaSApple OSS Distributions 	}
477*aca3beaaSApple OSS Distributions 	return PERSONA_ID_NONE;
478*aca3beaaSApple OSS Distributions }
479*aca3beaaSApple OSS Distributions 
480*aca3beaaSApple OSS Distributions int persona_proc_inherit(proc_t child, proc_t parent);
481*aca3beaaSApple OSS Distributions 
482*aca3beaaSApple OSS Distributions int persona_proc_adopt(proc_t p, struct persona *persona,
483*aca3beaaSApple OSS Distributions     kauth_cred_t auth_override);
484*aca3beaaSApple OSS Distributions int persona_proc_drop(proc_t p);
485*aca3beaaSApple OSS Distributions 
486*aca3beaaSApple OSS Distributions /* returns a reference that must be released with persona_put() */
487*aca3beaaSApple OSS Distributions struct persona *persona_proc_get(pid_t pid);
488*aca3beaaSApple OSS Distributions 
489*aca3beaaSApple OSS Distributions int persona_find_all(const char *login, uid_t uid, persona_type_t persona_type,
490*aca3beaaSApple OSS Distributions     struct persona **persona, size_t *plen);
491*aca3beaaSApple OSS Distributions 
492*aca3beaaSApple OSS Distributions #else /* !CONFIG_PERSONAS */
493*aca3beaaSApple OSS Distributions 
494*aca3beaaSApple OSS Distributions static inline int
proc_has_persona(__unused proc_t p)495*aca3beaaSApple OSS Distributions proc_has_persona(__unused proc_t p)
496*aca3beaaSApple OSS Distributions {
497*aca3beaaSApple OSS Distributions 	return 0;
498*aca3beaaSApple OSS Distributions }
499*aca3beaaSApple OSS Distributions 
500*aca3beaaSApple OSS Distributions static inline uid_t
persona_id_from_proc(__unused proc_t p)501*aca3beaaSApple OSS Distributions persona_id_from_proc(__unused proc_t p)
502*aca3beaaSApple OSS Distributions {
503*aca3beaaSApple OSS Distributions 	return PERSONA_ID_NONE;
504*aca3beaaSApple OSS Distributions }
505*aca3beaaSApple OSS Distributions 
506*aca3beaaSApple OSS Distributions #endif /* CONFIG_PERSONAS */
507*aca3beaaSApple OSS Distributions #endif /* XNU_KERNEL_PRIVATE */
508*aca3beaaSApple OSS Distributions __END_DECLS
509*aca3beaaSApple OSS Distributions 
510*aca3beaaSApple OSS Distributions #endif /* KERNEL_PRIVATE */
511*aca3beaaSApple OSS Distributions 
512*aca3beaaSApple OSS Distributions #endif /* PRIVATE */
513*aca3beaaSApple OSS Distributions #endif /* _SYS_PERSONA_H_ */
514