1 /* $NetBSD: secmodel_example.c,v 1.29 2023/01/05 17:36:53 jakllsch 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.29 2023/01/05 17:36:53 jakllsch 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
sysctl_security_example_setup(struct sysctllog ** clog)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
secmodel_example_init(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
secmodel_example_start(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
secmodel_example_stop(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
secmodel_example_eval(const char * what,void * arg,void * ret)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 attachement/detachement 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
secmodel_example_modcmd(modcmd_t cmd,void * arg)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
secmodel_example_generic_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_system_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_process_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_network_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_machdep_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_device_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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
secmodel_example_vnode_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)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