Home | History | Annotate | Line # | Download | only in suser
secmodel_suser.c revision 1.26
      1 /* $NetBSD: secmodel_suser.c,v 1.26 2009/10/03 03:59:39 elad Exp $ */
      2 /*-
      3  * Copyright (c) 2006 Elad Efrat <elad (at) 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.26 2009/10/03 03:59:39 elad 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 	dovfsusermount = 0;
    156 }
    157 
    158 void
    159 secmodel_suser_start(void)
    160 {
    161 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
    162 	    secmodel_suser_generic_cb, NULL);
    163 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
    164 	    secmodel_suser_system_cb, NULL);
    165 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
    166 	    secmodel_suser_process_cb, NULL);
    167 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
    168 	    secmodel_suser_network_cb, NULL);
    169 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
    170 	    secmodel_suser_machdep_cb, NULL);
    171 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
    172 	    secmodel_suser_device_cb, NULL);
    173 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
    174 	    secmodel_suser_vnode_cb, NULL);
    175 }
    176 
    177 void
    178 secmodel_suser_stop(void)
    179 {
    180 	kauth_unlisten_scope(l_generic);
    181 	kauth_unlisten_scope(l_system);
    182 	kauth_unlisten_scope(l_process);
    183 	kauth_unlisten_scope(l_network);
    184 	kauth_unlisten_scope(l_machdep);
    185 	kauth_unlisten_scope(l_device);
    186 	kauth_unlisten_scope(l_vnode);
    187 }
    188 
    189 static int
    190 suser_modcmd(modcmd_t cmd, void *arg)
    191 {
    192 	int error = 0;
    193 
    194 	switch (cmd) {
    195 	case MODULE_CMD_INIT:
    196 		secmodel_suser_init();
    197 		secmodel_suser_start();
    198 		sysctl_security_suser_setup(&suser_sysctl_log);
    199 		break;
    200 
    201 	case MODULE_CMD_FINI:
    202 		sysctl_teardown(&suser_sysctl_log);
    203 		secmodel_suser_stop();
    204 		break;
    205 
    206 	case MODULE_CMD_AUTOUNLOAD:
    207 		error = EPERM;
    208 		break;
    209 
    210 	default:
    211 		error = ENOTTY;
    212 		break;
    213 	}
    214 
    215 	return (error);
    216 }
    217 
    218 /*
    219  * kauth(9) listener
    220  *
    221  * Security model: Traditional NetBSD
    222  * Scope: Generic
    223  * Responsibility: Superuser access
    224  */
    225 int
    226 secmodel_suser_generic_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 
    232 	isroot = (kauth_cred_geteuid(cred) == 0);
    233 	result = KAUTH_RESULT_DEFER;
    234 
    235 	switch (action) {
    236 	case KAUTH_GENERIC_ISSUSER:
    237 		if (isroot)
    238 			result = KAUTH_RESULT_ALLOW;
    239 		break;
    240 
    241 	case KAUTH_GENERIC_CANSEE:
    242 		if (!secmodel_suser_curtain)
    243 			result = KAUTH_RESULT_ALLOW;
    244 		else if (isroot || kauth_cred_uidmatch(cred, arg0))
    245 			result = KAUTH_RESULT_ALLOW;
    246 
    247 		break;
    248 
    249 	default:
    250 		break;
    251 	}
    252 
    253 	return (result);
    254 }
    255 
    256 /*
    257  * kauth(9) listener
    258  *
    259  * Security model: Traditional NetBSD
    260  * Scope: System
    261  * Responsibility: Superuser access
    262  */
    263 int
    264 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
    265     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    266 {
    267 	bool isroot;
    268 	int result;
    269 	enum kauth_system_req req;
    270 
    271 	isroot = (kauth_cred_geteuid(cred) == 0);
    272 	result = KAUTH_RESULT_DEFER;
    273 	req = (enum kauth_system_req)arg0;
    274 
    275 	switch (action) {
    276 	case KAUTH_SYSTEM_CPU:
    277 		switch (req) {
    278 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
    279 			if (isroot)
    280 				result = KAUTH_RESULT_ALLOW;
    281 
    282 			break;
    283 
    284 		default:
    285 			break;
    286 		}
    287 
    288 		break;
    289 
    290 	case KAUTH_SYSTEM_FS_QUOTA:
    291 		switch (req) {
    292 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
    293 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
    294 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
    295 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
    296 			if (isroot)
    297 				result = KAUTH_RESULT_ALLOW;
    298 			break;
    299 
    300 		default:
    301 			break;
    302 		}
    303 
    304 		break;
    305 
    306 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
    307 		if (isroot)
    308 			result = KAUTH_RESULT_ALLOW;
    309 		break;
    310 
    311 	case KAUTH_SYSTEM_MOUNT:
    312 		switch (req) {
    313 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
    314 			result = KAUTH_RESULT_ALLOW;
    315 			break;
    316 
    317 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
    318 			if (isroot)
    319 				result = KAUTH_RESULT_ALLOW;
    320 			else if (dovfsusermount) {
    321 				struct vnode *vp = arg1;
    322 				u_long flags = (u_long)arg2;
    323 
    324 				if (!(flags & MNT_NODEV) ||
    325 				    !(flags & MNT_NOSUID))
    326 					break;
    327 
    328 				if ((vp->v_mount->mnt_flag & MNT_NOEXEC) &&
    329 				    !(flags & MNT_NOEXEC))
    330 					break;
    331 
    332 				result = KAUTH_RESULT_ALLOW;
    333 			}
    334 
    335 			break;
    336 
    337 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
    338 			if (isroot)
    339 				result = KAUTH_RESULT_ALLOW;
    340 			else {
    341 				struct mount *mp = arg1;
    342 
    343 				if (mp->mnt_stat.f_owner ==
    344 				    kauth_cred_geteuid(cred))
    345 					result = KAUTH_RESULT_ALLOW;
    346 			}
    347 
    348 			break;
    349 
    350 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
    351 			if (isroot)
    352 				result = KAUTH_RESULT_ALLOW;
    353 			else if (dovfsusermount) {
    354 				struct mount *mp = arg1;
    355 				u_long flags = (u_long)arg2;
    356 
    357 				/* No exporting for non-root. */
    358 				if (flags & MNT_EXPORTED)
    359 					break;
    360 
    361 				if (!(flags & MNT_NODEV) ||
    362 				    !(flags & MNT_NOSUID))
    363 					break;
    364 
    365 				/*
    366 				 * Only super-user, or user that did the mount,
    367 				 * can update.
    368 				 */
    369 				if (mp->mnt_stat.f_owner !=
    370 				    kauth_cred_geteuid(cred))
    371 					break;
    372 
    373 				/* Retain 'noexec'. */
    374 				if ((mp->mnt_flag & MNT_NOEXEC) &&
    375 				    !(flags & MNT_NOEXEC))
    376 					break;
    377 
    378 				result = KAUTH_RESULT_ALLOW;
    379 			}
    380 
    381 			break;
    382 
    383 		default:
    384 			break;
    385 		}
    386 
    387 		break;
    388 
    389 	case KAUTH_SYSTEM_PSET:
    390 		switch (req) {
    391 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
    392 		case KAUTH_REQ_SYSTEM_PSET_BIND:
    393 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
    394 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
    395 			if (isroot)
    396 				result = KAUTH_RESULT_ALLOW;
    397 
    398 			break;
    399 
    400 		default:
    401 			break;
    402 		}
    403 
    404 		break;
    405 
    406 	case KAUTH_SYSTEM_TIME:
    407 		switch (req) {
    408 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
    409 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
    410 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
    411 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
    412 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
    413 			if (isroot)
    414 				result = KAUTH_RESULT_ALLOW;
    415 			break;
    416 
    417 		default:
    418 			break;
    419 		}
    420 		break;
    421 
    422 	case KAUTH_SYSTEM_SYSCTL:
    423 		switch (req) {
    424 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
    425 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
    426 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
    427 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
    428 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
    429 			if (isroot)
    430 				result = KAUTH_RESULT_ALLOW;
    431 			break;
    432 
    433 		default:
    434 			break;
    435 		}
    436 
    437 		break;
    438 
    439 	case KAUTH_SYSTEM_SWAPCTL:
    440 	case KAUTH_SYSTEM_ACCOUNTING:
    441 	case KAUTH_SYSTEM_REBOOT:
    442 	case KAUTH_SYSTEM_CHROOT:
    443 	case KAUTH_SYSTEM_FILEHANDLE:
    444 	case KAUTH_SYSTEM_MKNOD:
    445 	case KAUTH_SYSTEM_SETIDCORE:
    446 	case KAUTH_SYSTEM_MODULE:
    447 		if (isroot)
    448 			result = KAUTH_RESULT_ALLOW;
    449 		break;
    450 
    451 	case KAUTH_SYSTEM_CHSYSFLAGS:
    452 		/*
    453 		 * Needs to be checked in conjunction with the immutable and
    454 		 * append-only flags (usually). Should be handled differently.
    455 		 * Infects ufs, ext2fs, tmpfs, and rump.
    456 		 */
    457 		if (isroot)
    458 			result = KAUTH_RESULT_ALLOW;
    459 
    460 		break;
    461 
    462 	default:
    463 		break;
    464 	}
    465 
    466 	return (result);
    467 }
    468 
    469 /*
    470  * kauth(9) listener
    471  *
    472  * Security model: Traditional NetBSD
    473  * Scope: Process
    474  * Responsibility: Superuser access
    475  */
    476 int
    477 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
    478     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    479 {
    480 	struct proc *p;
    481 	bool isroot;
    482 	int result;
    483 
    484 	isroot = (kauth_cred_geteuid(cred) == 0);
    485 	result = KAUTH_RESULT_DEFER;
    486 	p = arg0;
    487 
    488 	switch (action) {
    489 	case KAUTH_PROCESS_SIGNAL:
    490 	case KAUTH_PROCESS_KTRACE:
    491 	case KAUTH_PROCESS_PROCFS:
    492 	case KAUTH_PROCESS_PTRACE:
    493 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
    494 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
    495 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
    496 	case KAUTH_PROCESS_SETID:
    497 	case KAUTH_PROCESS_KEVENT_FILTER:
    498 	case KAUTH_PROCESS_NICE:
    499 	case KAUTH_PROCESS_FORK:
    500 	case KAUTH_PROCESS_CORENAME:
    501 	case KAUTH_PROCESS_STOPFLAG:
    502 		if (isroot)
    503 			result = KAUTH_RESULT_ALLOW;
    504 
    505 		break;
    506 
    507 	case KAUTH_PROCESS_CANSEE: {
    508 		unsigned long req;
    509 
    510 		req = (unsigned long)arg1;
    511 
    512 		switch (req) {
    513 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
    514 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
    515 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
    516 			if (isroot) {
    517 				result = KAUTH_RESULT_ALLOW;
    518 				break;
    519 			}
    520 
    521 			if (secmodel_suser_curtain) {
    522 				if (kauth_cred_uidmatch(cred, p->p_cred) != 0)
    523 					result = KAUTH_RESULT_DENY;
    524 			}
    525 
    526 			break;
    527 
    528 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
    529 			if (isroot)
    530 				result = KAUTH_RESULT_ALLOW;
    531 
    532 			break;
    533 
    534 		default:
    535 			break;
    536 		}
    537 
    538 		break;
    539 		}
    540 
    541 	case KAUTH_PROCESS_RLIMIT: {
    542 		enum kauth_process_req req;
    543 
    544 		req = (enum kauth_process_req)(unsigned long)arg1;
    545 
    546 		switch (req) {
    547 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
    548 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
    549 			if (isroot)
    550 				result = KAUTH_RESULT_ALLOW;
    551 
    552 			break;
    553 
    554 		default:
    555 			break;
    556 		}
    557 
    558 		break;
    559 		}
    560 
    561 	default:
    562 		break;
    563 	}
    564 
    565 	return (result);
    566 }
    567 
    568 /*
    569  * kauth(9) listener
    570  *
    571  * Security model: Traditional NetBSD
    572  * Scope: Network
    573  * Responsibility: Superuser access
    574  */
    575 int
    576 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
    577     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    578 {
    579 	bool isroot;
    580 	int result;
    581 	enum kauth_network_req req;
    582 
    583 	isroot = (kauth_cred_geteuid(cred) == 0);
    584 	result = KAUTH_RESULT_DEFER;
    585 	req = (enum kauth_network_req)arg0;
    586 
    587 	switch (action) {
    588 	case KAUTH_NETWORK_ALTQ:
    589 		switch (req) {
    590 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
    591 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
    592 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
    593 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
    594 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
    595 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
    596 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
    597 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
    598 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
    599 		case KAUTH_REQ_NETWORK_ALTQ_RED:
    600 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
    601 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
    602 			if (isroot)
    603 				result = KAUTH_RESULT_ALLOW;
    604 			break;
    605 
    606 		default:
    607 			break;
    608 		}
    609 
    610 		break;
    611 
    612 	case KAUTH_NETWORK_BIND:
    613 		switch (req) {
    614 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
    615 			if (isroot)
    616 				result = KAUTH_RESULT_ALLOW;
    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_GETPRIV:
    634 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
    635 			if (isroot)
    636 				result = KAUTH_RESULT_ALLOW;
    637 			break;
    638 
    639 		default:
    640 			break;
    641 		}
    642 		break;
    643 
    644 	case KAUTH_NETWORK_INTERFACE_PPP:
    645 		switch (req) {
    646 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
    647 			if (isroot)
    648 				result = KAUTH_RESULT_ALLOW;
    649 			break;
    650 
    651 		default:
    652 			break;
    653 		}
    654 
    655 		break;
    656 
    657 	case KAUTH_NETWORK_INTERFACE_SLIP:
    658 		switch (req) {
    659 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
    660 			if (isroot)
    661 				result = KAUTH_RESULT_ALLOW;
    662 			break;
    663 
    664 		default:
    665 			break;
    666 		}
    667 
    668 		break;
    669 
    670 	case KAUTH_NETWORK_INTERFACE_STRIP:
    671 		switch (req) {
    672 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
    673 			if (isroot)
    674 				result = KAUTH_RESULT_ALLOW;
    675 			break;
    676 
    677 		default:
    678 			break;
    679 		}
    680 
    681 		break;
    682 
    683 	case KAUTH_NETWORK_INTERFACE_TUN:
    684 		switch (req) {
    685 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
    686 			if (isroot)
    687 				result = KAUTH_RESULT_ALLOW;
    688 			break;
    689 
    690 		default:
    691 			break;
    692 		}
    693 
    694 		break;
    695 
    696 	case KAUTH_NETWORK_NFS:
    697 		switch (req) {
    698 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
    699 		case KAUTH_REQ_NETWORK_NFS_SVC:
    700 			if (isroot)
    701 				result = KAUTH_RESULT_ALLOW;
    702 
    703 			break;
    704 
    705 		default:
    706 			break;
    707 		}
    708 		break;
    709 
    710 	case KAUTH_NETWORK_SOCKET:
    711 		switch (req) {
    712 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
    713 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
    714 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
    715 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
    716 			if (isroot)
    717 				result = KAUTH_RESULT_ALLOW;
    718 			break;
    719 
    720 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
    721 			if (isroot) {
    722 				result = KAUTH_RESULT_ALLOW;
    723 				break;
    724 			}
    725 
    726 			if (secmodel_suser_curtain) {
    727 				struct socket *so;
    728 				uid_t so_uid;
    729 
    730 				so = (struct socket *)arg1;
    731 				so_uid = so->so_uidinfo->ui_uid;
    732 				if (kauth_cred_geteuid(cred) != so_uid)
    733 					result = KAUTH_RESULT_DENY;
    734 			}
    735 
    736 			break;
    737 
    738 		default:
    739 			break;
    740 		}
    741 
    742 		break;
    743 
    744 
    745 	default:
    746 		break;
    747 	}
    748 
    749 	return (result);
    750 }
    751 
    752 /*
    753  * kauth(9) listener
    754  *
    755  * Security model: Traditional NetBSD
    756  * Scope: Machdep
    757  * Responsibility: Superuser access
    758  */
    759 int
    760 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
    761     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    762 {
    763         bool isroot;
    764         int result;
    765 
    766         isroot = (kauth_cred_geteuid(cred) == 0);
    767         result = KAUTH_RESULT_DEFER;
    768 
    769         switch (action) {
    770 	case KAUTH_MACHDEP_IOPERM_GET:
    771 	case KAUTH_MACHDEP_LDT_GET:
    772 	case KAUTH_MACHDEP_LDT_SET:
    773 	case KAUTH_MACHDEP_MTRR_GET:
    774 		result = KAUTH_RESULT_ALLOW;
    775 		break;
    776 
    777 	case KAUTH_MACHDEP_CACHEFLUSH:
    778 	case KAUTH_MACHDEP_IOPERM_SET:
    779 	case KAUTH_MACHDEP_IOPL:
    780 	case KAUTH_MACHDEP_MTRR_SET:
    781 	case KAUTH_MACHDEP_NVRAM:
    782 	case KAUTH_MACHDEP_UNMANAGEDMEM:
    783 		if (isroot)
    784 			result = KAUTH_RESULT_ALLOW;
    785 		break;
    786 
    787 	default:
    788 		break;
    789 	}
    790 
    791 	return (result);
    792 }
    793 
    794 /*
    795  * kauth(9) listener
    796  *
    797  * Security model: Traditional NetBSD
    798  * Scope: Device
    799  * Responsibility: Superuser access
    800  */
    801 int
    802 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
    803     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    804 {
    805         bool isroot;
    806         int result;
    807 
    808         isroot = (kauth_cred_geteuid(cred) == 0);
    809         result = KAUTH_RESULT_DEFER;
    810 
    811 	switch (action) {
    812 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
    813 	case KAUTH_DEVICE_BLUETOOTH_SEND:
    814 	case KAUTH_DEVICE_BLUETOOTH_RECV:
    815 	case KAUTH_DEVICE_TTY_OPEN:
    816 	case KAUTH_DEVICE_TTY_PRIVSET:
    817 	case KAUTH_DEVICE_TTY_STI:
    818 	case KAUTH_DEVICE_RND_ADDDATA:
    819 	case KAUTH_DEVICE_RND_GETPRIV:
    820 	case KAUTH_DEVICE_RND_SETPRIV:
    821 		if (isroot)
    822 			result = KAUTH_RESULT_ALLOW;
    823 		break;
    824 
    825 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
    826 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
    827 		enum kauth_device_req req;
    828 
    829 		req = (enum kauth_device_req)arg0;
    830 		switch (req) {
    831 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
    832 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
    833 			if (isroot)
    834 				result = KAUTH_RESULT_ALLOW;
    835 			break;
    836 
    837 		default:
    838 			break;
    839 		}
    840 
    841 		break;
    842 		}
    843 
    844 	case KAUTH_DEVICE_RAWIO_SPEC:
    845 	case KAUTH_DEVICE_RAWIO_PASSTHRU:
    846 		/*
    847 		 * Decision is root-agnostic.
    848 		 *
    849 		 * Both requests can be issued on devices subject to their
    850 		 * permission bits.
    851 		 */
    852 		result = KAUTH_RESULT_ALLOW;
    853 		break;
    854 
    855 	case KAUTH_DEVICE_GPIO_PINSET:
    856 		/*
    857 		 * root can access gpio pins, secmodel_securlevel can veto
    858 		 * this decision.
    859 		 */
    860 		if (isroot)
    861 			result = KAUTH_RESULT_ALLOW;
    862 		break;
    863 
    864 	default:
    865 		break;
    866 	}
    867 
    868 	return (result);
    869 }
    870 
    871 int
    872 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
    873     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    874 {
    875 	bool isroot;
    876 	int result;
    877 
    878 	isroot = (kauth_cred_geteuid(cred) == 0);
    879 	result = KAUTH_RESULT_DEFER;
    880 
    881 	if (isroot)
    882 		result = KAUTH_RESULT_ALLOW;
    883 
    884 	return (result);
    885 }
    886 
    887