xref: /freebsd/sys/security/mac_bsdextended/mac_bsdextended.c (revision 87569f75a91f298c52a71823c04d41cf53c88889)
1 /*-
2  * Copyright (c) 2005 Tom Rhodes
3  * Copyright (c) 1999-2002 Robert N. M. Watson
4  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
5  * All rights reserved.
6  *
7  * This software was developed by Robert Watson for the TrustedBSD Project.
8  * It was later enhanced by Tom Rhodes for the TrustedBSD Project.
9  *
10  * This software was developed for the FreeBSD Project in part by Network
11  * Associates Laboratories, the Security Research Division of Network
12  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
13  * as part of the DARPA CHATS research program.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * $FreeBSD$
37  */
38 
39 /*
40  * Developed by the TrustedBSD Project.
41  * "BSD Extended" MAC policy, allowing the administrator to impose
42  * mandatory rules regarding users and some system objects.
43  */
44 
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/acl.h>
48 #include <sys/conf.h>
49 #include <sys/kernel.h>
50 #include <sys/lock.h>
51 #include <sys/mac.h>
52 #include <sys/malloc.h>
53 #include <sys/mount.h>
54 #include <sys/mutex.h>
55 #include <sys/proc.h>
56 #include <sys/systm.h>
57 #include <sys/sysproto.h>
58 #include <sys/sysent.h>
59 #include <sys/vnode.h>
60 #include <sys/file.h>
61 #include <sys/socket.h>
62 #include <sys/socketvar.h>
63 #include <sys/sysctl.h>
64 #include <sys/syslog.h>
65 
66 #include <net/bpfdesc.h>
67 #include <net/if.h>
68 #include <net/if_types.h>
69 #include <net/if_var.h>
70 
71 #include <vm/vm.h>
72 
73 #include <sys/mac_policy.h>
74 
75 #include <security/mac_bsdextended/mac_bsdextended.h>
76 
77 static struct mtx mac_bsdextended_mtx;
78 
79 SYSCTL_DECL(_security_mac);
80 
81 SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
82     "TrustedBSD extended BSD MAC policy controls");
83 
84 static int	mac_bsdextended_enabled = 1;
85 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
86     &mac_bsdextended_enabled, 0, "Enforce extended BSD policy");
87 TUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled);
88 
89 MALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
90 
91 #define	MAC_BSDEXTENDED_MAXRULES	250
92 static struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
93 static int rule_count = 0;
94 static int rule_slots = 0;
95 
96 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
97     &rule_count, 0, "Number of defined rules\n");
98 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
99     &rule_slots, 0, "Number of used rule slots\n");
100 
101 /*
102  * This is just used for logging purposes, eventually we would like
103  * to log much more then failed requests.
104  */
105 static int mac_bsdextended_logging;
106 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
107     &mac_bsdextended_logging, 0, "Log failed authorization requests");
108 
109 /*
110  * This tunable is here for compatibility.  It will allow the user
111  * to switch between the new mode (first rule matches) and the old
112  * functionality (all rules match).
113  */
114 static int
115 mac_bsdextended_firstmatch_enabled;
116 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
117 	CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
118 	"Disable/enable match first rule functionality");
119 
120 static int
121 mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
122 {
123 
124 	if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS)
125 		return (EINVAL);
126 
127 	if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS)
128 		return (EINVAL);
129 
130 	if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
131 		return (EINVAL);
132 
133 	return (0);
134 }
135 
136 static int
137 sysctl_rule(SYSCTL_HANDLER_ARGS)
138 {
139 	struct mac_bsdextended_rule temprule, *ruleptr;
140 	u_int namelen;
141 	int error, index, *name;
142 
143 	error = 0;
144 	name = (int *)arg1;
145 	namelen = arg2;
146 
147 	/* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
148 
149 	if (namelen != 1)
150 		return (EINVAL);
151 
152 	index = name[0];
153         if (index >= MAC_BSDEXTENDED_MAXRULES)
154 		return (ENOENT);
155 
156 	ruleptr = NULL;
157 	if (req->newptr && req->newlen != 0) {
158 		error = SYSCTL_IN(req, &temprule, sizeof(temprule));
159 		if (error)
160 			return (error);
161 		MALLOC(ruleptr, struct mac_bsdextended_rule *,
162 		    sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO);
163 	}
164 
165 	mtx_lock(&mac_bsdextended_mtx);
166 
167 	if (req->oldptr) {
168 		if (index < 0 || index > rule_slots + 1) {
169 			error = ENOENT;
170 			goto out;
171 		}
172 		if (rules[index] == NULL) {
173 			error = ENOENT;
174 			goto out;
175 		}
176 		temprule = *rules[index];
177 	}
178 
179 	if (req->newptr && req->newlen == 0) {
180 		/* printf("deletion\n"); */
181 		KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL"));
182 		ruleptr = rules[index];
183 		if (ruleptr == NULL) {
184 			error = ENOENT;
185 			goto out;
186 		}
187 		rule_count--;
188 		rules[index] = NULL;
189 	} else if (req->newptr) {
190 		error = mac_bsdextended_rule_valid(&temprule);
191 		if (error)
192 			goto out;
193 
194 		if (rules[index] == NULL) {
195 			/* printf("addition\n"); */
196 			*ruleptr = temprule;
197 			rules[index] = ruleptr;
198 			ruleptr = NULL;
199 			if (index + 1 > rule_slots)
200 				rule_slots = index + 1;
201 			rule_count++;
202 		} else {
203 			/* printf("replacement\n"); */
204 			*rules[index] = temprule;
205 		}
206 	}
207 
208 out:
209 	mtx_unlock(&mac_bsdextended_mtx);
210 	if (ruleptr != NULL)
211 		FREE(ruleptr, M_MACBSDEXTENDED);
212 	if (req->oldptr && error == 0)
213 		error = SYSCTL_OUT(req, &temprule, sizeof(temprule));
214 
215 	return (error);
216 }
217 
218 SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
219     CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
220 
221 static void
222 mac_bsdextended_init(struct mac_policy_conf *mpc)
223 {
224 
225 	/* Initialize ruleset lock. */
226 	mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
227 
228 	/* Register dynamic sysctl's for rules. */
229 }
230 
231 static void
232 mac_bsdextended_destroy(struct mac_policy_conf *mpc)
233 {
234 
235 	/* Destroy ruleset lock. */
236 	mtx_destroy(&mac_bsdextended_mtx);
237 
238 	/* Tear down sysctls. */
239 }
240 
241 static int
242 mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
243     struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode)
244 {
245 	int match;
246 
247 	/*
248 	 * Is there a subject match?
249 	 */
250 	mtx_assert(&mac_bsdextended_mtx, MA_OWNED);
251 	if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) {
252 		match =  (rule->mbr_subject.mbi_uid == cred->cr_uid ||
253 		    rule->mbr_subject.mbi_uid == cred->cr_ruid ||
254 		    rule->mbr_subject.mbi_uid == cred->cr_svuid);
255 
256 		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
257 			match = !match;
258 
259 		if (!match)
260 			return (0);
261 	}
262 
263 	if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) {
264 		match = (groupmember(rule->mbr_subject.mbi_gid, cred) ||
265 		    rule->mbr_subject.mbi_gid == cred->cr_rgid ||
266 		    rule->mbr_subject.mbi_gid == cred->cr_svgid);
267 
268 		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
269 			match = !match;
270 
271 		if (!match)
272 			return (0);
273 	}
274 
275 	/*
276 	 * Is there an object match?
277 	 */
278 	if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) {
279 		match = (rule->mbr_object.mbi_uid == object_uid);
280 
281 		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
282 			match = !match;
283 
284 		if (!match)
285 			return (0);
286 	}
287 
288 	if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) {
289 		match = (rule->mbr_object.mbi_gid == object_gid);
290 
291 		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
292 			match = !match;
293 
294 		if (!match)
295 			return (0);
296 	}
297 
298 	/*
299 	 * Is the access permitted?
300 	 */
301 	if ((rule->mbr_mode & acc_mode) != acc_mode) {
302 		if (mac_bsdextended_logging)
303 			log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
304 			    " on %d:%d failed. \n", cred->cr_ruid,
305 			    cred->cr_rgid, acc_mode, object_uid, object_gid);
306 		return (EACCES); /* Matching rule denies access */
307 	}
308 
309 	/*
310 	 * If the rule matched, permits access, and first match is enabled,
311 	 * return success.
312 	 */
313 	if (mac_bsdextended_firstmatch_enabled)
314 		return (EJUSTRETURN);
315 	else
316 		return(0);
317 }
318 
319 static int
320 mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid,
321     int acc_mode)
322 {
323 	int error, i;
324 
325 	if (suser_cred(cred, 0) == 0)
326 		return (0);
327 
328 	mtx_lock(&mac_bsdextended_mtx);
329 	for (i = 0; i < rule_slots; i++) {
330 		if (rules[i] == NULL)
331 			continue;
332 
333 		/*
334 		 * Since we do not separately handle append, map append to
335 		 * write.
336 		 */
337 		if (acc_mode & MBI_APPEND) {
338 			acc_mode &= ~MBI_APPEND;
339 			acc_mode |= MBI_WRITE;
340 		}
341 
342 		error = mac_bsdextended_rulecheck(rules[i], cred, object_uid,
343 		    object_gid, acc_mode);
344 		if (error == EJUSTRETURN)
345 			break;
346 		if (error) {
347 			mtx_unlock(&mac_bsdextended_mtx);
348 			return (error);
349 		}
350 	}
351 	mtx_unlock(&mac_bsdextended_mtx);
352 	return (0);
353 }
354 
355 static int
356 mac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
357 {
358 	int error;
359 	struct vattr vap;
360 
361 	if (!mac_bsdextended_enabled)
362 		return (0);
363 
364 	error = VOP_GETATTR(vp, &vap, cred, curthread);
365 	if (error)
366 		return (error);
367 
368 	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
369 	    acc_mode));
370 }
371 
372 static int
373 mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp,
374     struct label *label)
375 {
376 
377 	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
378 }
379 
380 static int
381 mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
382     struct label *label, int acc_mode)
383 {
384 
385 	return (mac_bsdextended_check_vp(cred, vp, acc_mode));
386 }
387 
388 static int
389 mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
390     struct label *dlabel)
391 {
392 
393 	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
394 }
395 
396 static int
397 mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
398     struct label *dlabel)
399 {
400 
401 	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
402 }
403 
404 static int
405 mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
406     struct label *dlabel, struct componentname *cnp, struct vattr *vap)
407 {
408 
409 	return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE));
410 }
411 
412 static int
413 mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
414     struct label *dlabel, struct vnode *vp, struct label *label,
415     struct componentname *cnp)
416 {
417 	int error;
418 
419 	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
420 	if (error)
421 		return (error);
422 
423 	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
424 }
425 
426 static int
427 mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
428     struct label *label, acl_type_t type)
429 {
430 
431 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
432 }
433 
434 static int
435 mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
436     struct label *label, int attrnamespace, const char *name)
437 {
438 
439 	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
440 }
441 
442 static int
443 mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
444     struct label *label, struct image_params *imgp,
445     struct label *execlabel)
446 {
447 
448 	return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC));
449 }
450 
451 static int
452 mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
453     struct label *label, acl_type_t type)
454 {
455 
456 	return (mac_bsdextended_check_vp(cred, vp, MBI_STAT));
457 }
458 
459 static int
460 mac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
461     struct label *label, int attrnamespace, const char *name, struct uio *uio)
462 {
463 
464 	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
465 }
466 
467 static int
468 mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
469     struct label *dlabel, struct vnode *vp, struct label *label,
470     struct componentname *cnp)
471 {
472 	int error;
473 
474 	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
475 	if (error)
476 		return (error);
477 
478 	error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
479 	if (error)
480 		return (error);
481 	return (0);
482 }
483 
484 static int
485 mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
486     struct label *label, int attrnamespace)
487 {
488 
489 	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
490 }
491 
492 static int
493 mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
494     struct label *dlabel, struct componentname *cnp)
495 {
496 
497 	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
498 }
499 
500 static int
501 mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
502     struct label *filelabel, int acc_mode)
503 {
504 
505 	return (mac_bsdextended_check_vp(cred, vp, acc_mode));
506 }
507 
508 static int
509 mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
510     struct label *dlabel)
511 {
512 
513 	return (mac_bsdextended_check_vp(cred, dvp, MBI_READ));
514 }
515 
516 static int
517 mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
518     struct label *label)
519 {
520 
521 	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
522 }
523 
524 static int
525 mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
526     struct label *dlabel, struct vnode *vp, struct label *label,
527     struct componentname *cnp)
528 {
529 	int error;
530 
531 	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
532 	if (error)
533 		return (error);
534 	error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
535 
536 	return (error);
537 }
538 
539 static int
540 mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
541     struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
542     struct componentname *cnp)
543 {
544 	int error;
545 
546 	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
547 	if (error)
548 		return (error);
549 
550 	if (vp != NULL)
551 		error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
552 
553 	return (error);
554 }
555 
556 static int
557 mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
558     struct label *label)
559 {
560 
561 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
562 }
563 
564 static int
565 mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
566     struct label *label, acl_type_t type, struct acl *acl)
567 {
568 
569 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
570 }
571 
572 static int
573 mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
574     struct label *label, int attrnamespace, const char *name, struct uio *uio)
575 {
576 
577 	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
578 }
579 
580 static int
581 mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
582     struct label *label, u_long flags)
583 {
584 
585 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
586 }
587 
588 static int
589 mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
590     struct label *label, mode_t mode)
591 {
592 
593 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
594 }
595 
596 static int
597 mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
598     struct label *label, uid_t uid, gid_t gid)
599 {
600 
601 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
602 }
603 
604 static int
605 mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
606     struct label *label, struct timespec atime, struct timespec utime)
607 {
608 
609 	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
610 }
611 
612 static int
613 mac_bsdextended_check_vnode_stat(struct ucred *active_cred,
614     struct ucred *file_cred, struct vnode *vp, struct label *label)
615 {
616 
617 	return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT));
618 }
619 
620 static struct mac_policy_ops mac_bsdextended_ops =
621 {
622 	.mpo_destroy = mac_bsdextended_destroy,
623 	.mpo_init = mac_bsdextended_init,
624 	.mpo_check_system_swapon = mac_bsdextended_check_system_swapon,
625 	.mpo_check_vnode_access = mac_bsdextended_check_vnode_access,
626 	.mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir,
627 	.mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot,
628 	.mpo_check_vnode_create = mac_bsdextended_check_create_vnode,
629 	.mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete,
630 	.mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl,
631 	.mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr,
632 	.mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec,
633 	.mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl,
634 	.mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr,
635 	.mpo_check_vnode_link = mac_bsdextended_check_vnode_link,
636 	.mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr,
637 	.mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup,
638 	.mpo_check_vnode_open = mac_bsdextended_check_vnode_open,
639 	.mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir,
640 	.mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink,
641 	.mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from,
642 	.mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to,
643 	.mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke,
644 	.mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode,
645 	.mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr,
646 	.mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags,
647 	.mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode,
648 	.mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner,
649 	.mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes,
650 	.mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat,
651 };
652 
653 MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended,
654     "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
655