FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_auth.c
1 /* $NetBSD: kern_auth.c,v 1.32.2.4 2007/01/07 10:51:15 bouyer Exp $ */
2
3 /*-
4 * Copyright (c) 2005, 2006 Elad Efrat <elad@NetBSD.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Elad Efrat.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: kern_auth.c,v 1.32.2.4 2007/01/07 10:51:15 bouyer Exp $");
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/queue.h>
39 #include <sys/time.h>
40 #include <sys/proc.h>
41 #include <sys/ucred.h>
42 #include <sys/pool.h>
43 #include <sys/kauth.h>
44 #include <sys/acct.h>
45 #include <sys/sysctl.h>
46 #include <sys/kmem.h>
47
48 /*
49 * Credentials.
50 */
51 struct kauth_cred {
52 struct simplelock cr_lock; /* lock on cr_refcnt */
53 u_int cr_refcnt; /* reference count */
54 uid_t cr_uid; /* user id */
55 uid_t cr_euid; /* effective user id */
56 uid_t cr_svuid; /* saved effective user id */
57 gid_t cr_gid; /* group id */
58 gid_t cr_egid; /* effective group id */
59 gid_t cr_svgid; /* saved effective group id */
60 u_int cr_ngroups; /* number of groups */
61 gid_t cr_groups[NGROUPS]; /* group memberships */
62 };
63
64 /*
65 * Listener.
66 */
67 struct kauth_listener {
68 kauth_scope_callback_t func; /* callback */
69 kauth_scope_t scope; /* scope backpointer */
70 u_int refcnt; /* reference count */
71 SIMPLEQ_ENTRY(kauth_listener) listener_next; /* listener list */
72 };
73
74 /*
75 * Scope.
76 */
77 struct kauth_scope {
78 const char *id; /* scope name */
79 void *cookie; /* user cookie */
80 u_int nlisteners; /* # of listeners */
81 SIMPLEQ_HEAD(, kauth_listener) listenq; /* listener list */
82 SIMPLEQ_ENTRY(kauth_scope) next_scope; /* scope list */
83 };
84
85 static POOL_INIT(kauth_cred_pool, sizeof(struct kauth_cred), 0, 0, 0,
86 "kauthcredpl", &pool_allocator_nointr);
87
88 /* List of scopes and its lock. */
89 static SIMPLEQ_HEAD(, kauth_scope) scope_list;
90 static struct simplelock scopes_lock;
91
92 /* Built-in scopes: generic, process. */
93 static kauth_scope_t kauth_builtin_scope_generic;
94 static kauth_scope_t kauth_builtin_scope_system;
95 static kauth_scope_t kauth_builtin_scope_process;
96 static kauth_scope_t kauth_builtin_scope_network;
97 static kauth_scope_t kauth_builtin_scope_machdep;
98 static kauth_scope_t kauth_builtin_scope_device;
99
100 static boolean_t listeners_have_been_loaded = FALSE;
101
102 /* Allocate new, empty kauth credentials. */
103 kauth_cred_t
104 kauth_cred_alloc(void)
105 {
106 kauth_cred_t cred;
107
108 cred = pool_get(&kauth_cred_pool, PR_WAITOK);
109 memset(cred, 0, sizeof(*cred));
110 simple_lock_init(&cred->cr_lock);
111 cred->cr_refcnt = 1;
112
113 return (cred);
114 }
115
116 /* Increment reference count to cred. */
117 void
118 kauth_cred_hold(kauth_cred_t cred)
119 {
120 KASSERT(cred != NULL);
121 KASSERT(cred->cr_refcnt > 0);
122
123 simple_lock(&cred->cr_lock);
124 cred->cr_refcnt++;
125 simple_unlock(&cred->cr_lock);
126 }
127
128 /* Decrease reference count to cred. If reached zero, free it. */
129 void
130 kauth_cred_free(kauth_cred_t cred)
131 {
132 u_int refcnt;
133
134 KASSERT(cred != NULL);
135 KASSERT(cred->cr_refcnt > 0);
136
137 simple_lock(&cred->cr_lock);
138 refcnt = --cred->cr_refcnt;
139 simple_unlock(&cred->cr_lock);
140
141 if (refcnt == 0)
142 pool_put(&kauth_cred_pool, cred);
143 }
144
145 void
146 kauth_cred_clone(kauth_cred_t from, kauth_cred_t to)
147 {
148 KASSERT(from != NULL);
149 KASSERT(to != NULL);
150 KASSERT(from->cr_refcnt > 0);
151
152 to->cr_uid = from->cr_uid;
153 to->cr_euid = from->cr_euid;
154 to->cr_svuid = from->cr_svuid;
155 to->cr_gid = from->cr_gid;
156 to->cr_egid = from->cr_egid;
157 to->cr_svgid = from->cr_svgid;
158 to->cr_ngroups = from->cr_ngroups;
159 memcpy(to->cr_groups, from->cr_groups, sizeof(to->cr_groups));
160 }
161
162 /*
163 * Duplicate cred and return a new kauth_cred_t.
164 */
165 kauth_cred_t
166 kauth_cred_dup(kauth_cred_t cred)
167 {
168 kauth_cred_t new_cred;
169
170 KASSERT(cred != NULL);
171 KASSERT(cred->cr_refcnt > 0);
172
173 new_cred = kauth_cred_alloc();
174
175 kauth_cred_clone(cred, new_cred);
176
177 return (new_cred);
178 }
179
180 /*
181 * Similar to crcopy(), only on a kauth_cred_t.
182 * XXX: Is this even needed? [kauth_cred_copy]
183 */
184 kauth_cred_t
185 kauth_cred_copy(kauth_cred_t cred)
186 {
187 kauth_cred_t new_cred;
188
189 KASSERT(cred != NULL);
190 KASSERT(cred->cr_refcnt > 0);
191
192 /* If the provided credentials already have one reference, use them. */
193 if (cred->cr_refcnt == 1)
194 return (cred);
195
196 new_cred = kauth_cred_alloc();
197
198 kauth_cred_clone(cred, new_cred);
199
200 kauth_cred_free(cred);
201
202 return (new_cred);
203 }
204
205 uid_t
206 kauth_cred_getuid(kauth_cred_t cred)
207 {
208 KASSERT(cred != NULL);
209
210 return (cred->cr_uid);
211 }
212
213 uid_t
214 kauth_cred_geteuid(kauth_cred_t cred)
215 {
216 KASSERT(cred != NULL);
217
218 return (cred->cr_euid);
219 }
220
221 uid_t
222 kauth_cred_getsvuid(kauth_cred_t cred)
223 {
224 KASSERT(cred != NULL);
225
226 return (cred->cr_svuid);
227 }
228
229 gid_t
230 kauth_cred_getgid(kauth_cred_t cred)
231 {
232 KASSERT(cred != NULL);
233
234 return (cred->cr_gid);
235 }
236
237 gid_t
238 kauth_cred_getegid(kauth_cred_t cred)
239 {
240 KASSERT(cred != NULL);
241
242 return (cred->cr_egid);
243 }
244
245 gid_t
246 kauth_cred_getsvgid(kauth_cred_t cred)
247 {
248 KASSERT(cred != NULL);
249
250 return (cred->cr_svgid);
251 }
252
253 void
254 kauth_cred_setuid(kauth_cred_t cred, uid_t uid)
255 {
256 KASSERT(cred != NULL);
257 KASSERT(cred->cr_refcnt == 1);
258
259 cred->cr_uid = uid;
260 }
261
262 void
263 kauth_cred_seteuid(kauth_cred_t cred, uid_t uid)
264 {
265 KASSERT(cred != NULL);
266 KASSERT(cred->cr_refcnt == 1);
267
268 cred->cr_euid = uid;
269 }
270
271 void
272 kauth_cred_setsvuid(kauth_cred_t cred, uid_t uid)
273 {
274 KASSERT(cred != NULL);
275 KASSERT(cred->cr_refcnt == 1);
276
277 cred->cr_svuid = uid;
278 }
279
280 void
281 kauth_cred_setgid(kauth_cred_t cred, gid_t gid)
282 {
283 KASSERT(cred != NULL);
284 KASSERT(cred->cr_refcnt == 1);
285
286 cred->cr_gid = gid;
287 }
288
289 void
290 kauth_cred_setegid(kauth_cred_t cred, gid_t gid)
291 {
292 KASSERT(cred != NULL);
293 KASSERT(cred->cr_refcnt == 1);
294
295 cred->cr_egid = gid;
296 }
297
298 void
299 kauth_cred_setsvgid(kauth_cred_t cred, gid_t gid)
300 {
301 KASSERT(cred != NULL);
302 KASSERT(cred->cr_refcnt == 1);
303
304 cred->cr_svgid = gid;
305 }
306
307 /* Checks if gid is a member of the groups in cred. */
308 int
309 kauth_cred_ismember_gid(kauth_cred_t cred, gid_t gid, int *resultp)
310 {
311 int i;
312
313 KASSERT(cred != NULL);
314 KASSERT(resultp != NULL);
315
316 *resultp = 0;
317
318 for (i = 0; i < cred->cr_ngroups; i++)
319 if (cred->cr_groups[i] == gid) {
320 *resultp = 1;
321 break;
322 }
323
324 return (0);
325 }
326
327 u_int
328 kauth_cred_ngroups(kauth_cred_t cred)
329 {
330 KASSERT(cred != NULL);
331
332 return (cred->cr_ngroups);
333 }
334
335 /*
336 * Return the group at index idx from the groups in cred.
337 */
338 gid_t
339 kauth_cred_group(kauth_cred_t cred, u_int idx)
340 {
341 KASSERT(cred != NULL);
342 KASSERT(idx < cred->cr_ngroups);
343
344 return (cred->cr_groups[idx]);
345 }
346
347 /* XXX elad: gmuid is unused for now. */
348 int
349 kauth_cred_setgroups(kauth_cred_t cred, gid_t *grbuf, size_t len, uid_t gmuid)
350 {
351 KASSERT(cred != NULL);
352 KASSERT(cred->cr_refcnt == 1);
353 KASSERT(len <= sizeof(cred->cr_groups) / sizeof(cred->cr_groups[0]));
354
355 if (len)
356 memcpy(cred->cr_groups, grbuf, len * sizeof(cred->cr_groups[0]));
357 memset(cred->cr_groups + len, 0xff,
358 sizeof(cred->cr_groups) - (len * sizeof(cred->cr_groups[0])));
359
360 cred->cr_ngroups = len;
361
362 return (0);
363 }
364
365 int
366 kauth_cred_getgroups(kauth_cred_t cred, gid_t *grbuf, size_t len)
367 {
368 KASSERT(cred != NULL);
369 KASSERT(len <= cred->cr_ngroups);
370
371 memset(grbuf, 0xff, sizeof(*grbuf) * len);
372 memcpy(grbuf, cred->cr_groups, sizeof(*grbuf) * len);
373
374 return (0);
375 }
376
377 /*
378 * Match uids in two credentials.
379 */
380 int
381 kauth_cred_uidmatch(kauth_cred_t cred1, kauth_cred_t cred2)
382 {
383 KASSERT(cred1 != NULL);
384 KASSERT(cred2 != NULL);
385
386 if (cred1->cr_uid == cred2->cr_uid ||
387 cred1->cr_euid == cred2->cr_uid ||
388 cred1->cr_uid == cred2->cr_euid ||
389 cred1->cr_euid == cred2->cr_euid)
390 return (1);
391
392 return (0);
393 }
394
395 u_int
396 kauth_cred_getrefcnt(kauth_cred_t cred)
397 {
398 KASSERT(cred != NULL);
399
400 return (cred->cr_refcnt);
401 }
402
403 /*
404 * Convert userland credentials (struct uucred) to kauth_cred_t.
405 * XXX: For NFS & puffs
406 */
407 void
408 kauth_uucred_to_cred(kauth_cred_t cred, const struct uucred *uuc)
409 {
410 KASSERT(cred != NULL);
411 KASSERT(uuc != NULL);
412
413 cred->cr_refcnt = 1;
414 cred->cr_uid = uuc->cr_uid;
415 cred->cr_euid = uuc->cr_uid;
416 cred->cr_svuid = uuc->cr_uid;
417 cred->cr_gid = uuc->cr_gid;
418 cred->cr_egid = uuc->cr_gid;
419 cred->cr_svgid = uuc->cr_gid;
420 cred->cr_ngroups = min(uuc->cr_ngroups, NGROUPS);
421 kauth_cred_setgroups(cred, __UNCONST(uuc->cr_groups),
422 cred->cr_ngroups, -1);
423 }
424
425 /*
426 * Convert kauth_cred_t to userland credentials (struct uucred).
427 * XXX: For NFS & puffs
428 */
429 void
430 kauth_cred_to_uucred(struct uucred *uuc, const kauth_cred_t cred)
431 {
432 KASSERT(cred != NULL);
433 KASSERT(uuc != NULL);
434 int ng;
435
436 ng = min(cred->cr_ngroups, NGROUPS);
437 uuc->cr_uid = cred->cr_euid;
438 uuc->cr_gid = cred->cr_egid;
439 uuc->cr_ngroups = ng;
440 kauth_cred_getgroups(cred, uuc->cr_groups, ng);
441 }
442
443 /*
444 * Compare kauth_cred_t and uucred credentials.
445 * XXX: Modelled after crcmp() for NFS.
446 */
447 int
448 kauth_cred_uucmp(kauth_cred_t cred, const struct uucred *uuc)
449 {
450 KASSERT(cred != NULL);
451 KASSERT(uuc != NULL);
452
453 if (cred->cr_euid == uuc->cr_uid &&
454 cred->cr_egid == uuc->cr_gid &&
455 cred->cr_ngroups == uuc->cr_ngroups) {
456 int i;
457
458 /* Check if all groups from uuc appear in cred. */
459 for (i = 0; i < uuc->cr_ngroups; i++) {
460 int ismember;
461
462 ismember = 0;
463 if (kauth_cred_ismember_gid(cred, uuc->cr_groups[i],
464 &ismember) != 0 || !ismember)
465 return (1);
466 }
467
468 return (0);
469 }
470
471 return (1);
472 }
473
474 /*
475 * Make a struct ucred out of a kauth_cred_t. For compatibility.
476 */
477 void
478 kauth_cred_toucred(kauth_cred_t cred, struct ucred *uc)
479 {
480 KASSERT(cred != NULL);
481 KASSERT(uc != NULL);
482
483 uc->cr_ref = cred->cr_refcnt;
484 uc->cr_uid = cred->cr_euid;
485 uc->cr_gid = cred->cr_egid;
486 uc->cr_ngroups = min(cred->cr_ngroups,
487 sizeof(uc->cr_groups) / sizeof(uc->cr_groups[0]));
488 memcpy(uc->cr_groups, cred->cr_groups,
489 uc->cr_ngroups * sizeof(uc->cr_groups[0]));
490 }
491
492 /*
493 * Make a struct pcred out of a kauth_cred_t. For compatibility.
494 */
495 void
496 kauth_cred_topcred(kauth_cred_t cred, struct pcred *pc)
497 {
498 KASSERT(cred != NULL);
499 KASSERT(pc != NULL);
500
501 pc->pc_ucred = NULL;
502 pc->p_ruid = cred->cr_uid;
503 pc->p_svuid = cred->cr_svuid;
504 pc->p_rgid = cred->cr_gid;
505 pc->p_svgid = cred->cr_svgid;
506 pc->p_refcnt = cred->cr_refcnt;
507 }
508
509 /*
510 * Return kauth_cred_t for the current LWP.
511 */
512 kauth_cred_t
513 kauth_cred_get(void)
514 {
515 return (curlwp->l_cred);
516 }
517
518 /*
519 * Returns a scope matching the provided id.
520 * Requires the scope list lock to be held by the caller.
521 */
522 static kauth_scope_t
523 kauth_ifindscope(const char *id)
524 {
525 kauth_scope_t scope;
526
527 /* XXX: assert lock on scope list? */
528
529 scope = NULL;
530 SIMPLEQ_FOREACH(scope, &scope_list, next_scope) {
531 if (strcmp(scope->id, id) == 0)
532 break;
533 }
534
535 return (scope);
536 }
537
538 /*
539 * Register a new scope.
540 *
541 * id - identifier for the scope
542 * callback - the scope's default listener
543 * cookie - cookie to be passed to the listener(s)
544 */
545 kauth_scope_t
546 kauth_register_scope(const char *id, kauth_scope_callback_t callback,
547 void *cookie)
548 {
549 kauth_scope_t scope;
550 kauth_listener_t listener = NULL; /* XXX gcc */
551
552 /* Sanitize input */
553 if (id == NULL)
554 return (NULL);
555
556 /* Allocate space for a new scope and listener. */
557 scope = kmem_alloc(sizeof(*scope), KM_SLEEP);
558 if (scope == NULL)
559 return NULL;
560 if (callback != NULL) {
561 listener = kmem_alloc(sizeof(*listener), KM_SLEEP);
562 if (listener == NULL) {
563 kmem_free(scope, sizeof(*scope));
564 return (NULL);
565 }
566 }
567
568 /*
569 * Acquire scope list lock.
570 *
571 * XXXSMP insufficient locking.
572 */
573 simple_lock(&scopes_lock);
574
575 /* Check we don't already have a scope with the same id */
576 if (kauth_ifindscope(id) != NULL) {
577 simple_unlock(&scopes_lock);
578
579 kmem_free(scope, sizeof(*scope));
580 if (callback != NULL)
581 kmem_free(listener, sizeof(*listener));
582
583 return (NULL);
584 }
585
586 /* Initialize new scope with parameters */
587 scope->id = id;
588 scope->cookie = cookie;
589 scope->nlisteners = 1;
590
591 SIMPLEQ_INIT(&scope->listenq);
592
593 /* Add default listener */
594 if (callback != NULL) {
595 listener->func = callback;
596 listener->scope = scope;
597 listener->refcnt = 0;
598 SIMPLEQ_INSERT_HEAD(&scope->listenq, listener, listener_next);
599 }
600
601 /* Insert scope to scopes list */
602 SIMPLEQ_INSERT_TAIL(&scope_list, scope, next_scope);
603
604 simple_unlock(&scopes_lock);
605
606 return (scope);
607 }
608
609 /*
610 * Initialize the kernel authorization subsystem.
611 *
612 * Initialize the scopes list lock.
613 * Register built-in scopes: generic, process.
614 */
615 void
616 kauth_init(void)
617 {
618 SIMPLEQ_INIT(&scope_list);
619 simple_lock_init(&scopes_lock);
620
621 /* Register generic scope. */
622 kauth_builtin_scope_generic = kauth_register_scope(KAUTH_SCOPE_GENERIC,
623 NULL, NULL);
624
625 /* Register system scope. */
626 kauth_builtin_scope_system = kauth_register_scope(KAUTH_SCOPE_SYSTEM,
627 NULL, NULL);
628
629 /* Register process scope. */
630 kauth_builtin_scope_process = kauth_register_scope(KAUTH_SCOPE_PROCESS,
631 NULL, NULL);
632
633 /* Register network scope. */
634 kauth_builtin_scope_network = kauth_register_scope(KAUTH_SCOPE_NETWORK,
635 NULL, NULL);
636
637 /* Register machdep scope. */
638 kauth_builtin_scope_machdep = kauth_register_scope(KAUTH_SCOPE_MACHDEP,
639 NULL, NULL);
640
641 /* Register device scope. */
642 kauth_builtin_scope_device = kauth_register_scope(KAUTH_SCOPE_DEVICE,
643 NULL, NULL);
644 }
645
646 /*
647 * Deregister a scope.
648 * Requires scope list lock to be held by the caller.
649 *
650 * scope - the scope to deregister
651 */
652 void
653 kauth_deregister_scope(kauth_scope_t scope)
654 {
655 if (scope != NULL) {
656 /* Remove scope from list */
657 SIMPLEQ_REMOVE(&scope_list, scope, kauth_scope, next_scope);
658 kmem_free(scope, sizeof(*scope));
659 }
660 }
661
662 /*
663 * Register a listener.
664 *
665 * id - scope identifier.
666 * callback - the callback routine for the listener.
667 * cookie - cookie to pass unmoidfied to the callback.
668 */
669 kauth_listener_t
670 kauth_listen_scope(const char *id, kauth_scope_callback_t callback,
671 void *cookie)
672 {
673 kauth_scope_t scope;
674 kauth_listener_t listener;
675
676 /*
677 * Find scope struct.
678 *
679 * XXXSMP insufficient locking.
680 */
681 simple_lock(&scopes_lock);
682 scope = kauth_ifindscope(id);
683 simple_unlock(&scopes_lock);
684 if (scope == NULL)
685 return (NULL);
686
687 /* Allocate listener */
688 listener = kmem_alloc(sizeof(*listener), KM_SLEEP);
689 if (listener == NULL)
690 return (NULL);
691
692 /* Initialize listener with parameters */
693 listener->func = callback;
694 listener->refcnt = 0;
695
696 /* Add listener to scope */
697 SIMPLEQ_INSERT_TAIL(&scope->listenq, listener, listener_next);
698
699 /* Raise number of listeners on scope. */
700 scope->nlisteners++;
701 listener->scope = scope;
702
703 listeners_have_been_loaded = TRUE;
704
705 return (listener);
706 }
707
708 /*
709 * Deregister a listener.
710 *
711 * listener - listener reference as returned from kauth_listen_scope().
712 */
713 void
714 kauth_unlisten_scope(kauth_listener_t listener)
715 {
716 if (listener != NULL) {
717 SIMPLEQ_REMOVE(&listener->scope->listenq, listener,
718 kauth_listener, listener_next);
719 listener->scope->nlisteners--;
720 kmem_free(listener, sizeof(*listener));
721 }
722 }
723
724 /*
725 * Authorize a request.
726 *
727 * scope - the scope of the request as defined by KAUTH_SCOPE_* or as
728 * returned from kauth_register_scope().
729 * credential - credentials of the user ("actor") making the request.
730 * action - request identifier.
731 * arg[0-3] - passed unmodified to listener(s).
732 */
733 int
734 kauth_authorize_action(kauth_scope_t scope, kauth_cred_t cred,
735 kauth_action_t action, void *arg0, void *arg1,
736 void *arg2, void *arg3)
737 {
738 kauth_listener_t listener;
739 int error, allow, fail;
740
741 #if 0 /* defined(LOCKDEBUG) */
742 spinlock_switchcheck();
743 simple_lock_only_held(NULL, "kauth_authorize_action");
744 #endif
745
746 KASSERT(cred != NULL);
747 KASSERT(action != 0);
748
749 /* Short-circuit requests coming from the kernel. */
750 if (cred == NOCRED || cred == FSCRED)
751 return (0);
752
753 KASSERT(scope != NULL);
754
755 if (!listeners_have_been_loaded) {
756 KASSERT(SIMPLEQ_EMPTY(&scope->listenq));
757
758 return (0);
759 }
760
761 fail = 0;
762 allow = 0;
763 SIMPLEQ_FOREACH(listener, &scope->listenq, listener_next) {
764 error = listener->func(cred, action, scope->cookie, arg0,
765 arg1, arg2, arg3);
766
767 if (error == KAUTH_RESULT_ALLOW)
768 allow = 1;
769 else if (error == KAUTH_RESULT_DENY)
770 fail = 1;
771 }
772
773 return ((allow && !fail) ? 0 : EPERM);
774 };
775
776 /*
777 * Generic scope authorization wrapper.
778 */
779 int
780 kauth_authorize_generic(kauth_cred_t cred, kauth_action_t action, void *arg0)
781 {
782 return (kauth_authorize_action(kauth_builtin_scope_generic, cred,
783 action, arg0, NULL, NULL, NULL));
784 }
785
786 /*
787 * System scope authorization wrapper.
788 */
789 int
790 kauth_authorize_system(kauth_cred_t cred, kauth_action_t action,
791 enum kauth_system_req req, void *arg1, void *arg2, void *arg3)
792 {
793 return (kauth_authorize_action(kauth_builtin_scope_system, cred,
794 action, (void *)req, arg1, arg2, arg3));
795 }
796
797 /*
798 * Process scope authorization wrapper.
799 */
800 int
801 kauth_authorize_process(kauth_cred_t cred, kauth_action_t action,
802 struct proc *p, void *arg1, void *arg2, void *arg3)
803 {
804 return (kauth_authorize_action(kauth_builtin_scope_process, cred,
805 action, p, arg1, arg2, arg3));
806 }
807
808 /*
809 * Network scope authorization wrapper.
810 */
811 int
812 kauth_authorize_network(kauth_cred_t cred, kauth_action_t action,
813 enum kauth_network_req req, void *arg1, void *arg2, void *arg3)
814 {
815 return (kauth_authorize_action(kauth_builtin_scope_network, cred,
816 action, (void *)req, arg1, arg2, arg3));
817 }
818
819 int
820 kauth_authorize_machdep(kauth_cred_t cred, kauth_action_t action,
821 void *arg0, void *arg1, void *arg2, void *arg3)
822 {
823 return (kauth_authorize_action(kauth_builtin_scope_machdep, cred,
824 action, arg0, arg1, arg2, arg3));
825 }
826
827 int
828 kauth_authorize_device(kauth_cred_t cred, kauth_action_t action,
829 void *arg0, void *arg1, void *arg2, void *arg3)
830 {
831 return (kauth_authorize_action(kauth_builtin_scope_device, cred,
832 action, arg0, arg1, arg2, arg3));
833 }
834
835 int
836 kauth_authorize_device_tty(kauth_cred_t cred, kauth_action_t action,
837 struct tty *tty)
838 {
839 return (kauth_authorize_action(kauth_builtin_scope_device, cred,
840 action, tty, NULL, NULL, NULL));
841 }
842
843 int
844 kauth_authorize_device_spec(kauth_cred_t cred, enum kauth_device_req req,
845 struct vnode *vp)
846 {
847 return (kauth_authorize_action(kauth_builtin_scope_device, cred,
848 KAUTH_DEVICE_RAWIO_SPEC, (void *)req, vp, NULL, NULL));
849 }
850
851 int
852 kauth_authorize_device_passthru(kauth_cred_t cred, dev_t dev, u_long bits,
853 void *data)
854 {
855 return (kauth_authorize_action(kauth_builtin_scope_device, cred,
856 KAUTH_DEVICE_RAWIO_PASSTHRU, (void *)bits, (void *)(u_long)dev,
857 data, NULL));
858 }
Cache object: f6258c7fd4525f3022a965efb2794520
|