xref: /netbsd-src/sys/secmodel/suser/secmodel_suser.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /* $NetBSD: secmodel_suser.c,v 1.40 2012/11/13 20:10:03 pooka Exp $ */
2 /*-
3  * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * This file contains kauth(9) listeners needed to implement the traditional
31  * NetBSD superuser access restrictions.
32  *
33  * There are two main resources a request can be issued to: user-owned and
34  * system owned. For the first, traditional Unix access checks are done, as
35  * well as superuser checks. If needed, the request context is examined before
36  * a decision is made. For the latter, usually only superuser checks are done
37  * as normal users are not allowed to access system resources.
38  */
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.40 2012/11/13 20:10:03 pooka Exp $");
42 
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/kauth.h>
46 
47 #include <sys/mutex.h>
48 #include <sys/mount.h>
49 #include <sys/socketvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/vnode.h>
52 #include <sys/proc.h>
53 #include <sys/module.h>
54 
55 #include <secmodel/secmodel.h>
56 #include <secmodel/suser/suser.h>
57 
58 MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
59 
60 static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
61     l_device, l_vnode;
62 
63 static secmodel_t suser_sm;
64 static struct sysctllog *suser_sysctl_log;
65 
66 void
67 sysctl_security_suser_setup(struct sysctllog **clog)
68 {
69 	const struct sysctlnode *rnode;
70 
71 	sysctl_createv(clog, 0, NULL, &rnode,
72 		       CTLFLAG_PERMANENT,
73 		       CTLTYPE_NODE, "security", NULL,
74 		       NULL, 0, NULL, 0,
75 		       CTL_SECURITY, CTL_EOL);
76 
77 	sysctl_createv(clog, 0, &rnode, &rnode,
78 		       CTLFLAG_PERMANENT,
79 		       CTLTYPE_NODE, "models", NULL,
80 		       NULL, 0, NULL, 0,
81 		       CTL_CREATE, CTL_EOL);
82 
83 	sysctl_createv(clog, 0, &rnode, &rnode,
84 		       CTLFLAG_PERMANENT,
85 		       CTLTYPE_NODE, "suser", NULL,
86 		       NULL, 0, NULL, 0,
87 		       CTL_CREATE, CTL_EOL);
88 
89 	sysctl_createv(clog, 0, &rnode, NULL,
90 		       CTLFLAG_PERMANENT,
91 		       CTLTYPE_STRING, "name", NULL,
92 		       NULL, 0, __UNCONST(SECMODEL_SUSER_NAME), 0,
93 		       CTL_CREATE, CTL_EOL);
94 }
95 
96 void
97 secmodel_suser_init(void)
98 {
99 
100 }
101 
102 void
103 secmodel_suser_start(void)
104 {
105 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
106 	    secmodel_suser_generic_cb, NULL);
107 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
108 	    secmodel_suser_system_cb, NULL);
109 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
110 	    secmodel_suser_process_cb, NULL);
111 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
112 	    secmodel_suser_network_cb, NULL);
113 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
114 	    secmodel_suser_machdep_cb, NULL);
115 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
116 	    secmodel_suser_device_cb, NULL);
117 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
118 	    secmodel_suser_vnode_cb, NULL);
119 }
120 
121 void
122 secmodel_suser_stop(void)
123 {
124 	kauth_unlisten_scope(l_generic);
125 	kauth_unlisten_scope(l_system);
126 	kauth_unlisten_scope(l_process);
127 	kauth_unlisten_scope(l_network);
128 	kauth_unlisten_scope(l_machdep);
129 	kauth_unlisten_scope(l_device);
130 	kauth_unlisten_scope(l_vnode);
131 }
132 
133 static bool
134 suser_isroot(kauth_cred_t cred)
135 {
136 	return kauth_cred_geteuid(cred) == 0;
137 }
138 
139 static int
140 suser_eval(const char *what, void *arg, void *ret)
141 {
142 	int error = 0;
143 
144 	if (strcasecmp(what, "is-root") == 0) {
145 		kauth_cred_t cred = arg;
146 		bool *bp = ret;
147 
148 		*bp = suser_isroot(cred);
149 	} else {
150 		error = ENOENT;
151 	}
152 
153 	return error;
154 }
155 
156 static int
157 suser_modcmd(modcmd_t cmd, void *arg)
158 {
159 	int error = 0;
160 
161 	switch (cmd) {
162 	case MODULE_CMD_INIT:
163 		error = secmodel_register(&suser_sm,
164 		    SECMODEL_SUSER_ID, SECMODEL_SUSER_NAME,
165 		    NULL, suser_eval, NULL);
166 		if (error != 0)
167 			printf("suser_modcmd::init: secmodel_register "
168 			    "returned %d\n", error);
169 
170 		secmodel_suser_init();
171 		secmodel_suser_start();
172 		sysctl_security_suser_setup(&suser_sysctl_log);
173 		break;
174 
175 	case MODULE_CMD_FINI:
176 		sysctl_teardown(&suser_sysctl_log);
177 		secmodel_suser_stop();
178 
179 		error = secmodel_deregister(suser_sm);
180 		if (error != 0)
181 			printf("suser_modcmd::fini: secmodel_deregister "
182 			    "returned %d\n", error);
183 
184 		break;
185 
186 	case MODULE_CMD_AUTOUNLOAD:
187 		error = EPERM;
188 		break;
189 
190 	default:
191 		error = ENOTTY;
192 		break;
193 	}
194 
195 	return (error);
196 }
197 
198 /*
199  * kauth(9) listener
200  *
201  * Security model: Traditional NetBSD
202  * Scope: Generic
203  * Responsibility: Superuser access
204  */
205 int
206 secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
207     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
208 {
209 	bool isroot;
210 	int result;
211 
212 	isroot = suser_isroot(cred);
213 	result = KAUTH_RESULT_DEFER;
214 
215 	switch (action) {
216 	case KAUTH_GENERIC_ISSUSER:
217 		if (isroot)
218 			result = KAUTH_RESULT_ALLOW;
219 		break;
220 
221 	default:
222 		break;
223 	}
224 
225 	return (result);
226 }
227 
228 /*
229  * kauth(9) listener
230  *
231  * Security model: Traditional NetBSD
232  * Scope: System
233  * Responsibility: Superuser access
234  */
235 int
236 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
237     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
238 {
239 	bool isroot;
240 	int result;
241 	enum kauth_system_req req;
242 
243 	isroot = suser_isroot(cred);
244 	result = KAUTH_RESULT_DEFER;
245 	req = (enum kauth_system_req)arg0;
246 
247 	switch (action) {
248 	case KAUTH_SYSTEM_CPU:
249 		switch (req) {
250 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
251 			if (isroot)
252 				result = KAUTH_RESULT_ALLOW;
253 
254 			break;
255 
256 		default:
257 			break;
258 		}
259 
260 		break;
261 
262 	case KAUTH_SYSTEM_DEVMAPPER:
263 		if (isroot)
264 			result = KAUTH_RESULT_ALLOW;
265 
266 		break;
267 
268 	case KAUTH_SYSTEM_FS_QUOTA:
269 		switch (req) {
270 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
271 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
272 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
273 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
274 			if (isroot)
275 				result = KAUTH_RESULT_ALLOW;
276 			break;
277 
278 		default:
279 			break;
280 		}
281 
282 		break;
283 
284 	case KAUTH_SYSTEM_SYSVIPC:
285 		switch (req) {
286 		case KAUTH_REQ_SYSTEM_SYSVIPC_BYPASS:
287 		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_LOCK:
288 		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_UNLOCK:
289 		case KAUTH_REQ_SYSTEM_SYSVIPC_MSGQ_OVERSIZE:
290 			if (isroot)
291 				result = KAUTH_RESULT_ALLOW;
292 
293 			break;
294 
295 		default:
296 			break;
297 		}
298 
299 		break;
300 
301 	case KAUTH_SYSTEM_MOUNT:
302 		switch (req) {
303 		case KAUTH_REQ_SYSTEM_MOUNT_DEVICE:
304 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
305 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
306 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
307 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
308 		case KAUTH_REQ_SYSTEM_MOUNT_UMAP:
309 			if (isroot) {
310 				result = KAUTH_RESULT_ALLOW;
311 				break;
312 			}
313 
314 			break;
315 
316 		default:
317 			break;
318 		}
319 
320 		break;
321 
322 	case KAUTH_SYSTEM_MQUEUE:
323 		if (isroot)
324 			result = KAUTH_RESULT_ALLOW;
325 
326 		break;
327 
328 	case KAUTH_SYSTEM_PSET:
329 		switch (req) {
330 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
331 		case KAUTH_REQ_SYSTEM_PSET_BIND:
332 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
333 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
334 			if (isroot)
335 				result = KAUTH_RESULT_ALLOW;
336 
337 			break;
338 
339 		default:
340 			break;
341 		}
342 
343 		break;
344 
345 	case KAUTH_SYSTEM_TIME:
346 		switch (req) {
347 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
348 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
349 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
350 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
351 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
352 			if (isroot)
353 				result = KAUTH_RESULT_ALLOW;
354 			break;
355 
356 		default:
357 			break;
358 		}
359 		break;
360 
361 	case KAUTH_SYSTEM_SEMAPHORE:
362 		if (isroot)
363 			result = KAUTH_RESULT_ALLOW;
364 
365 		break;
366 
367 	case KAUTH_SYSTEM_SYSCTL:
368 		switch (req) {
369 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
370 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
371 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
372 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
373 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
374 			if (isroot)
375 				result = KAUTH_RESULT_ALLOW;
376 			break;
377 
378 		default:
379 			break;
380 		}
381 
382 		break;
383 
384 	case KAUTH_SYSTEM_SWAPCTL:
385 	case KAUTH_SYSTEM_ACCOUNTING:
386 	case KAUTH_SYSTEM_REBOOT:
387 	case KAUTH_SYSTEM_CHROOT:
388 	case KAUTH_SYSTEM_FILEHANDLE:
389 	case KAUTH_SYSTEM_MKNOD:
390 	case KAUTH_SYSTEM_SETIDCORE:
391 	case KAUTH_SYSTEM_MODULE:
392 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
393 	case KAUTH_SYSTEM_MAP_VA_ZERO:
394 	case KAUTH_SYSTEM_FS_EXTATTR:
395 	case KAUTH_SYSTEM_FS_SNAPSHOT:
396 		if (isroot)
397 			result = KAUTH_RESULT_ALLOW;
398 		break;
399 
400 	case KAUTH_SYSTEM_DEBUG:
401 		switch (req) {
402 		case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
403 			if (isroot)
404 				result = KAUTH_RESULT_ALLOW;
405 
406 			break;
407 
408 		default:
409 			break;
410 		}
411 
412 		break;
413 
414 	case KAUTH_SYSTEM_CHSYSFLAGS:
415 		/* Deprecated. */
416 		if (isroot)
417 			result = KAUTH_RESULT_ALLOW;
418 
419 		break;
420 
421 	case KAUTH_SYSTEM_VERIEXEC:
422 		switch (req) {
423 		case KAUTH_REQ_SYSTEM_VERIEXEC_ACCESS:
424 		case KAUTH_REQ_SYSTEM_VERIEXEC_MODIFY:
425 			if (isroot)
426 				result = KAUTH_RESULT_ALLOW;
427 
428 			break;
429 
430 		default:
431 			break;
432 		}
433 
434 		break;
435 
436 	case KAUTH_SYSTEM_LFS:
437 		switch (req) {
438 		case KAUTH_REQ_SYSTEM_LFS_MARKV:
439 		case KAUTH_REQ_SYSTEM_LFS_BMAPV:
440 		case KAUTH_REQ_SYSTEM_LFS_SEGCLEAN:
441 		case KAUTH_REQ_SYSTEM_LFS_SEGWAIT:
442 		case KAUTH_REQ_SYSTEM_LFS_FCNTL:
443 			if (isroot)
444 				result = KAUTH_RESULT_ALLOW;
445 
446 		default:
447 			break;
448 		}
449 
450 		break;
451 
452 	default:
453 		break;
454 	}
455 
456 	return (result);
457 }
458 
459 /*
460  * kauth(9) listener
461  *
462  * Security model: Traditional NetBSD
463  * Scope: Process
464  * Responsibility: Superuser access
465  */
466 int
467 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
468     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
469 {
470 	bool isroot;
471 	int result;
472 
473 	isroot = suser_isroot(cred);
474 	result = KAUTH_RESULT_DEFER;
475 
476 	switch (action) {
477 	case KAUTH_PROCESS_SIGNAL:
478 	case KAUTH_PROCESS_KTRACE:
479 	case KAUTH_PROCESS_PROCFS:
480 	case KAUTH_PROCESS_PTRACE:
481 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
482 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
483 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
484 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
485 	case KAUTH_PROCESS_SETID:
486 	case KAUTH_PROCESS_KEVENT_FILTER:
487 	case KAUTH_PROCESS_NICE:
488 	case KAUTH_PROCESS_FORK:
489 	case KAUTH_PROCESS_CORENAME:
490 	case KAUTH_PROCESS_STOPFLAG:
491 		if (isroot)
492 			result = KAUTH_RESULT_ALLOW;
493 
494 		break;
495 
496 	case KAUTH_PROCESS_CANSEE: {
497 		unsigned long req;
498 
499 		req = (unsigned long)arg1;
500 
501 		switch (req) {
502 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
503 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
504 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
505 			if (isroot) {
506 				result = KAUTH_RESULT_ALLOW;
507 				break;
508 			}
509 
510 			break;
511 
512 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
513 			if (isroot)
514 				result = KAUTH_RESULT_ALLOW;
515 
516 			break;
517 
518 		default:
519 			break;
520 		}
521 
522 		break;
523 		}
524 
525 	case KAUTH_PROCESS_RLIMIT: {
526 		enum kauth_process_req req;
527 
528 		req = (enum kauth_process_req)(unsigned long)arg1;
529 
530 		switch (req) {
531 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
532 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
533 		case KAUTH_REQ_PROCESS_RLIMIT_BYPASS:
534 			if (isroot)
535 				result = KAUTH_RESULT_ALLOW;
536 
537 			break;
538 
539 		default:
540 			break;
541 		}
542 
543 		break;
544 		}
545 
546 	default:
547 		break;
548 	}
549 
550 	return (result);
551 }
552 
553 /*
554  * kauth(9) listener
555  *
556  * Security model: Traditional NetBSD
557  * Scope: Network
558  * Responsibility: Superuser access
559  */
560 int
561 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
562     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
563 {
564 	bool isroot;
565 	int result;
566 	enum kauth_network_req req;
567 
568 	isroot = suser_isroot(cred);
569 	result = KAUTH_RESULT_DEFER;
570 	req = (enum kauth_network_req)arg0;
571 
572 	switch (action) {
573 	case KAUTH_NETWORK_ALTQ:
574 		switch (req) {
575 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
576 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
577 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
578 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
579 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
580 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
581 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
582 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
583 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
584 		case KAUTH_REQ_NETWORK_ALTQ_RED:
585 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
586 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
587 			if (isroot)
588 				result = KAUTH_RESULT_ALLOW;
589 			break;
590 
591 		default:
592 			break;
593 		}
594 
595 		break;
596 
597 	case KAUTH_NETWORK_BIND:
598 		switch (req) {
599 		case KAUTH_REQ_NETWORK_BIND_PORT:
600 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
601 			if (isroot)
602 				result = KAUTH_RESULT_ALLOW;
603 			break;
604 
605 		default:
606 			break;
607 		}
608 		break;
609 
610 	case KAUTH_NETWORK_FIREWALL:
611 		switch (req) {
612 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
613 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
614 			if (isroot)
615 				result = KAUTH_RESULT_ALLOW;
616 
617 			break;
618 
619 		default:
620 			break;
621 		}
622 		break;
623 
624 	case KAUTH_NETWORK_FORWSRCRT:
625 	case KAUTH_NETWORK_ROUTE:
626 		if (isroot)
627 			result = KAUTH_RESULT_ALLOW;
628 
629 		break;
630 
631 	case KAUTH_NETWORK_INTERFACE:
632 		switch (req) {
633 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
634 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
635 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
636 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
637 		case KAUTH_REQ_NETWORK_INTERFACE_FIRMWARE:
638 			if (isroot)
639 				result = KAUTH_RESULT_ALLOW;
640 			break;
641 
642 		default:
643 			break;
644 		}
645 		break;
646 
647 	case KAUTH_NETWORK_INTERFACE_BRIDGE:
648 		switch (req) {
649 		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV:
650 		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV:
651 			if (isroot)
652 				result = KAUTH_RESULT_ALLOW;
653 			break;
654 
655 		default:
656 			break;
657 		}
658 
659 		break;
660 
661 	case KAUTH_NETWORK_INTERFACE_PPP:
662 		switch (req) {
663 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
664 			if (isroot)
665 				result = KAUTH_RESULT_ALLOW;
666 			break;
667 
668 		default:
669 			break;
670 		}
671 
672 		break;
673 
674 	case KAUTH_NETWORK_INTERFACE_PVC:
675 		switch (req) {
676 		case KAUTH_REQ_NETWORK_INTERFACE_PVC_ADD:
677 			if (isroot)
678 				result = KAUTH_RESULT_ALLOW;
679 
680 			break;
681 
682 		default:
683 			break;
684 		}
685 
686 		break;
687 
688 	case KAUTH_NETWORK_INTERFACE_SLIP:
689 		switch (req) {
690 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
691 			if (isroot)
692 				result = KAUTH_RESULT_ALLOW;
693 			break;
694 
695 		default:
696 			break;
697 		}
698 
699 		break;
700 
701 	case KAUTH_NETWORK_INTERFACE_STRIP:
702 		switch (req) {
703 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
704 			if (isroot)
705 				result = KAUTH_RESULT_ALLOW;
706 			break;
707 
708 		default:
709 			break;
710 		}
711 
712 		break;
713 
714 	case KAUTH_NETWORK_INTERFACE_TUN:
715 		switch (req) {
716 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
717 			if (isroot)
718 				result = KAUTH_RESULT_ALLOW;
719 			break;
720 
721 		default:
722 			break;
723 		}
724 
725 		break;
726 
727 	case KAUTH_NETWORK_IPV6:
728 		switch (req) {
729 		case KAUTH_REQ_NETWORK_IPV6_HOPBYHOP:
730 		case KAUTH_REQ_NETWORK_IPV6_JOIN_MULTICAST:
731 			if (isroot)
732 				result = KAUTH_RESULT_ALLOW;
733 
734 			break;
735 
736 		default:
737 			break;
738 		}
739 
740 		break;
741 
742 	case KAUTH_NETWORK_NFS:
743 		switch (req) {
744 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
745 		case KAUTH_REQ_NETWORK_NFS_SVC:
746 			if (isroot)
747 				result = KAUTH_RESULT_ALLOW;
748 
749 			break;
750 
751 		default:
752 			break;
753 		}
754 		break;
755 
756 	case KAUTH_NETWORK_SMB:
757 		switch (req) {
758 		case KAUTH_REQ_NETWORK_SMB_SHARE_ACCESS:
759 		case KAUTH_REQ_NETWORK_SMB_SHARE_CREATE:
760 		case KAUTH_REQ_NETWORK_SMB_VC_ACCESS:
761 		case KAUTH_REQ_NETWORK_SMB_VC_CREATE:
762 			if (isroot)
763 				result = KAUTH_RESULT_ALLOW;
764 
765 			break;
766 
767 		default:
768 			break;
769 		}
770 
771 		break;
772 
773 	case KAUTH_NETWORK_SOCKET:
774 		switch (req) {
775 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
776 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
777 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
778 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
779 			if (isroot)
780 				result = KAUTH_RESULT_ALLOW;
781 			break;
782 
783 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
784 			if (isroot) {
785 				result = KAUTH_RESULT_ALLOW;
786 				break;
787 			}
788 
789 			break;
790 
791 		default:
792 			break;
793 		}
794 
795 		break;
796 
797 	case KAUTH_NETWORK_IPSEC:
798 		switch (req) {
799 		case KAUTH_REQ_NETWORK_IPSEC_BYPASS:
800 			if (isroot)
801 				result = KAUTH_RESULT_ALLOW;
802 
803 			break;
804 
805 		default:
806 			break;
807 		}
808 
809 		break;
810 
811 	default:
812 		break;
813 	}
814 
815 	return (result);
816 }
817 
818 /*
819  * kauth(9) listener
820  *
821  * Security model: Traditional NetBSD
822  * Scope: Machdep
823  * Responsibility: Superuser access
824  */
825 int
826 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
827     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
828 {
829         bool isroot;
830         int result;
831 
832         isroot = suser_isroot(cred);
833         result = KAUTH_RESULT_DEFER;
834 
835         switch (action) {
836 	case KAUTH_MACHDEP_CPU_UCODE_APPLY:
837 	case KAUTH_MACHDEP_IOPERM_GET:
838 	case KAUTH_MACHDEP_LDT_GET:
839 	case KAUTH_MACHDEP_LDT_SET:
840 	case KAUTH_MACHDEP_MTRR_GET:
841 	case KAUTH_MACHDEP_CACHEFLUSH:
842 	case KAUTH_MACHDEP_IOPERM_SET:
843 	case KAUTH_MACHDEP_IOPL:
844 	case KAUTH_MACHDEP_MTRR_SET:
845 	case KAUTH_MACHDEP_NVRAM:
846 	case KAUTH_MACHDEP_UNMANAGEDMEM:
847 	case KAUTH_MACHDEP_PXG:
848 		if (isroot)
849 			result = KAUTH_RESULT_ALLOW;
850 		break;
851 
852 	default:
853 		break;
854 	}
855 
856 	return (result);
857 }
858 
859 /*
860  * kauth(9) listener
861  *
862  * Security model: Traditional NetBSD
863  * Scope: Device
864  * Responsibility: Superuser access
865  */
866 int
867 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
868     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
869 {
870         bool isroot;
871         int result;
872 
873         isroot = suser_isroot(cred);
874         result = KAUTH_RESULT_DEFER;
875 
876 	switch (action) {
877 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
878 	case KAUTH_DEVICE_BLUETOOTH_SEND:
879 	case KAUTH_DEVICE_BLUETOOTH_RECV:
880 	case KAUTH_DEVICE_TTY_OPEN:
881 	case KAUTH_DEVICE_TTY_PRIVSET:
882 	case KAUTH_DEVICE_TTY_STI:
883 	case KAUTH_DEVICE_TTY_VIRTUAL:
884 	case KAUTH_DEVICE_RND_ADDDATA:
885 	case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE:
886 	case KAUTH_DEVICE_RND_GETPRIV:
887 	case KAUTH_DEVICE_RND_SETPRIV:
888 	case KAUTH_DEVICE_WSCONS_KEYBOARD_BELL:
889 	case KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT:
890 		if (isroot)
891 			result = KAUTH_RESULT_ALLOW;
892 		break;
893 
894 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
895 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
896 		enum kauth_device_req req;
897 
898 		req = (enum kauth_device_req)arg0;
899 		switch (req) {
900 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
901 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
902 			if (isroot)
903 				result = KAUTH_RESULT_ALLOW;
904 			break;
905 
906 		default:
907 			break;
908 		}
909 
910 		break;
911 		}
912 
913 	case KAUTH_DEVICE_GPIO_PINSET:
914 		/*
915 		 * root can access gpio pins, secmodel_securlevel can veto
916 		 * this decision.
917 		 */
918 		if (isroot)
919 			result = KAUTH_RESULT_ALLOW;
920 		break;
921 
922 	default:
923 		break;
924 	}
925 
926 	return (result);
927 }
928 
929 int
930 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
931     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
932 {
933 	bool isroot;
934 	int result;
935 
936 	isroot = suser_isroot(cred);
937 	result = KAUTH_RESULT_DEFER;
938 
939 	if (isroot) {
940 		/* Superuser can execute only if the file's executable. */
941 		if ((action & KAUTH_VNODE_EXECUTE) == 0 ||
942 		    (action & KAUTH_VNODE_IS_EXEC))
943 			result = KAUTH_RESULT_ALLOW;
944 	}
945 
946 	return (result);
947 }
948 
949