1/* $NetBSD: secmodel_suser.c,v 1.58 2024/03/01 22:01:03 andvar 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.58 2024/03/01 22:01:03 andvar 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
58MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
59
60static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
61    l_device, l_vnode;
62
63static secmodel_t suser_sm;
64
65SYSCTL_SETUP(sysctl_security_suser_setup, "secmodel_user sysctl")
66{
67	const struct sysctlnode *rnode;
68
69	sysctl_createv(clog, 0, NULL, &rnode,
70		       CTLFLAG_PERMANENT,
71		       CTLTYPE_NODE, "models", NULL,
72		       NULL, 0, NULL, 0,
73		       CTL_SECURITY, CTL_CREATE, CTL_EOL);
74
75	sysctl_createv(clog, 0, &rnode, &rnode,
76		       CTLFLAG_PERMANENT,
77		       CTLTYPE_NODE, "suser", NULL,
78		       NULL, 0, NULL, 0,
79		       CTL_CREATE, CTL_EOL);
80
81	sysctl_createv(clog, 0, &rnode, NULL,
82		       CTLFLAG_PERMANENT,
83		       CTLTYPE_STRING, "name", NULL,
84		       NULL, 0, __UNCONST(SECMODEL_SUSER_NAME), 0,
85		       CTL_CREATE, CTL_EOL);
86}
87
88void
89secmodel_suser_init(void)
90{
91
92}
93
94void
95secmodel_suser_start(void)
96{
97	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
98	    secmodel_suser_generic_cb, NULL);
99	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
100	    secmodel_suser_system_cb, NULL);
101	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
102	    secmodel_suser_process_cb, NULL);
103	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
104	    secmodel_suser_network_cb, NULL);
105	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
106	    secmodel_suser_machdep_cb, NULL);
107	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
108	    secmodel_suser_device_cb, NULL);
109	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
110	    secmodel_suser_vnode_cb, NULL);
111}
112
113void
114secmodel_suser_stop(void)
115{
116	kauth_unlisten_scope(l_generic);
117	kauth_unlisten_scope(l_system);
118	kauth_unlisten_scope(l_process);
119	kauth_unlisten_scope(l_network);
120	kauth_unlisten_scope(l_machdep);
121	kauth_unlisten_scope(l_device);
122	kauth_unlisten_scope(l_vnode);
123}
124
125static bool
126suser_isroot(kauth_cred_t cred)
127{
128	return kauth_cred_geteuid(cred) == 0;
129}
130
131static int
132suser_eval(const char *what, void *arg, void *ret)
133{
134	int error = 0;
135
136	if (strcasecmp(what, "is-root") == 0) {
137		kauth_cred_t cred = arg;
138		bool *bp = ret;
139
140		*bp = suser_isroot(cred);
141	} else {
142		error = ENOENT;
143	}
144
145	return error;
146}
147
148static int
149suser_modcmd(modcmd_t cmd, void *arg)
150{
151	int error = 0;
152
153	switch (cmd) {
154	case MODULE_CMD_INIT:
155		error = secmodel_register(&suser_sm,
156		    SECMODEL_SUSER_ID, SECMODEL_SUSER_NAME,
157		    NULL, suser_eval, NULL);
158		if (error != 0)
159			printf("suser_modcmd::init: secmodel_register "
160			    "returned %d\n", error);
161
162		secmodel_suser_init();
163		secmodel_suser_start();
164		break;
165
166	case MODULE_CMD_FINI:
167		secmodel_suser_stop();
168
169		error = secmodel_deregister(suser_sm);
170		if (error != 0)
171			printf("suser_modcmd::fini: secmodel_deregister "
172			    "returned %d\n", error);
173
174		break;
175
176	case MODULE_CMD_AUTOUNLOAD:
177		error = EPERM;
178		break;
179
180	default:
181		error = ENOTTY;
182		break;
183	}
184
185	return (error);
186}
187
188/*
189 * kauth(9) listener
190 *
191 * Security model: Traditional NetBSD
192 * Scope: Generic
193 * Responsibility: Superuser access
194 */
195int
196secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
197    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
198{
199	bool isroot;
200	int result;
201
202	isroot = suser_isroot(cred);
203	result = KAUTH_RESULT_DEFER;
204
205	switch (action) {
206	case KAUTH_GENERIC_ISSUSER:
207		if (isroot)
208			result = KAUTH_RESULT_ALLOW;
209		break;
210
211	default:
212		break;
213	}
214
215	return (result);
216}
217
218/*
219 * kauth(9) listener
220 *
221 * Security model: Traditional NetBSD
222 * Scope: System
223 * Responsibility: Superuser access
224 */
225int
226secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
227    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
228{
229	bool isroot;
230	int result;
231	enum kauth_system_req req;
232
233	isroot = suser_isroot(cred);
234	result = KAUTH_RESULT_DEFER;
235	req = (enum kauth_system_req)(uintptr_t)arg0;
236
237	switch (action) {
238	case KAUTH_SYSTEM_CPU:
239		switch (req) {
240		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
241			if (isroot)
242				result = KAUTH_RESULT_ALLOW;
243
244			break;
245
246		default:
247			break;
248		}
249
250		break;
251
252	case KAUTH_SYSTEM_DEVMAPPER:
253		if (isroot)
254			result = KAUTH_RESULT_ALLOW;
255
256		break;
257
258	case KAUTH_SYSTEM_FS_QUOTA:
259		switch (req) {
260		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
261		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
262		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
263		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
264			if (isroot)
265				result = KAUTH_RESULT_ALLOW;
266			break;
267
268		default:
269			break;
270		}
271
272		break;
273
274	case KAUTH_SYSTEM_SYSVIPC:
275		switch (req) {
276		case KAUTH_REQ_SYSTEM_SYSVIPC_BYPASS:
277		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_LOCK:
278		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_UNLOCK:
279		case KAUTH_REQ_SYSTEM_SYSVIPC_MSGQ_OVERSIZE:
280			if (isroot)
281				result = KAUTH_RESULT_ALLOW;
282
283			break;
284
285		default:
286			break;
287		}
288
289		break;
290
291	case KAUTH_SYSTEM_MOUNT:
292		switch (req) {
293		case KAUTH_REQ_SYSTEM_MOUNT_DEVICE:
294		case KAUTH_REQ_SYSTEM_MOUNT_GET:
295		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
296		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
297		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
298		case KAUTH_REQ_SYSTEM_MOUNT_UMAP:
299			if (isroot) {
300				result = KAUTH_RESULT_ALLOW;
301				break;
302			}
303
304			break;
305
306		default:
307			break;
308		}
309
310		break;
311
312	case KAUTH_SYSTEM_MQUEUE:
313		if (isroot)
314			result = KAUTH_RESULT_ALLOW;
315
316		break;
317
318	case KAUTH_SYSTEM_PSET:
319		switch (req) {
320		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
321		case KAUTH_REQ_SYSTEM_PSET_BIND:
322		case KAUTH_REQ_SYSTEM_PSET_CREATE:
323		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
324			if (isroot)
325				result = KAUTH_RESULT_ALLOW;
326
327			break;
328
329		default:
330			break;
331		}
332
333		break;
334
335	case KAUTH_SYSTEM_TIME:
336		switch (req) {
337		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
338		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
339		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
340		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
341		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
342			if (isroot)
343				result = KAUTH_RESULT_ALLOW;
344			break;
345
346		default:
347			break;
348		}
349		break;
350
351	case KAUTH_SYSTEM_SEMAPHORE:
352		if (isroot)
353			result = KAUTH_RESULT_ALLOW;
354
355		break;
356
357	case KAUTH_SYSTEM_SYSCTL:
358		switch (req) {
359		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
360		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
361		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
362		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
363		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
364			if (isroot)
365				result = KAUTH_RESULT_ALLOW;
366			break;
367
368		default:
369			break;
370		}
371
372		break;
373
374	case KAUTH_SYSTEM_SWAPCTL:
375	case KAUTH_SYSTEM_ACCOUNTING:
376	case KAUTH_SYSTEM_REBOOT:
377	case KAUTH_SYSTEM_CHROOT:
378	case KAUTH_SYSTEM_FILEHANDLE:
379	case KAUTH_SYSTEM_MKNOD:
380	case KAUTH_SYSTEM_SETIDCORE:
381	case KAUTH_SYSTEM_MODULE:
382	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
383	case KAUTH_SYSTEM_MAP_VA_ZERO:
384	case KAUTH_SYSTEM_FS_EXTATTR:
385	case KAUTH_SYSTEM_FS_SNAPSHOT:
386		if (isroot)
387			result = KAUTH_RESULT_ALLOW;
388		break;
389
390	case KAUTH_SYSTEM_DEBUG:
391		break;
392
393	case KAUTH_SYSTEM_CHSYSFLAGS:
394		/* Deprecated. */
395		if (isroot)
396			result = KAUTH_RESULT_ALLOW;
397
398		break;
399
400	case KAUTH_SYSTEM_VERIEXEC:
401		switch (req) {
402		case KAUTH_REQ_SYSTEM_VERIEXEC_ACCESS:
403		case KAUTH_REQ_SYSTEM_VERIEXEC_MODIFY:
404			if (isroot)
405				result = KAUTH_RESULT_ALLOW;
406
407			break;
408
409		default:
410			break;
411		}
412
413		break;
414
415	case KAUTH_SYSTEM_LFS:
416		switch (req) {
417		case KAUTH_REQ_SYSTEM_LFS_MARKV:
418		case KAUTH_REQ_SYSTEM_LFS_BMAPV:
419		case KAUTH_REQ_SYSTEM_LFS_SEGCLEAN:
420		case KAUTH_REQ_SYSTEM_LFS_SEGWAIT:
421		case KAUTH_REQ_SYSTEM_LFS_FCNTL:
422			if (isroot)
423				result = KAUTH_RESULT_ALLOW;
424
425		default:
426			break;
427		}
428
429		break;
430
431	case KAUTH_SYSTEM_INTR:
432		switch (req) {
433		case KAUTH_REQ_SYSTEM_INTR_AFFINITY:
434			if (isroot)
435				result = KAUTH_RESULT_ALLOW;
436
437			break;
438
439		default:
440			break;
441		}
442
443		break;
444
445	case KAUTH_SYSTEM_KERNADDR:
446		if (isroot)
447			result = KAUTH_RESULT_ALLOW;
448
449		break;
450
451	default:
452		break;
453	}
454
455	return (result);
456}
457
458/*
459 * kauth(9) listener
460 *
461 * Security model: Traditional NetBSD
462 * Scope: Process
463 * Responsibility: Superuser access
464 */
465int
466secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
467    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
468{
469	bool isroot;
470	int result;
471
472	isroot = suser_isroot(cred);
473	result = KAUTH_RESULT_DEFER;
474
475	switch (action) {
476	case KAUTH_PROCESS_SIGNAL:
477	case KAUTH_PROCESS_KTRACE:
478	case KAUTH_PROCESS_PROCFS:
479	case KAUTH_PROCESS_PTRACE:
480	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
481	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
482	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
483	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
484	case KAUTH_PROCESS_SETID:
485	case KAUTH_PROCESS_KEVENT_FILTER:
486	case KAUTH_PROCESS_NICE:
487	case KAUTH_PROCESS_FORK:
488	case KAUTH_PROCESS_CORENAME:
489	case KAUTH_PROCESS_STOPFLAG:
490		if (isroot)
491			result = KAUTH_RESULT_ALLOW;
492
493		break;
494
495	case KAUTH_PROCESS_CANSEE: {
496		unsigned long req;
497
498		req = (unsigned long)arg1;
499
500		switch (req) {
501		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
502		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
503		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
504		case KAUTH_REQ_PROCESS_CANSEE_EPROC:
505		case KAUTH_REQ_PROCESS_CANSEE_KPTR:
506			if (isroot) {
507				result = KAUTH_RESULT_ALLOW;
508				break;
509			}
510
511			break;
512
513		case KAUTH_REQ_PROCESS_CANSEE_ENV:
514			if (isroot)
515				result = KAUTH_RESULT_ALLOW;
516
517			break;
518
519		default:
520			break;
521		}
522
523		break;
524		}
525
526	case KAUTH_PROCESS_RLIMIT: {
527		enum kauth_process_req req;
528
529		req = (enum kauth_process_req)(uintptr_t)arg1;
530
531		switch (req) {
532		case KAUTH_REQ_PROCESS_RLIMIT_SET:
533		case KAUTH_REQ_PROCESS_RLIMIT_GET:
534		case KAUTH_REQ_PROCESS_RLIMIT_BYPASS:
535			if (isroot)
536				result = KAUTH_RESULT_ALLOW;
537
538			break;
539
540		default:
541			break;
542		}
543
544		break;
545		}
546
547	default:
548		break;
549	}
550
551	return (result);
552}
553
554/*
555 * kauth(9) listener
556 *
557 * Security model: Traditional NetBSD
558 * Scope: Network
559 * Responsibility: Superuser access
560 */
561int
562secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
563    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
564{
565	bool isroot;
566	int result;
567	enum kauth_network_req req;
568
569	isroot = suser_isroot(cred);
570	result = KAUTH_RESULT_DEFER;
571	req = (enum kauth_network_req)(uintptr_t)arg0;
572
573	switch (action) {
574	case KAUTH_NETWORK_ALTQ:
575		switch (req) {
576		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
577		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
578		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
579		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
580		case KAUTH_REQ_NETWORK_ALTQ_CONF:
581		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
582		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
583		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
584		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
585		case KAUTH_REQ_NETWORK_ALTQ_RED:
586		case KAUTH_REQ_NETWORK_ALTQ_RIO:
587		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
588			if (isroot)
589				result = KAUTH_RESULT_ALLOW;
590			break;
591
592		default:
593			break;
594		}
595
596		break;
597
598	case KAUTH_NETWORK_BIND:
599		switch (req) {
600		case KAUTH_REQ_NETWORK_BIND_PORT:
601		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
602		case KAUTH_REQ_NETWORK_BIND_ANYADDR:
603			if (isroot)
604				result = KAUTH_RESULT_ALLOW;
605			break;
606
607		default:
608			break;
609		}
610		break;
611
612	case KAUTH_NETWORK_FIREWALL:
613		switch (req) {
614		case KAUTH_REQ_NETWORK_FIREWALL_FW:
615		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
616			if (isroot)
617				result = KAUTH_RESULT_ALLOW;
618
619			break;
620
621		default:
622			break;
623		}
624		break;
625
626	case KAUTH_NETWORK_FORWSRCRT:
627	case KAUTH_NETWORK_ROUTE:
628		if (isroot)
629			result = KAUTH_RESULT_ALLOW;
630
631		break;
632
633	case KAUTH_NETWORK_INTERFACE:
634		switch (req) {
635		case KAUTH_REQ_NETWORK_INTERFACE_GET:
636		case KAUTH_REQ_NETWORK_INTERFACE_SET:
637		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
638		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
639		case KAUTH_REQ_NETWORK_INTERFACE_FIRMWARE:
640			if (isroot)
641				result = KAUTH_RESULT_ALLOW;
642			break;
643
644		default:
645			break;
646		}
647		break;
648
649	case KAUTH_NETWORK_INTERFACE_BRIDGE:
650		switch (req) {
651		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV:
652		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV:
653			if (isroot)
654				result = KAUTH_RESULT_ALLOW;
655			break;
656
657		default:
658			break;
659		}
660
661		break;
662
663	case KAUTH_NETWORK_INTERFACE_PPP:
664		switch (req) {
665		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
666			if (isroot)
667				result = KAUTH_RESULT_ALLOW;
668			break;
669
670		default:
671			break;
672		}
673
674		break;
675
676	case KAUTH_NETWORK_INTERFACE_PVC:
677		switch (req) {
678		case KAUTH_REQ_NETWORK_INTERFACE_PVC_ADD:
679			if (isroot)
680				result = KAUTH_RESULT_ALLOW;
681
682			break;
683
684		default:
685			break;
686		}
687
688		break;
689
690	case KAUTH_NETWORK_INTERFACE_SLIP:
691		switch (req) {
692		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
693			if (isroot)
694				result = KAUTH_RESULT_ALLOW;
695			break;
696
697		default:
698			break;
699		}
700
701		break;
702
703	case KAUTH_NETWORK_INTERFACE_TUN:
704		switch (req) {
705		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
706			if (isroot)
707				result = KAUTH_RESULT_ALLOW;
708			break;
709
710		default:
711			break;
712		}
713
714		break;
715
716	case KAUTH_NETWORK_IPV6:
717		switch (req) {
718		case KAUTH_REQ_NETWORK_IPV6_HOPBYHOP:
719		case KAUTH_REQ_NETWORK_IPV6_JOIN_MULTICAST:
720			if (isroot)
721				result = KAUTH_RESULT_ALLOW;
722
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_SMB:
746		switch (req) {
747		case KAUTH_REQ_NETWORK_SMB_SHARE_ACCESS:
748		case KAUTH_REQ_NETWORK_SMB_SHARE_CREATE:
749		case KAUTH_REQ_NETWORK_SMB_VC_ACCESS:
750		case KAUTH_REQ_NETWORK_SMB_VC_CREATE:
751			if (isroot)
752				result = KAUTH_RESULT_ALLOW;
753
754			break;
755
756		default:
757			break;
758		}
759
760		break;
761
762	case KAUTH_NETWORK_INTERFACE_WG:
763		switch (req) {
764		case KAUTH_REQ_NETWORK_INTERFACE_WG_GETPRIV:
765		case KAUTH_REQ_NETWORK_INTERFACE_WG_SETPRIV:
766			if (isroot)
767				result = KAUTH_RESULT_ALLOW;
768			break;
769
770		default:
771			break;
772		}
773
774		break;
775
776	case KAUTH_NETWORK_SOCKET:
777		switch (req) {
778		case KAUTH_REQ_NETWORK_SOCKET_DROP:
779		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
780		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
781		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
782			if (isroot)
783				result = KAUTH_RESULT_ALLOW;
784			break;
785
786		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
787			if (isroot) {
788				result = KAUTH_RESULT_ALLOW;
789				break;
790			}
791
792			break;
793
794		default:
795			break;
796		}
797
798		break;
799
800	case KAUTH_NETWORK_IPSEC:
801		switch (req) {
802		case KAUTH_REQ_NETWORK_IPSEC_BYPASS:
803			if (isroot)
804				result = KAUTH_RESULT_ALLOW;
805
806			break;
807
808		default:
809			break;
810		}
811
812		break;
813
814	default:
815		break;
816	}
817
818	return (result);
819}
820
821/*
822 * kauth(9) listener
823 *
824 * Security model: Traditional NetBSD
825 * Scope: Machdep
826 * Responsibility: Superuser access
827 */
828int
829secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
830    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
831{
832	bool isroot;
833	int result;
834
835	isroot = suser_isroot(cred);
836	result = KAUTH_RESULT_DEFER;
837
838	switch (action) {
839	case KAUTH_MACHDEP_CPU_UCODE_APPLY:
840	case KAUTH_MACHDEP_IOPERM_GET:
841	case KAUTH_MACHDEP_LDT_GET:
842	case KAUTH_MACHDEP_LDT_SET:
843	case KAUTH_MACHDEP_MTRR_GET:
844	case KAUTH_MACHDEP_CACHEFLUSH:
845	case KAUTH_MACHDEP_IOPERM_SET:
846	case KAUTH_MACHDEP_IOPL:
847	case KAUTH_MACHDEP_MTRR_SET:
848	case KAUTH_MACHDEP_NVRAM:
849	case KAUTH_MACHDEP_UNMANAGEDMEM:
850	case KAUTH_MACHDEP_PXG:
851		if (isroot)
852			result = KAUTH_RESULT_ALLOW;
853		break;
854
855	case KAUTH_MACHDEP_SVS_DISABLE:
856		/* Deprecated. */
857		if (isroot)
858			result = KAUTH_RESULT_ALLOW;
859		break;
860
861	default:
862		break;
863	}
864
865	return (result);
866}
867
868/*
869 * kauth(9) listener
870 *
871 * Security model: Traditional NetBSD
872 * Scope: Device
873 * Responsibility: Superuser access
874 */
875int
876secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
877    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
878{
879	bool isroot;
880	int result;
881
882	isroot = suser_isroot(cred);
883	result = KAUTH_RESULT_DEFER;
884
885	switch (action) {
886	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
887	case KAUTH_DEVICE_BLUETOOTH_SEND:
888	case KAUTH_DEVICE_BLUETOOTH_RECV:
889	case KAUTH_DEVICE_TTY_OPEN:
890	case KAUTH_DEVICE_TTY_PRIVSET:
891	case KAUTH_DEVICE_TTY_STI:
892	case KAUTH_DEVICE_TTY_VIRTUAL:
893	case KAUTH_DEVICE_RND_ADDDATA:
894	case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE:
895	case KAUTH_DEVICE_RND_GETPRIV:
896	case KAUTH_DEVICE_RND_SETPRIV:
897	case KAUTH_DEVICE_WSCONS_KEYBOARD_BELL:
898	case KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT:
899	case KAUTH_DEVICE_NVMM_CTL:
900		if (isroot)
901			result = KAUTH_RESULT_ALLOW;
902		break;
903
904	case KAUTH_DEVICE_BLUETOOTH_BCSP:
905	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
906		enum kauth_device_req req;
907
908		req = (enum kauth_device_req)(uintptr_t)arg0;
909		switch (req) {
910		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
911		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
912			if (isroot)
913				result = KAUTH_RESULT_ALLOW;
914			break;
915
916		default:
917			break;
918		}
919
920		break;
921		}
922
923	case KAUTH_DEVICE_GPIO_PINSET:
924		/*
925		 * root can access gpio pins, secmodel_securelevel can veto
926		 * this decision.
927		 */
928		if (isroot)
929			result = KAUTH_RESULT_ALLOW;
930		break;
931
932	default:
933		break;
934	}
935
936	return (result);
937}
938
939int
940secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
941    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
942{
943	bool isroot;
944	int result;
945
946	isroot = suser_isroot(cred);
947	result = KAUTH_RESULT_DEFER;
948
949	if (isroot) {
950		/* Superuser can execute only if the file's executable. */
951		if ((action & KAUTH_VNODE_EXECUTE) == 0 ||
952		    (action & KAUTH_VNODE_IS_EXEC))
953			result = KAUTH_RESULT_ALLOW;
954	}
955
956	return (result);
957}
958
959