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