xref: /xnu-12377.81.4/bsd/sys/kauth.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
30  * support for mandatory and extensible security protections.  This notice
31  * is included in support of clause 2.2 (b) of the Apple Public License,
32  * Version 2.0.
33  */
34 
35 #ifndef _SYS_KAUTH_H
36 #define _SYS_KAUTH_H
37 
38 #include <sys/appleapiopts.h>
39 #include <sys/cdefs.h>
40 #include <mach/boolean.h>
41 #include <machine/types.h>      /* u_int8_t, etc. */
42 #include <sys/_types.h>         /* __offsetof() */
43 #include <sys/_types/_uid_t.h>  /* uid_t */
44 #include <sys/_types/_gid_t.h>     /* gid_t */
45 #include <sys/_types/_guid_t.h>
46 #include <sys/syslimits.h>      /* NGROUPS_MAX */
47 #ifdef KERNEL
48 #include <stdbool.h>
49 #include <sys/ucred.h>
50 #include <sys/lock.h>   /* lck_grp_t */
51 #endif /* KERNEL */
52 #if KERNEL_PRIVATE
53 #include <kern/smr_types.h>
54 #endif
55 
56 __BEGIN_DECLS
57 
58 #ifdef __APPLE_API_EVOLVING
59 
60 /*
61  * Identities.
62  */
63 
64 #define KAUTH_UID_NONE  (~(uid_t)0 - 100)       /* not a valid UID */
65 #define KAUTH_GID_NONE  (~(gid_t)0 - 100)       /* not a valid GID */
66 
67 /* NT Security Identifier, structure as defined by Microsoft */
68 #pragma pack(1)    /* push packing of 1 byte */
69 typedef struct {
70 	u_int8_t                sid_kind;
71 	u_int8_t                sid_authcount;
72 	u_int8_t                sid_authority[6];
73 #define KAUTH_NTSID_MAX_AUTHORITIES 16
74 	u_int32_t       sid_authorities[KAUTH_NTSID_MAX_AUTHORITIES];
75 } ntsid_t;
76 #pragma pack()    /* pop packing to previous packing level */
77 #define _NTSID_T
78 
79 /* valid byte count inside a SID structure */
80 #define KAUTH_NTSID_HDRSIZE     (8)
81 #define KAUTH_NTSID_SIZE(_s)    (KAUTH_NTSID_HDRSIZE + ((_s)->sid_authcount * sizeof(u_int32_t)))
82 
83 /*
84  * External lookup message payload; this structure is shared between the
85  * kernel group membership resolver, and the user space group membership
86  * resolver daemon, and is use to communicate resolution requests from the
87  * kernel to user space, and the result of that request from user space to
88  * the kernel.
89  */
90 struct kauth_identity_extlookup {
91 	u_int32_t       el_seqno;       /* request sequence number */
92 	u_int32_t       el_result;      /* lookup result */
93 #define KAUTH_EXTLOOKUP_SUCCESS         0       /* results here are good */
94 #define KAUTH_EXTLOOKUP_BADRQ           1       /* request badly formatted */
95 #define KAUTH_EXTLOOKUP_FAILURE         2       /* transient failure during lookup */
96 #define KAUTH_EXTLOOKUP_FATAL           3       /* permanent failure during lookup */
97 #define KAUTH_EXTLOOKUP_INPROG          100     /* request in progress */
98 	u_int32_t       el_flags;
99 #define KAUTH_EXTLOOKUP_VALID_UID       (1<<0)
100 #define KAUTH_EXTLOOKUP_VALID_UGUID     (1<<1)
101 #define KAUTH_EXTLOOKUP_VALID_USID      (1<<2)
102 #define KAUTH_EXTLOOKUP_VALID_GID       (1<<3)
103 #define KAUTH_EXTLOOKUP_VALID_GGUID     (1<<4)
104 #define KAUTH_EXTLOOKUP_VALID_GSID      (1<<5)
105 #define KAUTH_EXTLOOKUP_WANT_UID        (1<<6)
106 #define KAUTH_EXTLOOKUP_WANT_UGUID      (1<<7)
107 #define KAUTH_EXTLOOKUP_WANT_USID       (1<<8)
108 #define KAUTH_EXTLOOKUP_WANT_GID        (1<<9)
109 #define KAUTH_EXTLOOKUP_WANT_GGUID      (1<<10)
110 #define KAUTH_EXTLOOKUP_WANT_GSID       (1<<11)
111 #define KAUTH_EXTLOOKUP_WANT_MEMBERSHIP (1<<12)
112 #define KAUTH_EXTLOOKUP_VALID_MEMBERSHIP (1<<13)
113 #define KAUTH_EXTLOOKUP_ISMEMBER        (1<<14)
114 #define KAUTH_EXTLOOKUP_VALID_PWNAM     (1<<15)
115 #define KAUTH_EXTLOOKUP_WANT_PWNAM      (1<<16)
116 #define KAUTH_EXTLOOKUP_VALID_GRNAM     (1<<17)
117 #define KAUTH_EXTLOOKUP_WANT_GRNAM      (1<<18)
118 #define KAUTH_EXTLOOKUP_VALID_SUPGRPS   (1<<19)
119 #define KAUTH_EXTLOOKUP_WANT_SUPGRPS    (1<<20)
120 
121 	__darwin_pid_t  el_info_pid;            /* request on behalf of PID */
122 	u_int64_t       el_extend;              /* extension field */
123 	u_int32_t       el_info_reserved_1;     /* reserved (APPLE) */
124 
125 	uid_t           el_uid;         /* user ID */
126 	guid_t          el_uguid;       /* user GUID */
127 	u_int32_t       el_uguid_valid; /* TTL on translation result (seconds) */
128 	ntsid_t         el_usid;        /* user NT SID */
129 	u_int32_t       el_usid_valid;  /* TTL on translation result (seconds) */
130 	gid_t           el_gid;         /* group ID */
131 	guid_t          el_gguid;       /* group GUID */
132 	u_int32_t       el_gguid_valid; /* TTL on translation result (seconds) */
133 	ntsid_t         el_gsid;        /* group SID */
134 	u_int32_t       el_gsid_valid;  /* TTL on translation result (seconds) */
135 	u_int32_t       el_member_valid; /* TTL on group lookup result */
136 	u_int32_t       el_sup_grp_cnt;  /* count of supplemental groups up to NGROUPS */
137 	gid_t           el_sup_groups[NGROUPS_MAX];     /* supplemental group list */
138 };
139 
140 struct kauth_cache_sizes {
141 	u_int32_t kcs_group_size;
142 	u_int32_t kcs_id_size;
143 };
144 
145 #define KAUTH_EXTLOOKUP_REGISTER        (0)
146 #define KAUTH_EXTLOOKUP_RESULT          (1<<0)
147 #define KAUTH_EXTLOOKUP_WORKER          (1<<1)
148 #define KAUTH_EXTLOOKUP_DEREGISTER      (1<<2)
149 #define KAUTH_GET_CACHE_SIZES           (1<<3)
150 #define KAUTH_SET_CACHE_SIZES           (1<<4)
151 #define KAUTH_CLEAR_CACHES              (1<<5)
152 
153 #define IDENTITYSVC_ENTITLEMENT         "com.apple.private.identitysvc"
154 
155 #ifdef KERNEL
156 #pragma mark - kauth_cred
157 
158 /*!
159  * @brief
160  * Retains a credential data structure.
161  *
162  * @Description
163  * The reference returned must be released with @c kauth_cred_unref().
164  */
165 extern void         kauth_cred_ref(kauth_cred_t cred);
166 
167 /*!
168  * @brief
169  * Releases a credential data structure, and nils out the pointer.
170  *
171  * @Description
172  * @c credp must be non NULL, but can point to a NULL/NOCRED credential.
173  */
174 extern void         kauth_cred_unref(kauth_cred_t *credp);
175 
176 
177 /*!
178  * @brief
179  * Returns the current thread assumed credentials.
180  *
181  * @discussion
182  * These might differ from the proc's credential if settid() has been called.
183  * This never returns NULL/NOCRED.
184  *
185  * This function doesn't take a reference, and the returned pointer is valid
186  * for the duration of the current syscall.
187  *
188  * This function returns cached credentials without a reference which are valid
189  * for the duration of a MACF hook.  If a copy of this pointer has to be stashed,
190  * the credentials must be retained with kauth_cred_ref().
191  *
192  * (this function should really be called @c current_thread_cred())
193  */
194 extern kauth_cred_t kauth_cred_get(void) __pure2;
195 #define current_thread_cred()           kauth_cred_get()
196 
197 /*!
198  * @brief
199  * Returns the current MAC label slot value for the thread assumed credentials.
200  *
201  * @discussion
202  * These might differ from the proc's credential if settid() has been called.
203  */
204 extern intptr_t current_thread_cred_label_get(int slot) __pure2;
205 
206 /*!
207  * @brief
208  * Returns the current thread assumed credentials, with a reference.
209  *
210  * @discussion
211  * These might differ from the proc's credential if settid() has been called.
212  * This never returns NULL/NOCRED.
213  *
214  * The caller must call kauth_cred_unref() to dispose of the returned value.
215  *
216  * This is equivalent to @c kauth_cred_ref(kauth_cred_get())
217  *
218  * (this function should really be called @c current_thread_cred_ref())
219  */
220 extern kauth_cred_t kauth_cred_get_with_ref(void);
221 #define current_thread_cred_ref()       kauth_cred_get_with_ref()
222 
223 /*!
224  * @brief
225  * Returns the current cached proc credentials.
226  *
227  * @discussion
228  * This function will panic if its argument is neither PROC_NULL nor
229  * current_proc() (this can be used to protect against programming mistakes
230  * assuming the incorrect context).
231  *
232  * Note that this function returns the credential the proc had
233  * at the time of the last syscall this thread performed.
234  *
235  * This function returns cached credentials without a reference which are valid
236  * for the duration of a syscall only. If a copy of this pointer has to be
237  * stashed, the credentials must be retained with kauth_cred_ref().
238  *
239  * For the freshest credentials, kauth_cred_proc_ref()
240  * must be used against @c current_proc().
241  *
242  * This never returns NULL/NOCRED.
243  */
244 extern kauth_cred_t current_cached_proc_cred(proc_t) __pure2;
245 
246 /*!
247  * @brief
248  * Returns the current MAC label slot value for the cached proc credentials.
249  */
250 extern intptr_t current_cached_proc_label_get(int slot) __pure2;
251 
252 /*!
253  * @brief
254  * Returns the current cached proc credentials, with a reference.
255  *
256  * @discussion
257  * This function will panic if its argument is neither PROC_NULL nor
258  * current_proc() (this can be used to protect against programming mistakes
259  * assuming the incorrect context).
260  *
261  * Note that this function returns the credential the proc had
262  * at the time of the last syscall this thread performed.
263  *
264  * For the freshest credentials, kauth_cred_proc_ref()
265  * must be used against @c current_proc().
266  *
267  * The caller must call kauth_cred_unref() to dispose of the returned value.
268  *
269  * This never returns NULL/NOCRED.
270  */
271 extern kauth_cred_t current_cached_proc_cred_ref(proc_t);
272 
273 /*!
274  * @brief
275  * Returns the specified proc credentials, with a reference.
276  *
277  * @discussion
278  * The caller must call kauth_cred_unref() to dispose of the returned value.
279  * This never returns NULL/NOCRED.
280  *
281  * The caller must call kauth_cred_unref() to dispose of the returned value.
282  */
283 extern kauth_cred_t kauth_cred_proc_ref(proc_t procp);
284 
285 /*!
286  * @brief
287  * Returns the specified proc credentials, with a reference, or NOCRED.
288  *
289  * @discussion
290  * The caller must call kauth_cred_unref() to dispose of the returned value.
291  */
292 extern kauth_cred_t kauth_cred_proc_ref_for_pid(pid_t pid);
293 
294 /*!
295  * @brief
296  * Returns the specified proc credentials, with a reference, or NOCRED.
297  *
298  * @discussion
299  * The caller must call kauth_cred_unref() to dispose of the returned value.
300  */
301 extern kauth_cred_t kauth_cred_proc_ref_for_pidversion(pid_t pid, uint32_t version);
302 
303 
304 /*!
305  * @brief
306  * Obsolete way to create a valid posix-only credential structure out of
307  * a model, DO NOT USE.
308  */
309 extern kauth_cred_t kauth_cred_create(kauth_cred_t cred);
310 
311 
312 #pragma mark kauth_cred: accessors
313 
314 /*!
315  * @brief
316  * Returns the effective user ID for the specified @c kauth_cred_t.
317  */
318 extern uid_t        kauth_cred_getuid(kauth_cred_t _cred);
319 
320 /*!
321  * @brief
322  * Returns the real user ID for the specified @c kauth_cred_t.
323  */
324 extern uid_t        kauth_cred_getruid(kauth_cred_t _cred);
325 
326 /*!
327  * @brief
328  * Returns the saved user ID for the specified @c kauth_cred_t.
329  */
330 extern uid_t        kauth_cred_getsvuid(kauth_cred_t _cred);
331 
332 /*!
333  * @brief
334  * Returns whether the current credential effective user ID is the super user.
335  */
336 extern int          kauth_cred_issuser(kauth_cred_t _cred);
337 
338 /*!
339  * @brief
340  * Returns the effective group ID for the specified @c kauth_cred_t.
341  */
342 extern gid_t        kauth_cred_getgid(kauth_cred_t _cred);
343 
344 /*!
345  * @brief
346  * Returns the real group ID for the specified @c kauth_cred_t.
347  */
348 extern gid_t        kauth_cred_getrgid(kauth_cred_t _cred);
349 
350 /*!
351  * @brief
352  * Returns the saved group ID for the specified @c kauth_cred_t.
353  */
354 extern gid_t        kauth_cred_getsvgid(kauth_cred_t _cred);
355 
356 /*!
357  * @brief
358  * Returns the effective user ID for the current thread.
359  *
360  * @Description
361  * Equivalent to @c kauth_getuid(kauth_cred_get())
362  */
363 extern uid_t        kauth_getuid(void);
364 
365 /*!
366  * @brief
367  * Returns the real user ID for the current thread.
368  *
369  * @Description
370  * Equivalent to @c kauth_getruid(kauth_cred_get())
371  */
372 extern uid_t        kauth_getruid(void);
373 
374 /*!
375  * @brief
376  * Returns the effective group ID for the current thread.
377  *
378  * @Description
379  * Equivalent to @c kauth_getgid(kauth_cred_get())
380  */
381 extern gid_t        kauth_getgid(void);
382 
383 /*!
384  * @brief
385  * Returns the real group ID for the current thread.
386  *
387  * @Description
388  * Equivalent to @c kauth_getrgid(kauth_cred_get())
389  */
390 extern gid_t        kauth_getrgid(void);
391 
392 
393 #pragma mark kauth_cred: MACF label updates
394 
395 struct label;
396 
397 /*!
398  * @brief
399  * Updates the MAC label associated with a credential.
400  *
401  * @discussion
402  * This function returns a new credential where the passed
403  * in label is updated with the specified one.
404  *
405  * This will cause the @c cred_label_associate() MAC hook to be invoked
406  * first (so that all MAC policies have a chance to make the newly formed
407  * credential inherit labels) then the @c cred_label_update() hook
408  * (which will allow the newly made credential labels to be overridden).
409  *
410  * This never returns NULL/NOCRED.
411  *
412  * @param cred          (ref consumed) the credentials to use as a model.
413  * @param label         the model label to copy from.
414  */
415 extern kauth_cred_t kauth_cred_label_update(
416 	kauth_cred_t            cred,
417 	struct label           *label);
418 
419 
420 /*!
421  * @brief
422  * Updates the MAC label insde the proc's credentials.
423  *
424  * @discussion
425  * This function applies @c kauth_cred_label_update() to the specified
426  * process's credntials, and updates the process's credentials
427  * with the outcome.
428  *
429  * This function never fails (returns 0 all the time).
430  *
431  * @param proc          the process which creedntials must be updated.
432  * @param label         the model label to copy from.
433  */
434 extern int          kauth_proc_label_update(
435 	struct proc            *proc,
436 	struct label           *label);
437 
438 
439 #pragma mark kauth_cred: group membership (private API)
440 /*
441  * This part of the kernel is considered private and prototypes
442  * will be eventually be removed from the public headers.
443  */
444 
445 extern int          kauth_cred_pwnam2guid(char *pwnam, guid_t *guidp);
446 extern int          kauth_cred_grnam2guid(char *grnam, guid_t *guidp);
447 extern int          kauth_cred_guid2pwnam(guid_t *guidp, char *pwnam);
448 extern int          kauth_cred_guid2grnam(guid_t *guidp, char *grnam);
449 extern int          kauth_cred_guid2uid(guid_t *_guid, uid_t *_uidp);
450 extern int          kauth_cred_guid2gid(guid_t *_guid, gid_t *_gidp);
451 extern int          kauth_cred_ntsid2uid(ntsid_t *_sid, uid_t *_uidp);
452 extern int          kauth_cred_ntsid2gid(ntsid_t *_sid, gid_t *_gidp);
453 extern int          kauth_cred_ntsid2guid(ntsid_t *_sid, guid_t *_guidp);
454 extern int          kauth_cred_uid2guid(uid_t _uid, guid_t *_guidp);
455 extern int          kauth_cred_getguid(kauth_cred_t _cred, guid_t *_guidp);
456 extern int          kauth_cred_gid2guid(gid_t _gid, guid_t *_guidp);
457 extern int          kauth_cred_uid2ntsid(uid_t _uid, ntsid_t *_sidp);
458 extern int          kauth_cred_getntsid(kauth_cred_t _cred, ntsid_t *_sidp);
459 extern int          kauth_cred_gid2ntsid(gid_t _gid, ntsid_t *_sidp);
460 extern int          kauth_cred_guid2ntsid(guid_t *_guid, ntsid_t *_sidp);
461 extern int          kauth_cred_ismember_gid(kauth_cred_t _cred, gid_t _gid, int *_resultp);
462 extern int          kauth_cred_ismember_guid(kauth_cred_t _cred, guid_t *_guidp, int *_resultp);
463 extern int          kauth_cred_nfs4domain2dsnode(char *nfs4domain, char *dsnode);
464 extern int          kauth_cred_dsnode2nfs4domain(char *dsnode, char *nfs4domain);
465 
466 extern int          groupmember(gid_t gid, kauth_cred_t cred);
467 
468 
469 #ifdef KERNEL_PRIVATE
470 #pragma mark kauth_cred: private KPI
471 
472 extern int          kauth_cred_getgroups(kauth_cred_t _cred, gid_t *_groups, size_t *_groupcount);
473 
474 #endif /* KERNEL_PRIVATE */
475 #ifdef XNU_KERNEL_PRIVATE
476 #pragma mark kauth_cred: XNU only
477 #pragma GCC visibility push(hidden)
478 
479 extern lck_grp_t    kauth_lck_grp;
480 
481 extern void         kauth_init(void);
482 
483 #pragma mark XNU only: kauth_cred interfaces
484 
485 extern kauth_cred_t posix_cred_create(posix_cred_t pcred);
486 extern posix_cred_t posix_cred_get(kauth_cred_t cred) __pure2;
487 extern int          posix_cred_access(kauth_cred_t cred, id_t object_uid, id_t object_gid, mode_t object_mode, mode_t mode_req);
488 
489 extern int          cantrace(proc_t cur_procp, kauth_cred_t creds, proc_t traced_procp, int *errp);
490 extern kauth_cred_t kauth_cred_copy_real(kauth_cred_t cred);
491 
492 
493 /*!
494  * @brief
495  * Type of functions used to derive credentials from an original one.
496  *
497  * @description
498  * The @c model argument is an on-stack template that is to be mutated
499  * in place, and that will be used to make the derived credential.
500  *
501  * The function should return false if it made no modifications,
502  * and true if it did (it is OK to return true incorrectly,
503  * it is just a little less efficient).
504  */
505 typedef bool (^kauth_cred_derive_t)(kauth_cred_t parent, kauth_cred_t model);
506 
507 /*!
508  * @brief
509  * Derive a credential from a given cred.
510  *
511  * @description
512  * This function never returns NULL.
513  */
514 extern kauth_cred_t kauth_cred_derive(kauth_cred_t cred, kauth_cred_derive_t fn);
515 
516 __enum_decl(proc_settoken_t, uint32_t, {
517 	PROC_SETTOKEN_NONE       = 0x0000,
518 	PROC_SETTOKEN_LAZY       = 0x0001, /* set the security token on change */
519 	PROC_SETTOKEN_ALWAYS     = 0x0002, /* set the security token all the time */
520 	PROC_SETTOKEN_SETUGID    = 0x0003, /* PROC_SETTOKEN_LAZY + set P_SUGID */
521 });
522 
523 /*!
524  * @brief
525  * Update the credential on the specified proc.
526  *
527  * @description
528  * The function returns true if an update took place.
529  */
530 extern bool         kauth_cred_proc_update(proc_t p, proc_settoken_t action, kauth_cred_derive_t fn);
531 
532 extern bool         kauth_cred_model_setresuid(kauth_cred_t model, uid_t ruid, uid_t euid, uid_t svuid, uid_t gmuid);
533 extern bool         kauth_cred_model_setresgid(kauth_cred_t model, gid_t rgid, gid_t egid, gid_t svgid);
534 extern bool         kauth_cred_model_setuidgid(kauth_cred_t model, uid_t uid, gid_t gid);
535 extern bool         kauth_cred_model_setgroups(kauth_cred_t model, gid_t *groups, size_t groupcount, uid_t gmuid);
536 extern bool         kauth_cred_model_setauditinfo(kauth_cred_t model, au_session_t *);
537 
538 extern void         kauth_cred_thread_update(struct thread *, proc_t);
539 #ifdef CONFIG_MACF
540 extern void         kauth_proc_label_update_execve(struct proc *p, struct vfs_context *ctx, struct vnode *vp, off_t offset, struct vnode *scriptvp, struct label *scriptlabel, struct label *execlabel, unsigned int *csflags, void *psattr, int *disjoint, int *update_return);
541 #endif
542 extern int          kauth_cred_gid_subset(kauth_cred_t _cred1, kauth_cred_t _cred2, int *_resultp);
543 
544 extern kauth_cred_t kauth_cred_require(kauth_cred_t cred) __pure2;
545 
546 extern void         kauth_cred_set(kauth_cred_t *credp, kauth_cred_t new_cred);
547 #if CONFIG_EXT_RESOLVER
548 extern void         kauth_resolver_identity_reset(void);
549 #endif
550 
551 /* update the thread's proc cred cache, called on syscall entry */
552 extern void         current_cached_proc_cred_update(void);
553 
554 /*
555  * `kauth_cred_set` and `kauth_cred_unref` take pointers to a
556  * `kauth_cred_t`, which the compiler considers strictly different from a
557  * pointer to a signed `kauth_cred_t` (as it should do).  These macros
558  * therefore authenticate the arguments into naked locals, pass them to the
559  * function and then write back the results, signing them in the process.
560  */
561 #define kauth_cred_set(credp, new_cred) \
562     do { \
563 	    kauth_cred_t _cred __single = *(credp); \
564 	    (kauth_cred_set)(&_cred, (new_cred)); \
565 	    *(credp) = _cred; \
566     } while (0)
567 
568 #define kauth_cred_unref(credp) \
569     do { \
570 	    kauth_cred_t _credp __single = *(credp); \
571 	    (kauth_cred_unref)(&_credp); \
572 	    *(credp) = _credp; \
573     } while (0)
574 
575 #pragma GCC visibility pop
576 #endif /* XNU_KERNEL_PRIVATE */
577 #endif /* KERNEL */
578 #if defined(KERNEL) || defined (_SYS_ACL_H)
579 #pragma mark - kauth
580 #pragma mark kauth: Generic Access Control Lists.
581 
582 typedef u_int32_t kauth_ace_rights_t;
583 
584 /* Access Control List Entry (ACE) */
585 struct kauth_ace {
586 	guid_t          ace_applicable;
587 	u_int32_t       ace_flags;
588 #define KAUTH_ACE_KINDMASK              0xf
589 #define KAUTH_ACE_PERMIT                1
590 #define KAUTH_ACE_DENY                  2
591 #define KAUTH_ACE_AUDIT                 3       /* not implemented */
592 #define KAUTH_ACE_ALARM                 4       /* not implemented */
593 #define KAUTH_ACE_INHERITED             (1<<4)
594 #define KAUTH_ACE_FILE_INHERIT          (1<<5)
595 #define KAUTH_ACE_DIRECTORY_INHERIT     (1<<6)
596 #define KAUTH_ACE_LIMIT_INHERIT         (1<<7)
597 #define KAUTH_ACE_ONLY_INHERIT          (1<<8)
598 #define KAUTH_ACE_SUCCESS               (1<<9)  /* not implemented (AUDIT/ALARM) */
599 #define KAUTH_ACE_FAILURE               (1<<10) /* not implemented (AUDIT/ALARM) */
600 /* All flag bits controlling ACE inheritance */
601 #define KAUTH_ACE_INHERIT_CONTROL_FLAGS         \
602 	        (KAUTH_ACE_FILE_INHERIT |       \
603 	         KAUTH_ACE_DIRECTORY_INHERIT |  \
604 	         KAUTH_ACE_LIMIT_INHERIT |      \
605 	         KAUTH_ACE_ONLY_INHERIT)
606 	kauth_ace_rights_t ace_rights;          /* scope specific */
607 	/* These rights are never tested, but may be present in an ACL */
608 #define KAUTH_ACE_GENERIC_ALL           (1<<21)
609 #define KAUTH_ACE_GENERIC_EXECUTE       (1<<22)
610 #define KAUTH_ACE_GENERIC_WRITE         (1<<23)
611 #define KAUTH_ACE_GENERIC_READ          (1<<24)
612 };
613 
614 #ifndef _KAUTH_ACE
615 #define _KAUTH_ACE
616 typedef struct kauth_ace *kauth_ace_t;
617 #endif
618 
619 
620 /* Access Control List */
621 struct kauth_acl {
622 	u_int32_t       acl_entrycount;
623 	u_int32_t       acl_flags;
624 
625 	struct kauth_ace acl_ace[1];
626 };
627 
628 /*
629  * XXX this value needs to be raised - 3893388
630  */
631 #define KAUTH_ACL_MAX_ENTRIES           128
632 
633 /*
634  * The low 16 bits of the flags field are reserved for filesystem
635  * internal use and must be preserved by all APIs.  This includes
636  * round-tripping flags through user-space interfaces.
637  */
638 #define KAUTH_ACL_FLAGS_PRIVATE (0xffff)
639 
640 /*
641  * The high 16 bits of the flags are used to store attributes and
642  * to request specific handling of the ACL.
643  */
644 
645 /* inheritance will be deferred until the first rename operation */
646 #define KAUTH_ACL_DEFER_INHERIT (1<<16)
647 /* this ACL must not be overwritten as part of an inheritance operation */
648 #define KAUTH_ACL_NO_INHERIT    (1<<17)
649 
650 /* acl_entrycount that tells us the ACL is not valid */
651 #define KAUTH_FILESEC_NOACL ((u_int32_t)(-1))
652 
653 /*
654  * If the acl_entrycount field is KAUTH_FILESEC_NOACL, then the size is the
655  * same as a kauth_acl structure; the intent is to put an actual entrycount of
656  * KAUTH_FILESEC_NOACL on disk to distinguish a kauth_filesec_t with an empty
657  * entry (Windows treats this as "deny all") from one that merely indicates a
658  * file group and/or owner guid values.
659  */
660 #define KAUTH_ACL_SIZE(c)       (__offsetof(struct kauth_acl, acl_ace) + ((u_int32_t)(c) != KAUTH_FILESEC_NOACL ? ((c) * sizeof(struct kauth_ace)) : 0))
661 #define KAUTH_ACL_COPYSIZE(p)   KAUTH_ACL_SIZE((p)->acl_entrycount)
662 
663 
664 #ifndef _KAUTH_ACL
665 #define _KAUTH_ACL
666 typedef struct kauth_acl *kauth_acl_t;
667 #endif
668 
669 #ifdef KERNEL
670 kauth_acl_t     kauth_acl_alloc(int size);
671 void            kauth_acl_free(kauth_acl_t fsp);
672 #endif
673 
674 
675 /*
676  * Extended File Security.
677  */
678 
679 /* File Security information */
680 struct kauth_filesec {
681 	u_int32_t       fsec_magic;
682 #define KAUTH_FILESEC_MAGIC     0x012cc16d
683 	guid_t          fsec_owner;
684 	guid_t          fsec_group;
685 
686 	struct kauth_acl fsec_acl;
687 };
688 
689 /* backwards compatibility */
690 #define fsec_entrycount fsec_acl.acl_entrycount
691 #define fsec_flags      fsec_acl.acl_flags
692 #define fsec_ace        fsec_acl.acl_ace
693 #define KAUTH_FILESEC_FLAGS_PRIVATE     KAUTH_ACL_FLAGS_PRIVATE
694 #define KAUTH_FILESEC_DEFER_INHERIT     KAUTH_ACL_DEFER_INHERIT
695 #define KAUTH_FILESEC_NO_INHERIT        KAUTH_ACL_NO_INHERIT
696 #define KAUTH_FILESEC_NONE      ((kauth_filesec_t)0)
697 #define KAUTH_FILESEC_WANTED    ((kauth_filesec_t)1)
698 
699 #ifndef _KAUTH_FILESEC
700 #define _KAUTH_FILESEC
701 typedef struct kauth_filesec *kauth_filesec_t;
702 #endif
703 
704 #define KAUTH_FILESEC_SIZE(c)           (__offsetof(struct kauth_filesec, fsec_acl) + __offsetof(struct kauth_acl, acl_ace) + (c) * sizeof(struct kauth_ace))
705 #define KAUTH_FILESEC_COPYSIZE(p)       KAUTH_FILESEC_SIZE(((p)->fsec_entrycount == KAUTH_FILESEC_NOACL) ? 0 : (p)->fsec_entrycount)
706 #define KAUTH_FILESEC_COUNT(s)          (((s)  - KAUTH_FILESEC_SIZE(0)) / sizeof(struct kauth_ace))
707 #define KAUTH_FILESEC_VALID(s)          ((s) >= KAUTH_FILESEC_SIZE(0) && (((s) - KAUTH_FILESEC_SIZE(0)) % sizeof(struct kauth_ace)) == 0)
708 
709 #define KAUTH_FILESEC_XATTR     "com.apple.system.Security"
710 
711 /* Allowable first arguments to kauth_filesec_acl_setendian() */
712 #define KAUTH_ENDIAN_HOST       0x00000001      /* set host endianness */
713 #define KAUTH_ENDIAN_DISK       0x00000002      /* set disk endianness */
714 
715 #endif /* KERNEL || <sys/acl.h> */
716 #ifdef KERNEL
717 #pragma mark kauth: Scope management
718 
719 struct kauth_scope;
720 typedef struct kauth_scope *kauth_scope_t;
721 struct kauth_listener;
722 typedef struct kauth_listener *kauth_listener_t;
723 #ifndef _KAUTH_ACTION_T
724 typedef int kauth_action_t;
725 # define _KAUTH_ACTION_T
726 #endif
727 
728 typedef int (* kauth_scope_callback_t)(kauth_cred_t _credential,
729     void *_idata,
730     kauth_action_t _action,
731     uintptr_t _arg0,
732     uintptr_t _arg1,
733     uintptr_t _arg2,
734     uintptr_t _arg3);
735 
736 #define KAUTH_RESULT_ALLOW      (1)
737 #define KAUTH_RESULT_DENY       (2)
738 #define KAUTH_RESULT_DEFER      (3)
739 
740 struct kauth_acl_eval {
741 	kauth_ace_t             ae_acl;
742 	int                     ae_count;
743 	kauth_ace_rights_t      ae_requested;
744 	kauth_ace_rights_t      ae_residual;
745 	int                     ae_result;
746 	boolean_t               ae_found_deny;
747 	int                     ae_options;
748 #define KAUTH_AEVAL_IS_OWNER    (1<<0)          /* authorizing operation for owner */
749 #define KAUTH_AEVAL_IN_GROUP    (1<<1)          /* authorizing operation for groupmember */
750 #define KAUTH_AEVAL_IN_GROUP_UNKNOWN    (1<<2)          /* authorizing operation for unknown group membership */
751 	/* expansions for 'generic' rights bits */
752 	kauth_ace_rights_t      ae_exp_gall;
753 	kauth_ace_rights_t      ae_exp_gread;
754 	kauth_ace_rights_t      ae_exp_gwrite;
755 	kauth_ace_rights_t      ae_exp_gexec;
756 };
757 
758 typedef struct kauth_acl_eval *kauth_acl_eval_t;
759 
760 kauth_filesec_t kauth_filesec_alloc(int size);
761 void            kauth_filesec_free(kauth_filesec_t fsp);
762 extern kauth_scope_t kauth_register_scope(const char *_identifier, kauth_scope_callback_t _callback, void *_idata);
763 extern void     kauth_deregister_scope(kauth_scope_t _scope);
764 __kpi_deprecated("Use EndpointSecurity instead")
765 extern kauth_listener_t kauth_listen_scope(const char *_identifier, kauth_scope_callback_t _callback, void *_idata);
766 __kpi_deprecated("Use EndpointSecurity instead")
767 extern void     kauth_unlisten_scope(kauth_listener_t _scope);
768 extern int      kauth_authorize_action(kauth_scope_t _scope, kauth_cred_t _credential, kauth_action_t _action,
769     uintptr_t _arg0, uintptr_t _arg1, uintptr_t _arg2, uintptr_t _arg3);
770 
771 /*
772  * Generic scope.
773  */
774 #define KAUTH_SCOPE_GENERIC     "com.apple.kauth.generic"
775 
776 /* Actions */
777 #define KAUTH_GENERIC_ISSUSER                   1
778 
779 /*
780  * Process/task scope.
781  */
782 #define KAUTH_SCOPE_PROCESS     "com.apple.kauth.process"
783 
784 /* Actions */
785 #define KAUTH_PROCESS_CANSIGNAL                 1
786 #define KAUTH_PROCESS_CANTRACE                  2
787 
788 extern int      kauth_authorize_process(kauth_cred_t _credential, kauth_action_t _action,
789     struct proc *_process, uintptr_t _arg1, uintptr_t _arg2, uintptr_t _arg3);
790 
791 /*
792  * Vnode operation scope.
793  *
794  * Prototype for vnode_authorize is in vnode.h
795  */
796 #define KAUTH_SCOPE_VNODE       "com.apple.kauth.vnode"
797 
798 /*
799  * File system operation scope.
800  *
801  */
802 #define KAUTH_SCOPE_FILEOP      "com.apple.kauth.fileop"
803 
804 /* Actions */
805 #define KAUTH_FILEOP_OPEN                       1
806 #define KAUTH_FILEOP_CLOSE                      2
807 #define KAUTH_FILEOP_RENAME                     3
808 #define KAUTH_FILEOP_EXCHANGE                   4
809 #define KAUTH_FILEOP_LINK                       5
810 #define KAUTH_FILEOP_EXEC                       6
811 #define KAUTH_FILEOP_DELETE                     7
812 #define KAUTH_FILEOP_WILL_RENAME                8
813 
814 /*
815  * arguments passed to KAUTH_FILEOP_OPEN listeners
816  *		arg0 is pointer to vnode (vnode *) for given user path.
817  *		arg1 is pointer to path (char *) passed in to open.
818  * arguments passed to KAUTH_FILEOP_CLOSE listeners
819  *		arg0 is pointer to vnode (vnode *) for file to be closed.
820  *		arg1 is pointer to path (char *) of file to be closed.
821  *		arg2 is close flags.
822  * arguments passed to KAUTH_FILEOP_WILL_RENAME listeners
823  *		arg0 is pointer to vnode (vnode *) of the file being renamed
824  *		arg1 is pointer to the "from" path (char *)
825  *		arg2 is pointer to the "to" path (char *)
826  * arguments passed to KAUTH_FILEOP_RENAME listeners
827  *		arg0 is pointer to "from" path (char *).
828  *		arg1 is pointer to "to" path (char *).
829  * arguments passed to KAUTH_FILEOP_EXCHANGE listeners
830  *		arg0 is pointer to file 1 path (char *).
831  *		arg1 is pointer to file 2 path (char *).
832  * arguments passed to KAUTH_FILEOP_LINK listeners
833  *		arg0 is pointer to path to file we are linking to (char *).
834  *		arg1 is pointer to path to the new link file (char *).
835  * arguments passed to KAUTH_FILEOP_EXEC listeners
836  *		arg0 is pointer to vnode (vnode *) for executable.
837  *		arg1 is pointer to path (char *) to executable.
838  * arguments passed to KAUTH_FILEOP_DELETE listeners
839  *		arg0 is pointer to vnode (vnode *) of file/dir that was deleted.
840  *		arg1 is pointer to path (char *) of file/dir that was deleted.
841  */
842 
843 /* Flag values returned to close listeners. */
844 #define KAUTH_FILEOP_CLOSE_MODIFIED                     (1<<1)
845 
846 /* GUID, NTSID helpers */
847 extern guid_t   kauth_null_guid;
848 extern int      kauth_guid_equal(guid_t *_guid1, guid_t *_guid2);
849 
850 #ifdef KERNEL_PRIVATE
851 
852 extern int      kauth_acl_evaluate(kauth_cred_t _credential, kauth_acl_eval_t _eval);
853 
854 #endif /* KERNEL_PRIVATE */
855 #ifdef XNU_KERNEL_PRIVATE
856 #pragma mark kauth: XNU only
857 #pragma GCC visibility push(hidden)
858 
859 void            kauth_filesec_acl_setendian(int, kauth_filesec_t, kauth_acl_t);
860 int             kauth_copyinfilesec(user_addr_t xsecurity, kauth_filesec_t *xsecdestpp);
861 extern int      kauth_acl_inherit(vnode_t _dvp, kauth_acl_t _initial, kauth_acl_t *_product, int _isdir, vfs_context_t _ctx);
862 
863 extern int      kauth_authorize_allow(kauth_cred_t _credential, void *_idata, kauth_action_t _action,
864     uintptr_t _arg0, uintptr_t _arg1, uintptr_t _arg2, uintptr_t _arg3);
865 
866 extern int      kauth_authorize_generic(kauth_cred_t credential, kauth_action_t action);
867 
868 extern int      kauth_authorize_fileop_has_listeners(void);
869 
870 extern int      kauth_authorize_fileop(kauth_cred_t _credential, kauth_action_t _action,
871     uintptr_t _arg0, uintptr_t _arg1);
872 
873 extern int      kauth_ntsid_equal(ntsid_t *_sid1, ntsid_t *_sid2);
874 
875 extern int      kauth_wellknown_guid(guid_t *_guid);
876 #define KAUTH_WKG_NOT           0       /* not a well-known GUID */
877 #define KAUTH_WKG_OWNER         1
878 #define KAUTH_WKG_GROUP         2
879 #define KAUTH_WKG_NOBODY        3
880 #define KAUTH_WKG_EVERYBODY     4
881 
882 #pragma GCC visibility pop
883 #endif /* XNU_KERNEL_PRIVATE */
884 #endif /* KERNEL */
885 
886 /* Actions, also rights bits in an ACE */
887 
888 #if defined(KERNEL) || defined (_SYS_ACL_H)
889 #define KAUTH_VNODE_READ_DATA                   (1U<<1)
890 #define KAUTH_VNODE_LIST_DIRECTORY              KAUTH_VNODE_READ_DATA
891 #define KAUTH_VNODE_WRITE_DATA                  (1U<<2)
892 #define KAUTH_VNODE_ADD_FILE                    KAUTH_VNODE_WRITE_DATA
893 #define KAUTH_VNODE_EXECUTE                     (1U<<3)
894 #define KAUTH_VNODE_SEARCH                      KAUTH_VNODE_EXECUTE
895 #define KAUTH_VNODE_DELETE                      (1U<<4)
896 #define KAUTH_VNODE_APPEND_DATA                 (1U<<5)
897 #define KAUTH_VNODE_ADD_SUBDIRECTORY            KAUTH_VNODE_APPEND_DATA
898 #define KAUTH_VNODE_DELETE_CHILD                (1U<<6)
899 #define KAUTH_VNODE_READ_ATTRIBUTES             (1U<<7)
900 #define KAUTH_VNODE_WRITE_ATTRIBUTES            (1U<<8)
901 #define KAUTH_VNODE_READ_EXTATTRIBUTES          (1U<<9)
902 #define KAUTH_VNODE_WRITE_EXTATTRIBUTES         (1U<<10)
903 #define KAUTH_VNODE_READ_SECURITY               (1U<<11)
904 #define KAUTH_VNODE_WRITE_SECURITY              (1U<<12)
905 #define KAUTH_VNODE_TAKE_OWNERSHIP              (1U<<13)
906 
907 /* backwards compatibility only */
908 #define KAUTH_VNODE_CHANGE_OWNER                KAUTH_VNODE_TAKE_OWNERSHIP
909 
910 /* For Windows interoperability only */
911 #define KAUTH_VNODE_SYNCHRONIZE                 (1U<<20)
912 
913 /* (1<<21) - (1<<24) are reserved for generic rights bits */
914 
915 /* Actions not expressed as rights bits */
916 /*
917  * Authorizes the vnode as the target of a hard link.
918  */
919 #define KAUTH_VNODE_LINKTARGET                  (1U<<25)
920 
921 /*
922  * Indicates that other steps have been taken to authorise the action,
923  * but authorisation should be denied for immutable objects.
924  */
925 #define KAUTH_VNODE_CHECKIMMUTABLE              (1U<<26)
926 
927 /* Action modifiers */
928 /*
929  * The KAUTH_VNODE_ACCESS bit is passed to the callback if the authorisation
930  * request in progress is advisory, rather than authoritative.  Listeners
931  * performing consequential work (i.e. not strictly checking authorisation)
932  * may test this flag to avoid performing unnecessary work.
933  *
934  * This bit will never be present in an ACE.
935  */
936 #define KAUTH_VNODE_ACCESS                      (1U<<31)
937 
938 /*
939  * The KAUTH_VNODE_NOIMMUTABLE bit is passed to the callback along with the
940  * KAUTH_VNODE_WRITE_SECURITY bit (and no others) to indicate that the
941  * caller wishes to change one or more of the immutable flags, and the
942  * state of these flags should not be considered when authorizing the request.
943  * The system immutable flags are only ignored when the system securelevel
944  * is low enough to allow their removal.
945  */
946 #define KAUTH_VNODE_NOIMMUTABLE                 (1U<<30)
947 
948 
949 /*
950  * fake right that is composed by the following...
951  * vnode must have search for owner, group and world allowed
952  * plus there must be no deny modes present for SEARCH... this fake
953  * right is used by the fast lookup path to avoid checking
954  * for an exact match on the last credential to lookup
955  * the component being acted on
956  */
957 #define KAUTH_VNODE_SEARCHBYANYONE              (1U<<29)
958 
959 
960 /*
961  * when passed as an 'action' to "vnode_uncache_authorized_actions"
962  * it indicates that all of the cached authorizations for that
963  * vnode should be invalidated
964  */
965 #define KAUTH_INVALIDATE_CACHED_RIGHTS          ((kauth_action_t)~0)
966 
967 
968 
969 /* The expansions of the GENERIC bits at evaluation time */
970 #define KAUTH_VNODE_GENERIC_READ_BITS   (KAUTH_VNODE_READ_DATA |                \
971 	                                KAUTH_VNODE_READ_ATTRIBUTES |           \
972 	                                KAUTH_VNODE_READ_EXTATTRIBUTES |        \
973 	                                KAUTH_VNODE_READ_SECURITY)
974 
975 #define KAUTH_VNODE_GENERIC_WRITE_BITS  (KAUTH_VNODE_WRITE_DATA |               \
976 	                                KAUTH_VNODE_APPEND_DATA |               \
977 	                                KAUTH_VNODE_DELETE |                    \
978 	                                KAUTH_VNODE_DELETE_CHILD |              \
979 	                                KAUTH_VNODE_WRITE_ATTRIBUTES |          \
980 	                                KAUTH_VNODE_WRITE_EXTATTRIBUTES |       \
981 	                                KAUTH_VNODE_WRITE_SECURITY)
982 
983 #define KAUTH_VNODE_GENERIC_EXECUTE_BITS (KAUTH_VNODE_EXECUTE)
984 
985 #define KAUTH_VNODE_GENERIC_ALL_BITS    (KAUTH_VNODE_GENERIC_READ_BITS |        \
986 	                                KAUTH_VNODE_GENERIC_WRITE_BITS |        \
987 	                                KAUTH_VNODE_GENERIC_EXECUTE_BITS)
988 
989 /*
990  * Some sets of bits, defined here for convenience.
991  */
992 #define KAUTH_VNODE_WRITE_RIGHTS        (KAUTH_VNODE_ADD_FILE |                         \
993 	                                KAUTH_VNODE_ADD_SUBDIRECTORY |                  \
994 	                                KAUTH_VNODE_DELETE_CHILD |                      \
995 	                                KAUTH_VNODE_WRITE_DATA |                        \
996 	                                KAUTH_VNODE_APPEND_DATA |                       \
997 	                                KAUTH_VNODE_DELETE |                            \
998 	                                KAUTH_VNODE_WRITE_ATTRIBUTES |                  \
999 	                                KAUTH_VNODE_WRITE_EXTATTRIBUTES |               \
1000 	                                KAUTH_VNODE_WRITE_SECURITY |                    \
1001 	                                KAUTH_VNODE_TAKE_OWNERSHIP |                    \
1002 	                                KAUTH_VNODE_LINKTARGET |                        \
1003 	                                KAUTH_VNODE_CHECKIMMUTABLE)
1004 
1005 
1006 #endif /* KERNEL || <sys/acl.h> */
1007 
1008 #ifdef KERNEL
1009 /*
1010  * Debugging
1011  *
1012  * XXX this wouldn't be necessary if we had a *real* debug-logging system.
1013  */
1014 #if 0
1015 # ifndef _FN_KPRINTF
1016 #  define       _FN_KPRINTF
1017 void kprintf(const char *fmt, ...) __printflike(1, 2);
1018 # endif /* !_FN_KPRINTF */
1019 # define KAUTH_DEBUG_ENABLE
1020 # define K_UUID_FMT "%08x:%08x:%08x:%08x"
1021 # define K_UUID_ARG(_u) &_u.g_guid_asint[0],&_u.g_guid_asint[1],&_u.g_guid_asint[2],&_u.g_guid_asint[3]
1022 # define KAUTH_DEBUG(fmt, args...)      do { kprintf("%s:%d: " fmt "\n", __PRETTY_FUNCTION__, __LINE__ , ##args); } while (0)
1023 # define KAUTH_DEBUG_CTX(_c)            KAUTH_DEBUG("p = %p c = %p", _c->vc_proc, _c->vc_ucred)
1024 # define VFS_DEBUG(_ctx, _vp, fmt, args...)                                             \
1025 	do {                                                                            \
1026 	        kprintf("%p '%s' %s:%d " fmt "\n",                                      \
1027 	            _ctx,                                                               \
1028 	            (_vp != NULL && _vp->v_name != NULL) ? _vp->v_name : "????",        \
1029 	            __PRETTY_FUNCTION__, __LINE__ ,                                     \
1030 	            ##args);                                                            \
1031 	} while(0)
1032 #else   /* !0 */
1033 # define KAUTH_DEBUG(fmt, args...)              do { } while (0)
1034 # define VFS_DEBUG(ctx, vp, fmt, args...)       do { } while(0)
1035 #endif  /* !0 */
1036 #endif  /* KERNEL */
1037 
1038 #endif /* __APPLE_API_EVOLVING */
1039 
1040 __END_DECLS
1041 
1042 #endif /* _SYS_KAUTH_H */
1043