Home | History | Annotate | Line # | Download | only in suser
secmodel_suser.c revision 1.33
      1 /* $NetBSD: secmodel_suser.c,v 1.33 2009/12/24 19:02:07 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.33 2009/12/24 19:02:07 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 }
    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 	default:
    241 		break;
    242 	}
    243 
    244 	return (result);
    245 }
    246 
    247 static int
    248 suser_usermount_policy(kauth_cred_t cred, enum kauth_system_req req, void *arg1,
    249     void *arg2)
    250 {
    251 	struct mount *mp;
    252 	u_long flags;
    253 	int result;
    254 
    255 	result = KAUTH_RESULT_DEFER;
    256 
    257 	if (!dovfsusermount)
    258 		return result;
    259 
    260 	switch (req) {
    261 	case KAUTH_REQ_SYSTEM_MOUNT_NEW:
    262 		mp = ((struct vnode *)arg1)->v_mount;
    263 		flags= (u_long)arg2;
    264 
    265 		if (usermount_common_policy(mp, flags) != 0)
    266 			break;
    267 
    268 		result = KAUTH_RESULT_ALLOW;
    269 
    270 		break;
    271 
    272 	case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
    273 		mp = arg1;
    274 
    275 		/* Must own the mount. */
    276 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
    277 			break;
    278 
    279 		result = KAUTH_RESULT_ALLOW;
    280 
    281 		break;
    282 
    283 	case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
    284 		mp = arg1;
    285 		flags = (u_long)arg2;
    286 
    287 		/* Must own the mount. */
    288 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
    289 			break;
    290 
    291 		if (usermount_common_policy(mp, flags) != 0)
    292 			break;
    293 
    294 		result = KAUTH_RESULT_ALLOW;
    295 
    296 		break;
    297 
    298 	default:
    299 		break;
    300 	}
    301 
    302 	return result;
    303 }
    304 
    305 /*
    306  * kauth(9) listener
    307  *
    308  * Security model: Traditional NetBSD
    309  * Scope: System
    310  * Responsibility: Superuser access
    311  */
    312 int
    313 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
    314     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    315 {
    316 	bool isroot;
    317 	int result;
    318 	enum kauth_system_req req;
    319 
    320 	isroot = (kauth_cred_geteuid(cred) == 0);
    321 	result = KAUTH_RESULT_DEFER;
    322 	req = (enum kauth_system_req)arg0;
    323 
    324 	switch (action) {
    325 	case KAUTH_SYSTEM_CPU:
    326 		switch (req) {
    327 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
    328 			if (isroot)
    329 				result = KAUTH_RESULT_ALLOW;
    330 
    331 			break;
    332 
    333 		default:
    334 			break;
    335 		}
    336 
    337 		break;
    338 
    339 	case KAUTH_SYSTEM_FS_QUOTA:
    340 		switch (req) {
    341 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
    342 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
    343 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
    344 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
    345 			if (isroot)
    346 				result = KAUTH_RESULT_ALLOW;
    347 			break;
    348 
    349 		default:
    350 			break;
    351 		}
    352 
    353 		break;
    354 
    355 	case KAUTH_SYSTEM_MOUNT:
    356 		switch (req) {
    357 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
    358 			if (isroot) {
    359 				result = KAUTH_RESULT_ALLOW;
    360 				break;
    361 			}
    362 
    363 			break;
    364 
    365 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
    366 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
    367 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
    368 			if (isroot) {
    369 				result = KAUTH_RESULT_ALLOW;
    370 				break;
    371 			}
    372 
    373 			result = suser_usermount_policy(cred, req, arg1, arg2);
    374 
    375 			break;
    376 
    377 		default:
    378 			break;
    379 		}
    380 
    381 		break;
    382 
    383 	case KAUTH_SYSTEM_PSET:
    384 		switch (req) {
    385 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
    386 		case KAUTH_REQ_SYSTEM_PSET_BIND:
    387 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
    388 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
    389 			if (isroot)
    390 				result = KAUTH_RESULT_ALLOW;
    391 
    392 			break;
    393 
    394 		default:
    395 			break;
    396 		}
    397 
    398 		break;
    399 
    400 	case KAUTH_SYSTEM_TIME:
    401 		switch (req) {
    402 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
    403 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
    404 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
    405 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
    406 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
    407 			if (isroot)
    408 				result = KAUTH_RESULT_ALLOW;
    409 			break;
    410 
    411 		default:
    412 			break;
    413 		}
    414 		break;
    415 
    416 	case KAUTH_SYSTEM_SYSCTL:
    417 		switch (req) {
    418 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
    419 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
    420 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
    421 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
    422 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
    423 			if (isroot)
    424 				result = KAUTH_RESULT_ALLOW;
    425 			break;
    426 
    427 		default:
    428 			break;
    429 		}
    430 
    431 		break;
    432 
    433 	case KAUTH_SYSTEM_SWAPCTL:
    434 	case KAUTH_SYSTEM_ACCOUNTING:
    435 	case KAUTH_SYSTEM_REBOOT:
    436 	case KAUTH_SYSTEM_CHROOT:
    437 	case KAUTH_SYSTEM_FILEHANDLE:
    438 	case KAUTH_SYSTEM_MKNOD:
    439 	case KAUTH_SYSTEM_SETIDCORE:
    440 	case KAUTH_SYSTEM_MODULE:
    441 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
    442 		if (isroot)
    443 			result = KAUTH_RESULT_ALLOW;
    444 		break;
    445 
    446 	case KAUTH_SYSTEM_DEBUG:
    447 		switch (req) {
    448 		case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
    449 			if (isroot)
    450 				result = KAUTH_RESULT_ALLOW;
    451 
    452 			break;
    453 
    454 		default:
    455 			break;
    456 		}
    457 
    458 		break;
    459 
    460 	case KAUTH_SYSTEM_CHSYSFLAGS:
    461 		/*
    462 		 * Needs to be checked in conjunction with the immutable and
    463 		 * append-only flags (usually). Should be handled differently.
    464 		 * Infects ufs, ext2fs, tmpfs, and rump.
    465 		 */
    466 		if (isroot)
    467 			result = KAUTH_RESULT_ALLOW;
    468 
    469 		break;
    470 
    471 	default:
    472 		break;
    473 	}
    474 
    475 	return (result);
    476 }
    477 
    478 /*
    479  * kauth(9) listener
    480  *
    481  * Security model: Traditional NetBSD
    482  * Scope: Process
    483  * Responsibility: Superuser access
    484  */
    485 int
    486 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
    487     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    488 {
    489 	struct proc *p;
    490 	bool isroot;
    491 	int result;
    492 
    493 	isroot = (kauth_cred_geteuid(cred) == 0);
    494 	result = KAUTH_RESULT_DEFER;
    495 	p = arg0;
    496 
    497 	switch (action) {
    498 	case KAUTH_PROCESS_SIGNAL:
    499 	case KAUTH_PROCESS_KTRACE:
    500 	case KAUTH_PROCESS_PROCFS:
    501 	case KAUTH_PROCESS_PTRACE:
    502 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
    503 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
    504 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
    505 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
    506 	case KAUTH_PROCESS_SETID:
    507 	case KAUTH_PROCESS_KEVENT_FILTER:
    508 	case KAUTH_PROCESS_NICE:
    509 	case KAUTH_PROCESS_FORK:
    510 	case KAUTH_PROCESS_CORENAME:
    511 	case KAUTH_PROCESS_STOPFLAG:
    512 		if (isroot)
    513 			result = KAUTH_RESULT_ALLOW;
    514 
    515 		break;
    516 
    517 	case KAUTH_PROCESS_CANSEE: {
    518 		unsigned long req;
    519 
    520 		req = (unsigned long)arg1;
    521 
    522 		switch (req) {
    523 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
    524 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
    525 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
    526 			if (isroot) {
    527 				result = KAUTH_RESULT_ALLOW;
    528 				break;
    529 			}
    530 
    531 			if (secmodel_suser_curtain) {
    532 				if (!kauth_cred_uidmatch(cred, p->p_cred))
    533 					result = KAUTH_RESULT_DENY;
    534 			}
    535 
    536 			break;
    537 
    538 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
    539 			if (isroot)
    540 				result = KAUTH_RESULT_ALLOW;
    541 
    542 			break;
    543 
    544 		default:
    545 			break;
    546 		}
    547 
    548 		break;
    549 		}
    550 
    551 	case KAUTH_PROCESS_RLIMIT: {
    552 		enum kauth_process_req req;
    553 
    554 		req = (enum kauth_process_req)(unsigned long)arg1;
    555 
    556 		switch (req) {
    557 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
    558 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
    559 			if (isroot)
    560 				result = KAUTH_RESULT_ALLOW;
    561 
    562 			break;
    563 
    564 		default:
    565 			break;
    566 		}
    567 
    568 		break;
    569 		}
    570 
    571 	default:
    572 		break;
    573 	}
    574 
    575 	return (result);
    576 }
    577 
    578 /*
    579  * kauth(9) listener
    580  *
    581  * Security model: Traditional NetBSD
    582  * Scope: Network
    583  * Responsibility: Superuser access
    584  */
    585 int
    586 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
    587     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    588 {
    589 	bool isroot;
    590 	int result;
    591 	enum kauth_network_req req;
    592 
    593 	isroot = (kauth_cred_geteuid(cred) == 0);
    594 	result = KAUTH_RESULT_DEFER;
    595 	req = (enum kauth_network_req)arg0;
    596 
    597 	switch (action) {
    598 	case KAUTH_NETWORK_ALTQ:
    599 		switch (req) {
    600 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
    601 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
    602 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
    603 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
    604 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
    605 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
    606 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
    607 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
    608 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
    609 		case KAUTH_REQ_NETWORK_ALTQ_RED:
    610 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
    611 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
    612 			if (isroot)
    613 				result = KAUTH_RESULT_ALLOW;
    614 			break;
    615 
    616 		default:
    617 			break;
    618 		}
    619 
    620 		break;
    621 
    622 	case KAUTH_NETWORK_BIND:
    623 		switch (req) {
    624 		case KAUTH_REQ_NETWORK_BIND_PORT:
    625 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
    626 			if (isroot)
    627 				result = KAUTH_RESULT_ALLOW;
    628 			break;
    629 
    630 		default:
    631 			break;
    632 		}
    633 		break;
    634 
    635 	case KAUTH_NETWORK_FIREWALL:
    636 		switch (req) {
    637 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
    638 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
    639 			if (isroot)
    640 				result = KAUTH_RESULT_ALLOW;
    641 
    642 			break;
    643 
    644 		default:
    645 			break;
    646 		}
    647 		break;
    648 
    649 	case KAUTH_NETWORK_FORWSRCRT:
    650 	case KAUTH_NETWORK_ROUTE:
    651 		if (isroot)
    652 			result = KAUTH_RESULT_ALLOW;
    653 
    654 		break;
    655 
    656 	case KAUTH_NETWORK_INTERFACE:
    657 		switch (req) {
    658 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
    659 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
    660 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
    661 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
    662 			if (isroot)
    663 				result = KAUTH_RESULT_ALLOW;
    664 			break;
    665 
    666 		default:
    667 			break;
    668 		}
    669 		break;
    670 
    671 	case KAUTH_NETWORK_INTERFACE_PPP:
    672 		switch (req) {
    673 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
    674 			if (isroot)
    675 				result = KAUTH_RESULT_ALLOW;
    676 			break;
    677 
    678 		default:
    679 			break;
    680 		}
    681 
    682 		break;
    683 
    684 	case KAUTH_NETWORK_INTERFACE_SLIP:
    685 		switch (req) {
    686 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
    687 			if (isroot)
    688 				result = KAUTH_RESULT_ALLOW;
    689 			break;
    690 
    691 		default:
    692 			break;
    693 		}
    694 
    695 		break;
    696 
    697 	case KAUTH_NETWORK_INTERFACE_STRIP:
    698 		switch (req) {
    699 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
    700 			if (isroot)
    701 				result = KAUTH_RESULT_ALLOW;
    702 			break;
    703 
    704 		default:
    705 			break;
    706 		}
    707 
    708 		break;
    709 
    710 	case KAUTH_NETWORK_INTERFACE_TUN:
    711 		switch (req) {
    712 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
    713 			if (isroot)
    714 				result = KAUTH_RESULT_ALLOW;
    715 			break;
    716 
    717 		default:
    718 			break;
    719 		}
    720 
    721 		break;
    722 
    723 	case KAUTH_NETWORK_NFS:
    724 		switch (req) {
    725 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
    726 		case KAUTH_REQ_NETWORK_NFS_SVC:
    727 			if (isroot)
    728 				result = KAUTH_RESULT_ALLOW;
    729 
    730 			break;
    731 
    732 		default:
    733 			break;
    734 		}
    735 		break;
    736 
    737 	case KAUTH_NETWORK_SOCKET:
    738 		switch (req) {
    739 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
    740 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
    741 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
    742 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
    743 			if (isroot)
    744 				result = KAUTH_RESULT_ALLOW;
    745 			break;
    746 
    747 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
    748 			if (isroot) {
    749 				result = KAUTH_RESULT_ALLOW;
    750 				break;
    751 			}
    752 
    753 			if (secmodel_suser_curtain) {
    754 				struct socket *so;
    755 				uid_t so_uid;
    756 
    757 				so = (struct socket *)arg1;
    758 				so_uid = so->so_uidinfo->ui_uid;
    759 				if (kauth_cred_geteuid(cred) != so_uid)
    760 					result = KAUTH_RESULT_DENY;
    761 			}
    762 
    763 			break;
    764 
    765 		default:
    766 			break;
    767 		}
    768 
    769 		break;
    770 
    771 
    772 	default:
    773 		break;
    774 	}
    775 
    776 	return (result);
    777 }
    778 
    779 /*
    780  * kauth(9) listener
    781  *
    782  * Security model: Traditional NetBSD
    783  * Scope: Machdep
    784  * Responsibility: Superuser access
    785  */
    786 int
    787 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
    788     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    789 {
    790         bool isroot;
    791         int result;
    792 
    793         isroot = (kauth_cred_geteuid(cred) == 0);
    794         result = KAUTH_RESULT_DEFER;
    795 
    796         switch (action) {
    797 	case KAUTH_MACHDEP_IOPERM_GET:
    798 	case KAUTH_MACHDEP_LDT_GET:
    799 	case KAUTH_MACHDEP_LDT_SET:
    800 	case KAUTH_MACHDEP_MTRR_GET:
    801 	case KAUTH_MACHDEP_CACHEFLUSH:
    802 	case KAUTH_MACHDEP_IOPERM_SET:
    803 	case KAUTH_MACHDEP_IOPL:
    804 	case KAUTH_MACHDEP_MTRR_SET:
    805 	case KAUTH_MACHDEP_NVRAM:
    806 	case KAUTH_MACHDEP_UNMANAGEDMEM:
    807 		if (isroot)
    808 			result = KAUTH_RESULT_ALLOW;
    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: Device
    823  * Responsibility: Superuser access
    824  */
    825 int
    826 secmodel_suser_device_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 = (kauth_cred_geteuid(cred) == 0);
    833         result = KAUTH_RESULT_DEFER;
    834 
    835 	switch (action) {
    836 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
    837 	case KAUTH_DEVICE_BLUETOOTH_SEND:
    838 	case KAUTH_DEVICE_BLUETOOTH_RECV:
    839 	case KAUTH_DEVICE_TTY_OPEN:
    840 	case KAUTH_DEVICE_TTY_PRIVSET:
    841 	case KAUTH_DEVICE_TTY_STI:
    842 	case KAUTH_DEVICE_RND_ADDDATA:
    843 	case KAUTH_DEVICE_RND_GETPRIV:
    844 	case KAUTH_DEVICE_RND_SETPRIV:
    845 		if (isroot)
    846 			result = KAUTH_RESULT_ALLOW;
    847 		break;
    848 
    849 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
    850 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
    851 		enum kauth_device_req req;
    852 
    853 		req = (enum kauth_device_req)arg0;
    854 		switch (req) {
    855 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
    856 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
    857 			if (isroot)
    858 				result = KAUTH_RESULT_ALLOW;
    859 			break;
    860 
    861 		default:
    862 			break;
    863 		}
    864 
    865 		break;
    866 		}
    867 
    868 	case KAUTH_DEVICE_GPIO_PINSET:
    869 		/*
    870 		 * root can access gpio pins, secmodel_securlevel can veto
    871 		 * this decision.
    872 		 */
    873 		if (isroot)
    874 			result = KAUTH_RESULT_ALLOW;
    875 		break;
    876 
    877 	default:
    878 		break;
    879 	}
    880 
    881 	return (result);
    882 }
    883 
    884 int
    885 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
    886     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    887 {
    888 	bool isroot;
    889 	int result;
    890 
    891 	isroot = (kauth_cred_geteuid(cred) == 0);
    892 	result = KAUTH_RESULT_DEFER;
    893 
    894 	if (isroot)
    895 		result = KAUTH_RESULT_ALLOW;
    896 
    897 	return (result);
    898 }
    899 
    900