xref: /netbsd-src/share/examples/secmodel/secmodel_example.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /* $NetBSD: secmodel_example.c,v 1.26 2011/12/04 23:55:36 jym 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.26 2011/12/04 23:55:36 jym 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 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
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 		switch (req) {
302 		case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
303 		default:
304 			result = KAUTH_RESULT_DEFER;
305 			break;
306 		}
307 		break;
308 
309 	case KAUTH_SYSTEM_PSET:
310 		switch (req) {
311 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
312 		case KAUTH_REQ_SYSTEM_PSET_BIND:
313 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
314 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
315 		default:
316 			result = KAUTH_RESULT_DEFER;
317 			break;
318 		}
319 		break;
320 
321 	case KAUTH_SYSTEM_FS_QUOTA:
322 		switch (req) {
323 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
324 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
325 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
326 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
327 		default:
328 			result = KAUTH_RESULT_DEFER;
329 			break;
330 		}
331 		break;
332 
333 	case KAUTH_SYSTEM_FILEHANDLE:
334 	case KAUTH_SYSTEM_MKNOD:
335 	case KAUTH_SYSTEM_MODULE:
336 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
337 	case KAUTH_SYSTEM_SETIDCORE:
338 	case KAUTH_SYSTEM_SWAPCTL:
339 	case KAUTH_SYSTEM_ACCOUNTING:
340 	case KAUTH_SYSTEM_REBOOT:
341 	default:
342 		result = KAUTH_RESULT_DEFER;
343 		break;
344 	}
345 
346 	return (result);
347 }
348 
349 /*
350  * kauth(9) listener
351  *
352  * Security model: example
353  * Scope: Process
354  */
355 static int
356 secmodel_example_process_cb(kauth_cred_t cred, kauth_action_t action,
357     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
358 {
359 	int result;
360 
361 	result = KAUTH_RESULT_DENY;
362 
363 	switch (action) {
364 	case KAUTH_PROCESS_KTRACE:
365 		switch ((u_long)arg1) {
366 		case KAUTH_REQ_PROCESS_KTRACE_PERSISTENT:
367 		default:
368 			result = KAUTH_RESULT_DEFER;
369 			break;
370 		}
371 		break;
372 
373 	case KAUTH_PROCESS_CANSEE:
374 		switch ((u_long)arg1) {
375 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
376 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
377 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
378 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
379 		default:
380 			result = KAUTH_RESULT_DEFER;
381 			break;
382 		}
383 		break;
384 
385 	case KAUTH_PROCESS_CORENAME:
386 		switch ((u_long)arg1) {
387 		case KAUTH_REQ_PROCESS_CORENAME_GET:
388 		case KAUTH_REQ_PROCESS_CORENAME_SET:
389 		default:
390 			result = KAUTH_RESULT_DEFER;
391 			break;
392 		}
393 		break;
394 
395 	case KAUTH_PROCESS_RLIMIT:
396 		switch ((u_long)arg1) {
397 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
398 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
399 		default:
400 			result = KAUTH_RESULT_DEFER;
401 			break;
402 		}
403 		break;
404 
405 	case KAUTH_PROCESS_STOPFLAG:
406 	case KAUTH_PROCESS_PTRACE:
407 	case KAUTH_PROCESS_SIGNAL:
408 	case KAUTH_PROCESS_PROCFS:
409 	case KAUTH_PROCESS_FORK:
410 	case KAUTH_PROCESS_KEVENT_FILTER:
411 	case KAUTH_PROCESS_NICE:
412 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
413 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
414 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
415 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
416 	case KAUTH_PROCESS_SETID:
417 	default:
418 		result = KAUTH_RESULT_DEFER;
419 		break;
420 	}
421 
422 	return (result);
423 }
424 
425 /*
426  * kauth(9) listener
427  *
428  * Security model: example
429  * Scope: Network
430  */
431 static int
432 secmodel_example_network_cb(kauth_cred_t cred, kauth_action_t action,
433     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
434 {
435 	int result;
436 
437 	result = KAUTH_RESULT_DENY;
438 
439 	switch (action) {
440 	case KAUTH_NETWORK_ALTQ:
441 		switch((u_long)arg0) {
442 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
443 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
444 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
445 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
446 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
447 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
448 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
449 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
450 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
451 		case KAUTH_REQ_NETWORK_ALTQ_RED:
452 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
453 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
454 		default:
455 			result = KAUTH_RESULT_DEFER;
456 			break;
457 		}
458 		break;
459 
460 	case KAUTH_NETWORK_BIND:
461 		switch((u_long)arg0) {
462 		case KAUTH_REQ_NETWORK_BIND_PORT:
463 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
464 		default:
465 			result = KAUTH_RESULT_DEFER;
466 			break;
467 		}
468 		break;
469 
470 	case KAUTH_NETWORK_FIREWALL:
471 		switch ((u_long)arg0) {
472 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
473 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
474 		default:
475 			result = KAUTH_RESULT_DEFER;
476 			break;
477 		}
478 		break;
479 
480 	case KAUTH_NETWORK_FORWSRCRT:
481 		break;
482 
483 	case KAUTH_NETWORK_INTERFACE:
484 		switch ((u_long)arg0) {
485 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
486 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
487 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
488 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
489 		default:
490 			result = KAUTH_RESULT_DEFER;
491 			break;
492 		}
493 		break;
494 
495 	case KAUTH_NETWORK_NFS:
496 		switch ((u_long)arg0) {
497 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
498 		case KAUTH_REQ_NETWORK_NFS_SVC:
499 		default:
500 			result = KAUTH_RESULT_DEFER;
501 			break;
502 		}
503 		break;
504 
505 	case KAUTH_NETWORK_INTERFACE_PPP:
506 		switch ((u_long)arg0) {
507 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
508 		default:
509 			result = KAUTH_RESULT_DEFER;
510 			break;
511 		}
512 		break;
513 
514 	case KAUTH_NETWORK_INTERFACE_SLIP:
515 		switch ((u_long)arg0) {
516 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
517 		default:
518 			result = KAUTH_RESULT_DEFER;
519 			break;
520 		}
521 		break;
522 
523 	case KAUTH_NETWORK_INTERFACE_STRIP:
524 		switch ((u_long)arg0) {
525 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
526 		default:
527 			result = KAUTH_RESULT_DEFER;
528 			break;
529 		}
530 		break;
531 
532 	case KAUTH_NETWORK_ROUTE:
533 		break;
534 
535 	case KAUTH_NETWORK_SOCKET:
536 		switch((u_long)arg0) {
537 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
538 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
539 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
540 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
541 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
542 		default:
543 			result = KAUTH_RESULT_DEFER;
544 			break;
545 		}
546 		break;
547 
548 		break;
549 	case KAUTH_NETWORK_INTERFACE_TUN:
550 		switch ((u_long)arg0) {
551 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
552 		default:
553 			result = KAUTH_RESULT_DEFER;
554 			break;
555 		}
556 		break;
557 
558 	default:
559 		result = KAUTH_RESULT_DEFER;
560 		break;
561 	}
562 
563 	return (result);
564 }
565 
566 /*
567  * kauth(9) listener
568  *
569  * Security model: example
570  * Scope: Machdep
571  */
572 static int
573 secmodel_example_machdep_cb(kauth_cred_t cred, kauth_action_t action,
574     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
575 {
576 	int result;
577 
578 	result = KAUTH_RESULT_DENY;
579 
580 	switch (action) {
581 	case KAUTH_MACHDEP_CACHEFLUSH:
582 	case KAUTH_MACHDEP_IOPERM_GET:
583 	case KAUTH_MACHDEP_IOPERM_SET:
584 	case KAUTH_MACHDEP_IOPL:
585 	case KAUTH_MACHDEP_LDT_GET:
586 	case KAUTH_MACHDEP_LDT_SET:
587 	case KAUTH_MACHDEP_MTRR_GET:
588 	case KAUTH_MACHDEP_MTRR_SET:
589 	case KAUTH_MACHDEP_NVRAM:
590 	case KAUTH_MACHDEP_UNMANAGEDMEM:
591 	default:
592 		result = KAUTH_RESULT_DEFER;
593 		break;
594 	}
595 
596 	return (result);
597 }
598 
599 /*
600  * kauth(9) listener
601  *
602  * Security model: example
603  * Scope: Device
604  */
605 static int
606 secmodel_example_device_cb(kauth_cred_t cred, kauth_action_t action,
607     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
608 {
609 	int result;
610 
611 	result = KAUTH_RESULT_DENY;
612 
613 	switch (action) {
614 	case KAUTH_DEVICE_TTY_OPEN:
615 	case KAUTH_DEVICE_TTY_PRIVSET:
616 	case KAUTH_DEVICE_TTY_STI:
617 		break;
618 
619 	case KAUTH_DEVICE_RAWIO_SPEC:
620 		switch ((u_long)arg0) {
621 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_READ:
622 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_WRITE:
623 		case KAUTH_REQ_DEVICE_RAWIO_SPEC_RW:
624 			break;
625 
626 		default:
627 			result = KAUTH_RESULT_DEFER;
628 			break;
629 		}
630 		break;
631 
632 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
633 		switch ((u_long)arg0) {
634 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
635 		default:
636 			result = KAUTH_RESULT_DEFER;
637 			break;
638 		}
639 		break;
640 
641 	case KAUTH_DEVICE_BLUETOOTH_BTUART:
642 		switch ((u_long)arg0) {
643 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
644 		default:
645 			result = KAUTH_RESULT_DEFER;
646 			break;
647 		}
648 		break;
649 
650 	case KAUTH_DEVICE_RAWIO_PASSTHRU:
651 	case KAUTH_DEVICE_BLUETOOTH_RECV:
652 	case KAUTH_DEVICE_BLUETOOTH_SEND:
653 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
654 	default:
655 		result = KAUTH_RESULT_DEFER;
656 		break;
657 	}
658 
659 	return (result);
660 }
661 
662 /*
663  * kauth(9) listener
664  *
665  * Security model: example
666  * Scope: Vnode
667  */
668 static int
669 secmodel_example_vnode_cb(kauth_cred_t cred, kauth_action_t action,
670     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
671 {
672 	int result;
673 
674 	result = KAUTH_RESULT_DENY;
675 
676 	switch (action) {
677 	case KAUTH_VNODE_READ_DATA:
678 	  /* KAUTH_VNODE_LIST_DIRECTORY: */
679 		result = KAUTH_RESULT_DEFER;
680 		break;
681 
682 	case KAUTH_VNODE_WRITE_DATA:
683 	  /* KAUTH_VNODE_ADD_FILE: */
684 		result = KAUTH_RESULT_DEFER;
685 		break;
686 
687 	case KAUTH_VNODE_EXECUTE:
688 	  /* KAUTH_VNODE_SEARCH: */
689 		result = KAUTH_RESULT_DEFER;
690 		break;
691 
692 	case KAUTH_VNODE_APPEND_DATA:
693 	  /* KAUTH_VNODE_ADD_SUBDIRECTORY: */
694 		result = KAUTH_RESULT_DEFER;
695 		break;
696 
697 	case KAUTH_VNODE_DELETE:
698 	case KAUTH_VNODE_READ_TIMES:
699 	case KAUTH_VNODE_WRITE_TIMES:
700 	case KAUTH_VNODE_READ_FLAGS:
701 	case KAUTH_VNODE_WRITE_FLAGS:
702 	case KAUTH_VNODE_READ_SYSFLAGS:
703 	case KAUTH_VNODE_WRITE_SYSFLAGS:
704 	case KAUTH_VNODE_RENAME:
705 	case KAUTH_VNODE_CHANGE_OWNERSHIP:
706 	case KAUTH_VNODE_READ_SECURITY:
707 	case KAUTH_VNODE_WRITE_SECURITY:
708 	case KAUTH_VNODE_READ_ATTRIBUTES:
709 	case KAUTH_VNODE_WRITE_ATTRIBUTES:
710 	case KAUTH_VNODE_READ_EXTATTRIBUTES:
711 	case KAUTH_VNODE_WRITE_EXTATTRIBUTES:
712 	default:
713 		result = KAUTH_RESULT_DEFER;
714 		break;
715 	}
716 
717 	return (result);
718 }
719