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
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 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
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