Home | History | Annotate | Line # | Download | only in secmodel
      1 /* $NetBSD: secmodel_example.c,v 1.30 2024/02/02 22:14:04 andvar Exp $ */
      2 
      3 /*
      4  * This file is placed in the public domain.
      5  */
      6 
      7 /*
      8  * Skeleton file for building a NetBSD security model from scratch, containing
      9  * every kauth(9) scope, action, and request, as well as some coding hints.
     10  *
     11  * This file will be kept in-sync with the official NetBSD kernel, so *always*
     12  * use the latest revision.
     13  */
     14 
     15 #include <sys/cdefs.h>
     16 __KERNEL_RCSID(0, "$NetBSD: secmodel_example.c,v 1.30 2024/02/02 22:14:04 andvar Exp $");
     17 
     18 #include <sys/types.h>
     19 #include <sys/param.h>
     20 #include <sys/kauth.h>
     21 
     22 #include <sys/module.h>
     23 #include <sys/sysctl.h>
     24 
     25 #include <secmodel/secmodel.h>
     26 #include <secmodel/example/example.h>
     27 
     28 MODULE(MODULE_CLASS_SECMODEL, secmodel_example, NULL);
     29 
     30 static secmodel_t example_sm;
     31 static struct sysctllog *sysctl_example_log;
     32 
     33 static kauth_listener_t l_device, l_generic, l_machdep, l_network,
     34     l_process, l_system, l_vnode;
     35 
     36 static void secmodel_example_init(void);
     37 static void secmodel_example_start(void);
     38 static void secmodel_example_stop(void);
     39 
     40 static void sysctl_security_example_setup(struct sysctllog **);
     41 
     42 static int secmodel_example_device_cb(kauth_cred_t, kauth_action_t, void *,
     43     void *, void *, void *, void *);
     44 static int secmodel_example_generic_cb(kauth_cred_t, kauth_action_t, void *,
     45     void *, void *, void *, void *);
     46 static int secmodel_example_machdep_cb(kauth_cred_t, kauth_action_t, void *,
     47     void *, void *, void *, void *);
     48 static int secmodel_example_network_cb(kauth_cred_t, kauth_action_t, void *,
     49     void *, void *, void *, void *);
     50 static int secmodel_example_process_cb(kauth_cred_t, kauth_action_t, void *,
     51     void *, void *, void *, void *);
     52 static int secmodel_example_system_cb(kauth_cred_t, kauth_action_t, void *,
     53     void *, void *, void *, void *);
     54 static int secmodel_example_vnode_cb(kauth_cred_t, kauth_action_t, void *,
     55     void *, void *, void *, void *);
     56 
     57 /*
     58  * Creates sysctl(7) entries expected from a security model.
     59  */
     60 static void
     61 sysctl_security_example_setup(struct sysctllog **clog)
     62 {
     63 	const struct sysctlnode *rnode;
     64 
     65 	sysctl_createv(clog, 0, NULL, &rnode,
     66 		       CTLFLAG_PERMANENT,
     67 		       CTLTYPE_NODE, "security", NULL,
     68 		       NULL, 0, NULL, 0,
     69 		       CTL_CREATE, CTL_EOL);
     70 
     71 	sysctl_createv(clog, 0, &rnode, &rnode,
     72 		       CTLFLAG_PERMANENT,
     73 		       CTLTYPE_NODE, "models", NULL,
     74 		       NULL, 0, NULL, 0,
     75 		       CTL_CREATE, CTL_EOL);
     76 
     77 	sysctl_createv(clog, 0, &rnode, &rnode,
     78 		       CTLFLAG_PERMANENT,
     79 		       CTLTYPE_NODE, "example",
     80 		       SYSCTL_DESCR("example security model"),
     81 		       NULL, 0, NULL, 0,
     82 		       CTL_CREATE, CTL_EOL);
     83 
     84 	sysctl_createv(clog, 0, &rnode, NULL,
     85 		       CTLFLAG_PERMANENT,
     86 		       CTLTYPE_STRING, "name", NULL,
     87 		       NULL, 0, __UNCONST(SECMODEL_EXAMPLE_NAME), 0
     88 		       CTL_CREATE, CTL_EOL);
     89 }
     90 
     91 /*
     92  * Initialize the security model.
     93  */
     94 static void
     95 secmodel_example_init(void)
     96 {
     97 
     98 	/* typically used to set static variables and states */
     99 }
    100 
    101 /*
    102  * Start the security model.
    103  */
    104 static void
    105 secmodel_example_start(void)
    106 {
    107 
    108 	/* register listeners */
    109 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
    110 	    secmodel_example_device_cb, NULL);
    111 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
    112 	    secmodel_example_generic_cb, NULL);
    113 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
    114 	    secmodel_example_machdep_cb, NULL);
    115 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
    116 	    secmodel_example_network_cb, NULL);
    117 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
    118 	    secmodel_example_process_cb, NULL);
    119 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
    120 	    secmodel_example_system_cb, NULL);
    121 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
    122 	    secmodel_example_vnode_cb, NULL);
    123 }
    124 
    125 /*
    126  * Stop the security model.
    127  */
    128 static void
    129 secmodel_example_stop(void)
    130 {
    131 
    132 	/* unregister listeners */
    133 	kauth_unlisten_scope(l_device);
    134 	kauth_unlisten_scope(l_generic);
    135 	kauth_unlisten_scope(l_machdep);
    136 	kauth_unlisten_scope(l_network);
    137 	kauth_unlisten_scope(l_process);
    138 	kauth_unlisten_scope(l_system);
    139 	kauth_unlisten_scope(l_vnode);
    140 }
    141 
    142 /*
    143  * An evaluation routine example. That one will allow any secmodel(9)
    144  * to request to secmodel_example if "is-example-useful". We consider
    145  * that it is, so return yes.
    146  */
    147 static int
    148 secmodel_example_eval(const char *what, void *arg, void *ret)
    149 {
    150 	int error = 0;
    151 
    152 	if (strcasecmp(what, "is-example-useful") == 0) {
    153 		bool *bp = ret;
    154 		*bp = true;
    155 	} else {
    156 		error = ENOENT;
    157 	}
    158 
    159 	return error;
    160 }
    161 
    162 /*
    163  * Module attachment/detachment routine. Whether the secmodel(9) is
    164  * builtin or loaded dynamically, it is in charge of initializing, starting
    165  * and stopping the module. See module(9).
    166  */
    167 
    168 static int
    169 secmodel_example_modcmd(modcmd_t cmd, void *arg)
    170 {
    171 	int error = 0;
    172 
    173 	switch (cmd) {
    174 	case MODULE_CMD_INIT:
    175 		secmodel_example_init();
    176 		secmodel_example_start();
    177 		sysctl_security_example_setup(&sysctl_example_log);
    178 
    179 		error = secmodel_register(&example_sm,
    180 		    SECMODEL_EXAMPLE_ID, SECMODEL_EXAMPLE_NAME,
    181 		    NULL, secmodel_example_eval, NULL);
    182 		if (error != 0)
    183 			printf("secmodel_example_modcmd::init: "
    184 			    "secmodel_register returned %d\n", error);
    185 
    186 		break;
    187 
    188 	case MODULE_CMD_FINI:
    189 		error = secmodel_deregister(example_sm);
    190 		if (error != 0)
    191 			printf("secmodel_example_modcmd::fini: "
    192 			    "secmodel_deregister returned %d\n", error);
    193 
    194 		sysctl_teardown(&sysctl_example_log);
    195 		secmodel_example_stop();
    196 		break;
    197 
    198 	default:
    199 		error = ENOTTY;
    200 		break;
    201 	}
    202 
    203 	return error;
    204 }
    205 
    206 /*
    207  * Security model: example
    208  * Scope: Generic
    209  */
    210 static int
    211 secmodel_example_generic_cb(kauth_cred_t cred, kauth_action_t action,
    212     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    213 {
    214 	int result;
    215 
    216 	result = KAUTH_RESULT_DENY;
    217 
    218 	switch(action) {
    219 	case KAUTH_GENERIC_ISSUSER:
    220 	default:
    221 		result = KAUTH_RESULT_DEFER;
    222 		break;
    223 	}
    224 
    225 	return (result);
    226 }
    227 
    228 /*
    229  * Security model: example
    230  * Scope: System
    231  */
    232 static int
    233 secmodel_example_system_cb(kauth_cred_t cred, kauth_action_t action,
    234     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    235 {
    236 	int result;
    237 	enum kauth_system_req req;
    238 
    239 	result = KAUTH_RESULT_DENY;
    240 
    241 	req = (enum kauth_system_req)arg0;
    242 
    243 	switch (action) {
    244 	case KAUTH_SYSTEM_MOUNT:
    245 		switch (req) {
    246 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
    247 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
    248 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
    249 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
    250 		default:
    251 			result = KAUTH_RESULT_DEFER;
    252 			break;
    253 		}
    254 		break;
    255 
    256 	case KAUTH_SYSTEM_TIME:
    257 		switch (req) {
    258 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
    259 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
    260 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
    261 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
    262 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
    263 		default:
    264 			result = KAUTH_RESULT_DEFER;
    265 			break;
    266 		}
    267 		break;
    268 
    269 	case KAUTH_SYSTEM_SYSCTL:
    270 		switch (req) {
    271 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
    272 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
    273 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
    274 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
    275 		default:
    276 			result = KAUTH_RESULT_DEFER;
    277 			break;
    278 		}
    279 		break;
    280 
    281 	case KAUTH_SYSTEM_CHROOT:
    282 		switch (req) {
    283 		case KAUTH_REQ_SYSTEM_CHROOT_CHROOT:
    284 		case KAUTH_REQ_SYSTEM_CHROOT_FCHROOT:
    285 		default:
    286 			result = KAUTH_RESULT_DEFER;
    287 			break;
    288 		}
    289 		break;
    290 
    291 	case KAUTH_SYSTEM_CPU:
    292 		switch (req) {
    293 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
    294 		default:
    295 			result = KAUTH_RESULT_DEFER;
    296 			break;
    297 		}
    298 		break;
    299 
    300 	case KAUTH_SYSTEM_DEBUG:
    301 		break;
    302 
    303 	case KAUTH_SYSTEM_PSET:
    304 		switch (req) {
    305 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
    306 		case KAUTH_REQ_SYSTEM_PSET_BIND:
    307 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
    308 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
    309 		default:
    310 			result = KAUTH_RESULT_DEFER;
    311 			break;
    312 		}
    313 		break;
    314 
    315 	case KAUTH_SYSTEM_FS_QUOTA:
    316 		switch (req) {
    317 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
    318 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
    319 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
    320 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
    321 		default:
    322 			result = KAUTH_RESULT_DEFER;
    323 			break;
    324 		}
    325 		break;
    326 
    327 	case KAUTH_SYSTEM_FILEHANDLE:
    328 	case KAUTH_SYSTEM_MKNOD:
    329 	case KAUTH_SYSTEM_MODULE:
    330 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
    331 	case KAUTH_SYSTEM_SETIDCORE:
    332 	case KAUTH_SYSTEM_SWAPCTL:
    333 	case KAUTH_SYSTEM_ACCOUNTING:
    334 	case KAUTH_SYSTEM_REBOOT:
    335 	default:
    336 		result = KAUTH_RESULT_DEFER;
    337 		break;
    338 	}
    339 
    340 	return (result);
    341 }
    342 
    343 /*
    344  * kauth(9) listener
    345  *
    346  * Security model: example
    347  * Scope: Process
    348  */
    349 static int
    350 secmodel_example_process_cb(kauth_cred_t cred, kauth_action_t action,
    351     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    352 {
    353 	int result;
    354 
    355 	result = KAUTH_RESULT_DENY;
    356 
    357 	switch (action) {
    358 	case KAUTH_PROCESS_KTRACE:
    359 		switch ((u_long)arg1) {
    360 		case KAUTH_REQ_PROCESS_KTRACE_PERSISTENT:
    361 		default:
    362 			result = KAUTH_RESULT_DEFER;
    363 			break;
    364 		}
    365 		break;
    366 
    367 	case KAUTH_PROCESS_CANSEE:
    368 		switch ((u_long)arg1) {
    369 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
    370 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
    371 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
    372 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
    373 		case KAUTH_REQ_PROCESS_CANSEE_EPROC:
    374 		default:
    375 			result = KAUTH_RESULT_DEFER;
    376 			break;
    377 		}
    378 		break;
    379 
    380 	case KAUTH_PROCESS_CORENAME:
    381 		switch ((u_long)arg1) {
    382 		case KAUTH_REQ_PROCESS_CORENAME_GET:
    383 		case KAUTH_REQ_PROCESS_CORENAME_SET:
    384 		default:
    385 			result = KAUTH_RESULT_DEFER;
    386 			break;
    387 		}
    388 		break;
    389 
    390 	case KAUTH_PROCESS_RLIMIT:
    391 		switch ((u_long)arg1) {
    392 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
    393 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
    394 		default:
    395 			result = KAUTH_RESULT_DEFER;
    396 			break;
    397 		}
    398 		break;
    399 
    400 	case KAUTH_PROCESS_STOPFLAG:
    401 	case KAUTH_PROCESS_PTRACE:
    402 	case KAUTH_PROCESS_SIGNAL:
    403 	case KAUTH_PROCESS_PROCFS:
    404 	case KAUTH_PROCESS_FORK:
    405 	case KAUTH_PROCESS_KEVENT_FILTER:
    406 	case KAUTH_PROCESS_NICE:
    407 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
    408 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
    409 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
    410 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
    411 	case KAUTH_PROCESS_SETID:
    412 	default:
    413 		result = KAUTH_RESULT_DEFER;
    414 		break;
    415 	}
    416 
    417 	return (result);
    418 }
    419 
    420 /*
    421  * kauth(9) listener
    422  *
    423  * Security model: example
    424  * Scope: Network
    425  */
    426 static int
    427 secmodel_example_network_cb(kauth_cred_t cred, kauth_action_t action,
    428     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    429 {
    430 	int result;
    431 
    432 	result = KAUTH_RESULT_DENY;
    433 
    434 	switch (action) {
    435 	case KAUTH_NETWORK_ALTQ:
    436 		switch((u_long)arg0) {
    437 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
    438 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
    439 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
    440 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
    441 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
    442 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
    443 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
    444 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
    445 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
    446 		case KAUTH_REQ_NETWORK_ALTQ_RED:
    447 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
    448 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
    449 		default:
    450 			result = KAUTH_RESULT_DEFER;
    451 			break;
    452 		}
    453 		break;
    454 
    455 	case KAUTH_NETWORK_BIND:
    456 		switch((u_long)arg0) {
    457 		case KAUTH_REQ_NETWORK_BIND_PORT:
    458 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
    459 		default:
    460 			result = KAUTH_RESULT_DEFER;
    461 			break;
    462 		}
    463 		break;
    464 
    465 	case KAUTH_NETWORK_FIREWALL:
    466 		switch ((u_long)arg0) {
    467 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
    468 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
    469 		default:
    470 			result = KAUTH_RESULT_DEFER;
    471 			break;
    472 		}
    473 		break;
    474 
    475 	case KAUTH_NETWORK_FORWSRCRT:
    476 		break;
    477 
    478 	case KAUTH_NETWORK_INTERFACE:
    479 		switch ((u_long)arg0) {
    480 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
    481 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
    482 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
    483 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
    484 		default:
    485 			result = KAUTH_RESULT_DEFER;
    486 			break;
    487 		}
    488 		break;
    489 
    490 	case KAUTH_NETWORK_NFS:
    491 		switch ((u_long)arg0) {
    492 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
    493 		case KAUTH_REQ_NETWORK_NFS_SVC:
    494 		default:
    495 			result = KAUTH_RESULT_DEFER;
    496 			break;
    497 		}
    498 		break;
    499 
    500 	case KAUTH_NETWORK_INTERFACE_PPP:
    501 		switch ((u_long)arg0) {
    502 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
    503 		default:
    504 			result = KAUTH_RESULT_DEFER;
    505 			break;
    506 		}
    507 		break;
    508 
    509 	case KAUTH_NETWORK_INTERFACE_SLIP:
    510 		switch ((u_long)arg0) {
    511 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
    512 		default:
    513 			result = KAUTH_RESULT_DEFER;
    514 			break;
    515 		}
    516 		break;
    517 
    518 	case KAUTH_NETWORK_ROUTE:
    519 		break;
    520 
    521 	case KAUTH_NETWORK_SOCKET:
    522 		switch((u_long)arg0) {
    523 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
    524 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
    525 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
    526 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
    527 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
    528 		default:
    529 			result = KAUTH_RESULT_DEFER;
    530 			break;
    531 		}
    532 		break;
    533 
    534 		break;
    535 	case KAUTH_NETWORK_INTERFACE_TUN:
    536 		switch ((u_long)arg0) {
    537 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
    538 		default:
    539 			result = KAUTH_RESULT_DEFER;
    540 			break;
    541 		}
    542 		break;
    543 
    544 	default:
    545 		result = KAUTH_RESULT_DEFER;
    546 		break;
    547 	}
    548 
    549 	return (result);
    550 }
    551 
    552 /*
    553  * kauth(9) listener
    554  *
    555  * Security model: example
    556  * Scope: Machdep
    557  */
    558 static int
    559 secmodel_example_machdep_cb(kauth_cred_t cred, kauth_action_t action,
    560     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    561 {
    562 	int result;
    563 
    564 	result = KAUTH_RESULT_DENY;
    565 
    566 	switch (action) {
    567 	case KAUTH_MACHDEP_CACHEFLUSH:
    568 	case KAUTH_MACHDEP_IOPERM_GET:
    569 	case KAUTH_MACHDEP_IOPERM_SET:
    570 	case KAUTH_MACHDEP_IOPL:
    571 	case KAUTH_MACHDEP_LDT_GET:
    572 	case KAUTH_MACHDEP_LDT_SET:
    573 	case KAUTH_MACHDEP_MTRR_GET:
    574 	case KAUTH_MACHDEP_MTRR_SET:
    575 	case KAUTH_MACHDEP_NVRAM:
    576 	case KAUTH_MACHDEP_UNMANAGEDMEM:
    577 	default:
    578 		result = KAUTH_RESULT_DEFER;
    579 		break;
    580 	}
    581 
    582 	return (result);
    583 }
    584 
    585 /*
    586  * kauth(9) listener
    587  *
    588  * Security model: example
    589  * Scope: Device
    590  */
    591 static int
    592 secmodel_example_device_cb(kauth_cred_t cred, kauth_action_t action,
    593     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    594 {
    595 	int result;
    596 
    597 	result = KAUTH_RESULT_DENY;
    598 
    599 	switch (action) {
    600 	case KAUTH_DEVICE_TTY_OPEN:
    601 	case KAUTH_DEVICE_TTY_PRIVSET:
    602 	case KAUTH_DEVICE_TTY_STI:
    603 		break;
    604 
    605 	case KAUTH_DEVICE_RAWIO_SPEC:
    606 		switch ((u_long)arg0) {
    607 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
    608 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
    609 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
    610 			break;
    611 
    612 		default:
    613 			result = KAUTH_RESULT_DEFER;
    614 			break;
    615 		}
    616 		break;
    617 
    618 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
    619 		switch ((u_long)arg0) {
    620 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
    621 		default:
    622 			result = KAUTH_RESULT_DEFER;
    623 			break;
    624 		}
    625 		break;
    626 
    627 	case KAUTH_DEVICE_BLUETOOTH_BTUART:
    628 		switch ((u_long)arg0) {
    629 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
    630 		default:
    631 			result = KAUTH_RESULT_DEFER;
    632 			break;
    633 		}
    634 		break;
    635 
    636 	case KAUTH_DEVICE_RAWIO_PASSTHRU:
    637 	case KAUTH_DEVICE_BLUETOOTH_RECV:
    638 	case KAUTH_DEVICE_BLUETOOTH_SEND:
    639 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
    640 	default:
    641 		result = KAUTH_RESULT_DEFER;
    642 		break;
    643 	}
    644 
    645 	return (result);
    646 }
    647 
    648 /*
    649  * kauth(9) listener
    650  *
    651  * Security model: example
    652  * Scope: Vnode
    653  */
    654 static int
    655 secmodel_example_vnode_cb(kauth_cred_t cred, kauth_action_t action,
    656     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    657 {
    658 	int result;
    659 
    660 	result = KAUTH_RESULT_DENY;
    661 
    662 	switch (action) {
    663 	case KAUTH_VNODE_READ_DATA:
    664 	  /* KAUTH_VNODE_LIST_DIRECTORY: */
    665 		result = KAUTH_RESULT_DEFER;
    666 		break;
    667 
    668 	case KAUTH_VNODE_WRITE_DATA:
    669 	  /* KAUTH_VNODE_ADD_FILE: */
    670 		result = KAUTH_RESULT_DEFER;
    671 		break;
    672 
    673 	case KAUTH_VNODE_EXECUTE:
    674 	  /* KAUTH_VNODE_SEARCH: */
    675 		result = KAUTH_RESULT_DEFER;
    676 		break;
    677 
    678 	case KAUTH_VNODE_APPEND_DATA:
    679 	  /* KAUTH_VNODE_ADD_SUBDIRECTORY: */
    680 		result = KAUTH_RESULT_DEFER;
    681 		break;
    682 
    683 	case KAUTH_VNODE_DELETE:
    684 	case KAUTH_VNODE_READ_TIMES:
    685 	case KAUTH_VNODE_WRITE_TIMES:
    686 	case KAUTH_VNODE_READ_FLAGS:
    687 	case KAUTH_VNODE_WRITE_FLAGS:
    688 	case KAUTH_VNODE_READ_SYSFLAGS:
    689 	case KAUTH_VNODE_WRITE_SYSFLAGS:
    690 	case KAUTH_VNODE_RENAME:
    691 	case KAUTH_VNODE_CHANGE_OWNERSHIP:
    692 	case KAUTH_VNODE_READ_SECURITY:
    693 	case KAUTH_VNODE_WRITE_SECURITY:
    694 	case KAUTH_VNODE_READ_ATTRIBUTES:
    695 	case KAUTH_VNODE_WRITE_ATTRIBUTES:
    696 	case KAUTH_VNODE_READ_EXTATTRIBUTES:
    697 	case KAUTH_VNODE_WRITE_EXTATTRIBUTES:
    698 	default:
    699 		result = KAUTH_RESULT_DEFER;
    700 		break;
    701 	}
    702 
    703 	return (result);
    704 }
    705