xref: /netbsd-src/sys/secmodel/suser/secmodel_suser.c (revision abb0f93cd77b67f080613360c65701f85e5f5cfe)
1 /* $NetBSD: secmodel_suser.c,v 1.32 2009/11/18 09:47:18 stacktic 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.32 2009/11/18 09:47:18 stacktic 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/uidinfo.h>
54 #include <sys/module.h>
55 
56 #include <secmodel/suser/suser.h>
57 
58 MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
59 
60 static int secmodel_suser_curtain;
61 /* static */ int dovfsusermount;
62 
63 static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
64     l_device, l_vnode;
65 
66 static struct sysctllog *suser_sysctl_log;
67 
68 void
69 sysctl_security_suser_setup(struct sysctllog **clog)
70 {
71 	const struct sysctlnode *rnode;
72 
73 	sysctl_createv(clog, 0, NULL, &rnode,
74 		       CTLFLAG_PERMANENT,
75 		       CTLTYPE_NODE, "security", NULL,
76 		       NULL, 0, NULL, 0,
77 		       CTL_SECURITY, CTL_EOL);
78 
79 	sysctl_createv(clog, 0, &rnode, &rnode,
80 		       CTLFLAG_PERMANENT,
81 		       CTLTYPE_NODE, "models", NULL,
82 		       NULL, 0, NULL, 0,
83 		       CTL_CREATE, CTL_EOL);
84 
85 	sysctl_createv(clog, 0, &rnode, &rnode,
86 		       CTLFLAG_PERMANENT,
87 		       CTLTYPE_NODE, "suser", NULL,
88 		       NULL, 0, NULL, 0,
89 		       CTL_CREATE, CTL_EOL);
90 
91 	sysctl_createv(clog, 0, &rnode, NULL,
92 		       CTLFLAG_PERMANENT,
93 		       CTLTYPE_STRING, "name", NULL,
94 		       NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
95 		       CTL_CREATE, CTL_EOL);
96 
97 	sysctl_createv(clog, 0, &rnode, NULL,
98 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
99 		       CTLTYPE_INT, "curtain",
100 		       SYSCTL_DESCR("Curtain information about objects to "\
101 		       		    "users not owning them."),
102 		       NULL, 0, &secmodel_suser_curtain, 0,
103 		       CTL_CREATE, CTL_EOL);
104 
105 	sysctl_createv(clog, 0, &rnode, NULL,
106 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
107 		       CTLTYPE_INT, "usermount",
108 		       SYSCTL_DESCR("Whether unprivileged users may mount "
109 				    "filesystems"),
110 		       NULL, 0, &dovfsusermount, 0,
111 		       CTL_CREATE, CTL_EOL);
112 
113 	/* Compatibility: security.curtain */
114 	sysctl_createv(clog, 0, NULL, &rnode,
115 		       CTLFLAG_PERMANENT,
116 		       CTLTYPE_NODE, "security", NULL,
117 		       NULL, 0, NULL, 0,
118 		       CTL_SECURITY, CTL_EOL);
119 
120 	sysctl_createv(clog, 0, &rnode, NULL,
121 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
122 		       CTLTYPE_INT, "curtain",
123 		       SYSCTL_DESCR("Curtain information about objects to "\
124 		       		    "users not owning them."),
125 		       NULL, 0, &secmodel_suser_curtain, 0,
126 		       CTL_CREATE, CTL_EOL);
127 
128 	/* Compatibility: vfs.generic.usermount */
129 	sysctl_createv(clog, 0, NULL, NULL,
130 		       CTLFLAG_PERMANENT,
131 		       CTLTYPE_NODE, "vfs", NULL,
132 		       NULL, 0, NULL, 0,
133 		       CTL_VFS, CTL_EOL);
134 
135 	sysctl_createv(clog, 0, NULL, NULL,
136 		       CTLFLAG_PERMANENT,
137 		       CTLTYPE_NODE, "generic",
138 		       SYSCTL_DESCR("Non-specific vfs related information"),
139 		       NULL, 0, NULL, 0,
140 		       CTL_VFS, VFS_GENERIC, CTL_EOL);
141 
142 	sysctl_createv(clog, 0, NULL, NULL,
143 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
144 		       CTLTYPE_INT, "usermount",
145 		       SYSCTL_DESCR("Whether unprivileged users may mount "
146 				    "filesystems"),
147 		       NULL, 0, &dovfsusermount, 0,
148 		       CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL);
149 }
150 
151 void
152 secmodel_suser_init(void)
153 {
154 	secmodel_suser_curtain = 0;
155 }
156 
157 void
158 secmodel_suser_start(void)
159 {
160 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
161 	    secmodel_suser_generic_cb, NULL);
162 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
163 	    secmodel_suser_system_cb, NULL);
164 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
165 	    secmodel_suser_process_cb, NULL);
166 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
167 	    secmodel_suser_network_cb, NULL);
168 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
169 	    secmodel_suser_machdep_cb, NULL);
170 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
171 	    secmodel_suser_device_cb, NULL);
172 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
173 	    secmodel_suser_vnode_cb, NULL);
174 }
175 
176 void
177 secmodel_suser_stop(void)
178 {
179 	kauth_unlisten_scope(l_generic);
180 	kauth_unlisten_scope(l_system);
181 	kauth_unlisten_scope(l_process);
182 	kauth_unlisten_scope(l_network);
183 	kauth_unlisten_scope(l_machdep);
184 	kauth_unlisten_scope(l_device);
185 	kauth_unlisten_scope(l_vnode);
186 }
187 
188 static int
189 suser_modcmd(modcmd_t cmd, void *arg)
190 {
191 	int error = 0;
192 
193 	switch (cmd) {
194 	case MODULE_CMD_INIT:
195 		secmodel_suser_init();
196 		secmodel_suser_start();
197 		sysctl_security_suser_setup(&suser_sysctl_log);
198 		break;
199 
200 	case MODULE_CMD_FINI:
201 		sysctl_teardown(&suser_sysctl_log);
202 		secmodel_suser_stop();
203 		break;
204 
205 	case MODULE_CMD_AUTOUNLOAD:
206 		error = EPERM;
207 		break;
208 
209 	default:
210 		error = ENOTTY;
211 		break;
212 	}
213 
214 	return (error);
215 }
216 
217 /*
218  * kauth(9) listener
219  *
220  * Security model: Traditional NetBSD
221  * Scope: Generic
222  * Responsibility: Superuser access
223  */
224 int
225 secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
226     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
227 {
228 	bool isroot;
229 	int result;
230 
231 	isroot = (kauth_cred_geteuid(cred) == 0);
232 	result = KAUTH_RESULT_DEFER;
233 
234 	switch (action) {
235 	case KAUTH_GENERIC_ISSUSER:
236 		if (isroot)
237 			result = KAUTH_RESULT_ALLOW;
238 		break;
239 
240 	case KAUTH_GENERIC_CANSEE:
241 		if (!secmodel_suser_curtain)
242 			result = KAUTH_RESULT_ALLOW;
243 		else if (isroot || kauth_cred_uidmatch(cred, arg0))
244 			result = KAUTH_RESULT_ALLOW;
245 
246 		break;
247 
248 	default:
249 		break;
250 	}
251 
252 	return (result);
253 }
254 
255 static int
256 suser_usermount_policy(kauth_cred_t cred, enum kauth_system_req req, void *arg1,
257     void *arg2)
258 {
259 	struct mount *mp;
260 	u_long flags;
261 	int result;
262 
263 	result = KAUTH_RESULT_DEFER;
264 
265 	if (!dovfsusermount)
266 		return result;
267 
268 	switch (req) {
269 	case KAUTH_REQ_SYSTEM_MOUNT_NEW:
270 		mp = ((struct vnode *)arg1)->v_mount;
271 		flags= (u_long)arg2;
272 
273 		if (usermount_common_policy(mp, flags) != 0)
274 			break;
275 
276 		result = KAUTH_RESULT_ALLOW;
277 
278 		break;
279 
280 	case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
281 		mp = arg1;
282 
283 		/* Must own the mount. */
284 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
285 			break;
286 
287 		result = KAUTH_RESULT_ALLOW;
288 
289 		break;
290 
291 	case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
292 		mp = arg1;
293 		flags = (u_long)arg2;
294 
295 		/* Must own the mount. */
296 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
297 			break;
298 
299 		if (usermount_common_policy(mp, flags) != 0)
300 			break;
301 
302 		result = KAUTH_RESULT_ALLOW;
303 
304 		break;
305 
306 	default:
307 		break;
308 	}
309 
310 	return result;
311 }
312 
313 /*
314  * kauth(9) listener
315  *
316  * Security model: Traditional NetBSD
317  * Scope: System
318  * Responsibility: Superuser access
319  */
320 int
321 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
322     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
323 {
324 	bool isroot;
325 	int result;
326 	enum kauth_system_req req;
327 
328 	isroot = (kauth_cred_geteuid(cred) == 0);
329 	result = KAUTH_RESULT_DEFER;
330 	req = (enum kauth_system_req)arg0;
331 
332 	switch (action) {
333 	case KAUTH_SYSTEM_CPU:
334 		switch (req) {
335 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
336 			if (isroot)
337 				result = KAUTH_RESULT_ALLOW;
338 
339 			break;
340 
341 		default:
342 			break;
343 		}
344 
345 		break;
346 
347 	case KAUTH_SYSTEM_FS_QUOTA:
348 		switch (req) {
349 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
350 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
351 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
352 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
353 			if (isroot)
354 				result = KAUTH_RESULT_ALLOW;
355 			break;
356 
357 		default:
358 			break;
359 		}
360 
361 		break;
362 
363 	case KAUTH_SYSTEM_MOUNT:
364 		switch (req) {
365 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
366 			if (isroot) {
367 				result = KAUTH_RESULT_ALLOW;
368 				break;
369 			}
370 
371 			break;
372 
373 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
374 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
375 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
376 			if (isroot) {
377 				result = KAUTH_RESULT_ALLOW;
378 				break;
379 			}
380 
381 			result = suser_usermount_policy(cred, req, arg1, arg2);
382 
383 			break;
384 
385 		default:
386 			break;
387 		}
388 
389 		break;
390 
391 	case KAUTH_SYSTEM_PSET:
392 		switch (req) {
393 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
394 		case KAUTH_REQ_SYSTEM_PSET_BIND:
395 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
396 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
397 			if (isroot)
398 				result = KAUTH_RESULT_ALLOW;
399 
400 			break;
401 
402 		default:
403 			break;
404 		}
405 
406 		break;
407 
408 	case KAUTH_SYSTEM_TIME:
409 		switch (req) {
410 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
411 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
412 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
413 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
414 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
415 			if (isroot)
416 				result = KAUTH_RESULT_ALLOW;
417 			break;
418 
419 		default:
420 			break;
421 		}
422 		break;
423 
424 	case KAUTH_SYSTEM_SYSCTL:
425 		switch (req) {
426 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
427 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
428 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
429 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
430 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
431 			if (isroot)
432 				result = KAUTH_RESULT_ALLOW;
433 			break;
434 
435 		default:
436 			break;
437 		}
438 
439 		break;
440 
441 	case KAUTH_SYSTEM_SWAPCTL:
442 	case KAUTH_SYSTEM_ACCOUNTING:
443 	case KAUTH_SYSTEM_REBOOT:
444 	case KAUTH_SYSTEM_CHROOT:
445 	case KAUTH_SYSTEM_FILEHANDLE:
446 	case KAUTH_SYSTEM_MKNOD:
447 	case KAUTH_SYSTEM_SETIDCORE:
448 	case KAUTH_SYSTEM_MODULE:
449 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
450 		if (isroot)
451 			result = KAUTH_RESULT_ALLOW;
452 		break;
453 
454 	case KAUTH_SYSTEM_DEBUG:
455 		switch (req) {
456 		case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
457 			if (isroot)
458 				result = KAUTH_RESULT_ALLOW;
459 
460 			break;
461 
462 		default:
463 			break;
464 		}
465 
466 		break;
467 
468 	case KAUTH_SYSTEM_CHSYSFLAGS:
469 		/*
470 		 * Needs to be checked in conjunction with the immutable and
471 		 * append-only flags (usually). Should be handled differently.
472 		 * Infects ufs, ext2fs, tmpfs, and rump.
473 		 */
474 		if (isroot)
475 			result = KAUTH_RESULT_ALLOW;
476 
477 		break;
478 
479 	default:
480 		break;
481 	}
482 
483 	return (result);
484 }
485 
486 /*
487  * kauth(9) listener
488  *
489  * Security model: Traditional NetBSD
490  * Scope: Process
491  * Responsibility: Superuser access
492  */
493 int
494 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
495     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
496 {
497 	struct proc *p;
498 	bool isroot;
499 	int result;
500 
501 	isroot = (kauth_cred_geteuid(cred) == 0);
502 	result = KAUTH_RESULT_DEFER;
503 	p = arg0;
504 
505 	switch (action) {
506 	case KAUTH_PROCESS_SIGNAL:
507 	case KAUTH_PROCESS_KTRACE:
508 	case KAUTH_PROCESS_PROCFS:
509 	case KAUTH_PROCESS_PTRACE:
510 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
511 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
512 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
513 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
514 	case KAUTH_PROCESS_SETID:
515 	case KAUTH_PROCESS_KEVENT_FILTER:
516 	case KAUTH_PROCESS_NICE:
517 	case KAUTH_PROCESS_FORK:
518 	case KAUTH_PROCESS_CORENAME:
519 	case KAUTH_PROCESS_STOPFLAG:
520 		if (isroot)
521 			result = KAUTH_RESULT_ALLOW;
522 
523 		break;
524 
525 	case KAUTH_PROCESS_CANSEE: {
526 		unsigned long req;
527 
528 		req = (unsigned long)arg1;
529 
530 		switch (req) {
531 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
532 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
533 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
534 			if (isroot) {
535 				result = KAUTH_RESULT_ALLOW;
536 				break;
537 			}
538 
539 			if (secmodel_suser_curtain) {
540 				if (!kauth_cred_uidmatch(cred, p->p_cred))
541 					result = KAUTH_RESULT_DENY;
542 			}
543 
544 			break;
545 
546 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
547 			if (isroot)
548 				result = KAUTH_RESULT_ALLOW;
549 
550 			break;
551 
552 		default:
553 			break;
554 		}
555 
556 		break;
557 		}
558 
559 	case KAUTH_PROCESS_RLIMIT: {
560 		enum kauth_process_req req;
561 
562 		req = (enum kauth_process_req)(unsigned long)arg1;
563 
564 		switch (req) {
565 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
566 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
567 			if (isroot)
568 				result = KAUTH_RESULT_ALLOW;
569 
570 			break;
571 
572 		default:
573 			break;
574 		}
575 
576 		break;
577 		}
578 
579 	default:
580 		break;
581 	}
582 
583 	return (result);
584 }
585 
586 /*
587  * kauth(9) listener
588  *
589  * Security model: Traditional NetBSD
590  * Scope: Network
591  * Responsibility: Superuser access
592  */
593 int
594 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
595     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
596 {
597 	bool isroot;
598 	int result;
599 	enum kauth_network_req req;
600 
601 	isroot = (kauth_cred_geteuid(cred) == 0);
602 	result = KAUTH_RESULT_DEFER;
603 	req = (enum kauth_network_req)arg0;
604 
605 	switch (action) {
606 	case KAUTH_NETWORK_ALTQ:
607 		switch (req) {
608 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
609 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
610 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
611 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
612 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
613 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
614 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
615 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
616 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
617 		case KAUTH_REQ_NETWORK_ALTQ_RED:
618 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
619 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
620 			if (isroot)
621 				result = KAUTH_RESULT_ALLOW;
622 			break;
623 
624 		default:
625 			break;
626 		}
627 
628 		break;
629 
630 	case KAUTH_NETWORK_BIND:
631 		switch (req) {
632 		case KAUTH_REQ_NETWORK_BIND_PORT:
633 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
634 			if (isroot)
635 				result = KAUTH_RESULT_ALLOW;
636 			break;
637 
638 		default:
639 			break;
640 		}
641 		break;
642 
643 	case KAUTH_NETWORK_FIREWALL:
644 		switch (req) {
645 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
646 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
647 			if (isroot)
648 				result = KAUTH_RESULT_ALLOW;
649 
650 			break;
651 
652 		default:
653 			break;
654 		}
655 		break;
656 
657 	case KAUTH_NETWORK_FORWSRCRT:
658 	case KAUTH_NETWORK_ROUTE:
659 		if (isroot)
660 			result = KAUTH_RESULT_ALLOW;
661 
662 		break;
663 
664 	case KAUTH_NETWORK_INTERFACE:
665 		switch (req) {
666 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
667 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
668 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
669 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
670 			if (isroot)
671 				result = KAUTH_RESULT_ALLOW;
672 			break;
673 
674 		default:
675 			break;
676 		}
677 		break;
678 
679 	case KAUTH_NETWORK_INTERFACE_PPP:
680 		switch (req) {
681 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
682 			if (isroot)
683 				result = KAUTH_RESULT_ALLOW;
684 			break;
685 
686 		default:
687 			break;
688 		}
689 
690 		break;
691 
692 	case KAUTH_NETWORK_INTERFACE_SLIP:
693 		switch (req) {
694 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
695 			if (isroot)
696 				result = KAUTH_RESULT_ALLOW;
697 			break;
698 
699 		default:
700 			break;
701 		}
702 
703 		break;
704 
705 	case KAUTH_NETWORK_INTERFACE_STRIP:
706 		switch (req) {
707 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
708 			if (isroot)
709 				result = KAUTH_RESULT_ALLOW;
710 			break;
711 
712 		default:
713 			break;
714 		}
715 
716 		break;
717 
718 	case KAUTH_NETWORK_INTERFACE_TUN:
719 		switch (req) {
720 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
721 			if (isroot)
722 				result = KAUTH_RESULT_ALLOW;
723 			break;
724 
725 		default:
726 			break;
727 		}
728 
729 		break;
730 
731 	case KAUTH_NETWORK_NFS:
732 		switch (req) {
733 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
734 		case KAUTH_REQ_NETWORK_NFS_SVC:
735 			if (isroot)
736 				result = KAUTH_RESULT_ALLOW;
737 
738 			break;
739 
740 		default:
741 			break;
742 		}
743 		break;
744 
745 	case KAUTH_NETWORK_SOCKET:
746 		switch (req) {
747 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
748 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
749 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
750 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
751 			if (isroot)
752 				result = KAUTH_RESULT_ALLOW;
753 			break;
754 
755 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
756 			if (isroot) {
757 				result = KAUTH_RESULT_ALLOW;
758 				break;
759 			}
760 
761 			if (secmodel_suser_curtain) {
762 				struct socket *so;
763 				uid_t so_uid;
764 
765 				so = (struct socket *)arg1;
766 				so_uid = so->so_uidinfo->ui_uid;
767 				if (kauth_cred_geteuid(cred) != so_uid)
768 					result = KAUTH_RESULT_DENY;
769 			}
770 
771 			break;
772 
773 		default:
774 			break;
775 		}
776 
777 		break;
778 
779 
780 	default:
781 		break;
782 	}
783 
784 	return (result);
785 }
786 
787 /*
788  * kauth(9) listener
789  *
790  * Security model: Traditional NetBSD
791  * Scope: Machdep
792  * Responsibility: Superuser access
793  */
794 int
795 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
796     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
797 {
798         bool isroot;
799         int result;
800 
801         isroot = (kauth_cred_geteuid(cred) == 0);
802         result = KAUTH_RESULT_DEFER;
803 
804         switch (action) {
805 	case KAUTH_MACHDEP_IOPERM_GET:
806 	case KAUTH_MACHDEP_LDT_GET:
807 	case KAUTH_MACHDEP_LDT_SET:
808 	case KAUTH_MACHDEP_MTRR_GET:
809 	case KAUTH_MACHDEP_CACHEFLUSH:
810 	case KAUTH_MACHDEP_IOPERM_SET:
811 	case KAUTH_MACHDEP_IOPL:
812 	case KAUTH_MACHDEP_MTRR_SET:
813 	case KAUTH_MACHDEP_NVRAM:
814 	case KAUTH_MACHDEP_UNMANAGEDMEM:
815 		if (isroot)
816 			result = KAUTH_RESULT_ALLOW;
817 		break;
818 
819 	default:
820 		break;
821 	}
822 
823 	return (result);
824 }
825 
826 /*
827  * kauth(9) listener
828  *
829  * Security model: Traditional NetBSD
830  * Scope: Device
831  * Responsibility: Superuser access
832  */
833 int
834 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
835     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
836 {
837         bool isroot;
838         int result;
839 
840         isroot = (kauth_cred_geteuid(cred) == 0);
841         result = KAUTH_RESULT_DEFER;
842 
843 	switch (action) {
844 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
845 	case KAUTH_DEVICE_BLUETOOTH_SEND:
846 	case KAUTH_DEVICE_BLUETOOTH_RECV:
847 	case KAUTH_DEVICE_TTY_OPEN:
848 	case KAUTH_DEVICE_TTY_PRIVSET:
849 	case KAUTH_DEVICE_TTY_STI:
850 	case KAUTH_DEVICE_RND_ADDDATA:
851 	case KAUTH_DEVICE_RND_GETPRIV:
852 	case KAUTH_DEVICE_RND_SETPRIV:
853 		if (isroot)
854 			result = KAUTH_RESULT_ALLOW;
855 		break;
856 
857 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
858 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
859 		enum kauth_device_req req;
860 
861 		req = (enum kauth_device_req)arg0;
862 		switch (req) {
863 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
864 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
865 			if (isroot)
866 				result = KAUTH_RESULT_ALLOW;
867 			break;
868 
869 		default:
870 			break;
871 		}
872 
873 		break;
874 		}
875 
876 	case KAUTH_DEVICE_GPIO_PINSET:
877 		/*
878 		 * root can access gpio pins, secmodel_securlevel can veto
879 		 * this decision.
880 		 */
881 		if (isroot)
882 			result = KAUTH_RESULT_ALLOW;
883 		break;
884 
885 	default:
886 		break;
887 	}
888 
889 	return (result);
890 }
891 
892 int
893 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
894     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
895 {
896 	bool isroot;
897 	int result;
898 
899 	isroot = (kauth_cred_geteuid(cred) == 0);
900 	result = KAUTH_RESULT_DEFER;
901 
902 	if (isroot)
903 		result = KAUTH_RESULT_ALLOW;
904 
905 	return (result);
906 }
907 
908