mac_bsdextended.c revision 166843
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: head/sys/security/mac_bsdextended/mac_bsdextended.c 166843 2007-02-20 10:21:27Z rwatson $
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/jail.h>
51#include <sys/lock.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#include <sys/ucred.h>
66
67#include <net/bpfdesc.h>
68#include <net/if.h>
69#include <net/if_types.h>
70#include <net/if_var.h>
71
72#include <vm/vm.h>
73
74#include <security/mac/mac_policy.h>
75#include <security/mac_bsdextended/mac_bsdextended.h>
76
77static struct mtx mac_bsdextended_mtx;
78
79SYSCTL_DECL(_security_mac);
80
81SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
82    "TrustedBSD extended BSD MAC policy controls");
83
84static int	mac_bsdextended_enabled = 1;
85SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
86    &mac_bsdextended_enabled, 0, "Enforce extended BSD policy");
87TUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled);
88
89MALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
90
91#define	MAC_BSDEXTENDED_MAXRULES	250
92static struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
93static int rule_count = 0;
94static int rule_slots = 0;
95static int rule_version = MB_VERSION;
96
97SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
98    &rule_count, 0, "Number of defined rules\n");
99SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
100    &rule_slots, 0, "Number of used rule slots\n");
101SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_version, CTLFLAG_RD,
102    &rule_version, 0, "Version number for API\n");
103
104/*
105 * This is just used for logging purposes, eventually we would like
106 * to log much more then failed requests.
107 */
108static int mac_bsdextended_logging;
109SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
110    &mac_bsdextended_logging, 0, "Log failed authorization requests");
111
112/*
113 * This tunable is here for compatibility.  It will allow the user
114 * to switch between the new mode (first rule matches) and the old
115 * functionality (all rules match).
116 */
117static int
118mac_bsdextended_firstmatch_enabled;
119SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
120	CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
121	"Disable/enable match first rule functionality");
122
123static int
124mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
125{
126
127	if ((rule->mbr_subject.mbs_flags | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
128		return (EINVAL);
129
130	if ((rule->mbr_subject.mbs_neg | MBS_ALL_FLAGS) != MBS_ALL_FLAGS)
131		return (EINVAL);
132
133	if ((rule->mbr_object.mbo_flags | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
134		return (EINVAL);
135
136	if ((rule->mbr_object.mbo_neg | MBO_ALL_FLAGS) != MBO_ALL_FLAGS)
137		return (EINVAL);
138
139	if ((rule->mbr_object.mbo_neg | MBO_TYPE_DEFINED) &&
140	    (rule->mbr_object.mbo_type | MBO_ALL_TYPE) != MBO_ALL_TYPE)
141		return (EINVAL);
142
143	if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
144		return (EINVAL);
145
146	return (0);
147}
148
149static int
150sysctl_rule(SYSCTL_HANDLER_ARGS)
151{
152	struct mac_bsdextended_rule temprule, *ruleptr;
153	u_int namelen;
154	int error, index, *name;
155
156	error = 0;
157	name = (int *)arg1;
158	namelen = arg2;
159
160	/* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
161
162	if (namelen != 1)
163		return (EINVAL);
164
165	index = name[0];
166        if (index >= MAC_BSDEXTENDED_MAXRULES)
167		return (ENOENT);
168
169	ruleptr = NULL;
170	if (req->newptr && req->newlen != 0) {
171		error = SYSCTL_IN(req, &temprule, sizeof(temprule));
172		if (error)
173			return (error);
174		MALLOC(ruleptr, struct mac_bsdextended_rule *,
175		    sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO);
176	}
177
178	mtx_lock(&mac_bsdextended_mtx);
179
180	if (req->oldptr) {
181		if (index < 0 || index > rule_slots + 1) {
182			error = ENOENT;
183			goto out;
184		}
185		if (rules[index] == NULL) {
186			error = ENOENT;
187			goto out;
188		}
189		temprule = *rules[index];
190	}
191
192	if (req->newptr && req->newlen == 0) {
193		/* printf("deletion\n"); */
194		KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL"));
195		ruleptr = rules[index];
196		if (ruleptr == NULL) {
197			error = ENOENT;
198			goto out;
199		}
200		rule_count--;
201		rules[index] = NULL;
202	} else if (req->newptr) {
203		error = mac_bsdextended_rule_valid(&temprule);
204		if (error)
205			goto out;
206
207		if (rules[index] == NULL) {
208			/* printf("addition\n"); */
209			*ruleptr = temprule;
210			rules[index] = ruleptr;
211			ruleptr = NULL;
212			if (index + 1 > rule_slots)
213				rule_slots = index + 1;
214			rule_count++;
215		} else {
216			/* printf("replacement\n"); */
217			*rules[index] = temprule;
218		}
219	}
220
221out:
222	mtx_unlock(&mac_bsdextended_mtx);
223	if (ruleptr != NULL)
224		FREE(ruleptr, M_MACBSDEXTENDED);
225	if (req->oldptr && error == 0)
226		error = SYSCTL_OUT(req, &temprule, sizeof(temprule));
227
228	return (error);
229}
230
231SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
232    CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
233
234static void
235mac_bsdextended_init(struct mac_policy_conf *mpc)
236{
237
238	/* Initialize ruleset lock. */
239	mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
240
241	/* Register dynamic sysctl's for rules. */
242}
243
244static void
245mac_bsdextended_destroy(struct mac_policy_conf *mpc)
246{
247
248	/* Destroy ruleset lock. */
249	mtx_destroy(&mac_bsdextended_mtx);
250
251	/* Tear down sysctls. */
252}
253
254static int
255mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
256    struct ucred *cred, struct vnode *vp, struct vattr *vap, int acc_mode)
257{
258	int match;
259	int i;
260
261	/*
262	 * Is there a subject match?
263	 */
264	mtx_assert(&mac_bsdextended_mtx, MA_OWNED);
265	if (rule->mbr_subject.mbs_flags & MBS_UID_DEFINED) {
266		match =  ((cred->cr_uid <= rule->mbr_subject.mbs_uid_max &&
267		    cred->cr_uid >= rule->mbr_subject.mbs_uid_min) ||
268		    (cred->cr_ruid <= rule->mbr_subject.mbs_uid_max &&
269		    cred->cr_ruid >= rule->mbr_subject.mbs_uid_min) ||
270		    (cred->cr_svuid <= rule->mbr_subject.mbs_uid_max &&
271		    cred->cr_svuid >= rule->mbr_subject.mbs_uid_min));
272
273		if (rule->mbr_subject.mbs_neg & MBS_UID_DEFINED)
274			match = !match;
275
276		if (!match)
277			return (0);
278	}
279
280	if (rule->mbr_subject.mbs_flags & MBS_GID_DEFINED) {
281		match = ((cred->cr_rgid <= rule->mbr_subject.mbs_gid_max &&
282		    cred->cr_rgid >= rule->mbr_subject.mbs_gid_min) ||
283		    (cred->cr_svgid <= rule->mbr_subject.mbs_gid_max &&
284		    cred->cr_svgid >= rule->mbr_subject.mbs_gid_min));
285
286		if (!match) {
287			for (i = 0; i < cred->cr_ngroups; i++)
288				if (cred->cr_groups[i]
289				    <= rule->mbr_subject.mbs_gid_max &&
290				    cred->cr_groups[i]
291				    >= rule->mbr_subject.mbs_gid_min) {
292					match = 1;
293					break;
294				}
295		}
296
297		if (rule->mbr_subject.mbs_neg & MBS_GID_DEFINED)
298			match = !match;
299
300		if (!match)
301			return (0);
302	}
303
304	if (rule->mbr_subject.mbs_flags & MBS_PRISON_DEFINED) {
305		match = (cred->cr_prison != NULL &&
306		    cred->cr_prison->pr_id == rule->mbr_subject.mbs_prison);
307
308		if (rule->mbr_subject.mbs_neg & MBS_PRISON_DEFINED)
309			match = !match;
310
311		if (!match)
312			return (0);
313	}
314
315	/*
316	 * Is there an object match?
317	 */
318	if (rule->mbr_object.mbo_flags & MBO_UID_DEFINED) {
319		match = (vap->va_uid <= rule->mbr_object.mbo_uid_max &&
320		    vap->va_uid >= rule->mbr_object.mbo_uid_min);
321
322		if (rule->mbr_object.mbo_neg & MBO_UID_DEFINED)
323			match = !match;
324
325		if (!match)
326			return (0);
327	}
328
329	if (rule->mbr_object.mbo_flags & MBO_GID_DEFINED) {
330		match = (vap->va_gid <= rule->mbr_object.mbo_gid_max &&
331		    vap->va_gid >= rule->mbr_object.mbo_gid_min);
332
333		if (rule->mbr_object.mbo_neg & MBO_GID_DEFINED)
334			match = !match;
335
336		if (!match)
337			return (0);
338	}
339
340	if (rule->mbr_object.mbo_flags & MBO_FSID_DEFINED) {
341		match = (bcmp(&(vp->v_mount->mnt_stat.f_fsid),
342		    &(rule->mbr_object.mbo_fsid),
343		    sizeof(rule->mbr_object.mbo_fsid)) == 0);
344
345		if (rule->mbr_object.mbo_neg & MBO_FSID_DEFINED)
346			match = !match;
347
348		if (!match)
349			return 0;
350	}
351
352	if (rule->mbr_object.mbo_flags & MBO_SUID) {
353		match = (vap->va_mode & VSUID);
354
355		if (rule->mbr_object.mbo_neg & MBO_SUID)
356			match = !match;
357
358		if (!match)
359			return 0;
360	}
361
362	if (rule->mbr_object.mbo_flags & MBO_SGID) {
363		match = (vap->va_mode & VSGID);
364
365		if (rule->mbr_object.mbo_neg & MBO_SGID)
366			match = !match;
367
368		if (!match)
369			return 0;
370	}
371
372	if (rule->mbr_object.mbo_flags & MBO_UID_SUBJECT) {
373		match = (vap->va_uid == cred->cr_uid ||
374		    vap->va_uid == cred->cr_ruid ||
375		    vap->va_uid == cred->cr_svuid);
376
377		if (rule->mbr_object.mbo_neg & MBO_UID_SUBJECT)
378			match = !match;
379
380		if (!match)
381			return 0;
382	}
383
384	if (rule->mbr_object.mbo_flags & MBO_GID_SUBJECT) {
385		match = (groupmember(vap->va_gid, cred) ||
386		    vap->va_gid == cred->cr_rgid ||
387		    vap->va_gid == cred->cr_svgid);
388
389		if (rule->mbr_object.mbo_neg & MBO_GID_SUBJECT)
390			match = !match;
391
392		if (!match)
393			return 0;
394	}
395
396	if (rule->mbr_object.mbo_flags & MBO_TYPE_DEFINED) {
397		switch (vap->va_type) {
398		case VREG:
399			match = (rule->mbr_object.mbo_type & MBO_TYPE_REG);
400			break;
401		case VDIR:
402			match = (rule->mbr_object.mbo_type & MBO_TYPE_DIR);
403			break;
404		case VBLK:
405			match = (rule->mbr_object.mbo_type & MBO_TYPE_BLK);
406			break;
407		case VCHR:
408			match = (rule->mbr_object.mbo_type & MBO_TYPE_CHR);
409			break;
410		case VLNK:
411			match = (rule->mbr_object.mbo_type & MBO_TYPE_LNK);
412			break;
413		case VSOCK:
414			match = (rule->mbr_object.mbo_type & MBO_TYPE_SOCK);
415			break;
416		case VFIFO:
417			match = (rule->mbr_object.mbo_type & MBO_TYPE_FIFO);
418			break;
419		default:
420			match = 0;
421		}
422
423		if (rule->mbr_object.mbo_neg & MBO_TYPE_DEFINED)
424			match = !match;
425
426		if (!match)
427			return 0;
428	}
429
430	/*
431	 * Is the access permitted?
432	 */
433	if ((rule->mbr_mode & acc_mode) != acc_mode) {
434		if (mac_bsdextended_logging)
435			log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
436			    " on %d:%d failed. \n", cred->cr_ruid,
437			    cred->cr_rgid, acc_mode, vap->va_uid, vap->va_gid);
438		return (EACCES); /* Matching rule denies access */
439	}
440
441	/*
442	 * If the rule matched, permits access, and first match is enabled,
443	 * return success.
444	 */
445	if (mac_bsdextended_firstmatch_enabled)
446		return (EJUSTRETURN);
447	else
448		return(0);
449}
450
451static int
452mac_bsdextended_check(struct ucred *cred, struct vnode *vp, struct vattr *vap,
453    int acc_mode)
454{
455	int error, i;
456
457	/*
458	 * XXXRW: More specific privilege selection needed?
459	 */
460	if (suser_cred(cred, 0) == 0)
461		return (0);
462
463	/*
464	 * Since we do not separately handle append, map append to write.
465	 */
466	if (acc_mode & MBI_APPEND) {
467		acc_mode &= ~MBI_APPEND;
468		acc_mode |= MBI_WRITE;
469	}
470
471	mtx_lock(&mac_bsdextended_mtx);
472	for (i = 0; i < rule_slots; i++) {
473		if (rules[i] == NULL)
474			continue;
475
476		error = mac_bsdextended_rulecheck(rules[i], cred,
477		    vp, vap, acc_mode);
478		if (error == EJUSTRETURN)
479			break;
480		if (error) {
481			mtx_unlock(&mac_bsdextended_mtx);
482			return (error);
483		}
484	}
485	mtx_unlock(&mac_bsdextended_mtx);
486	return (0);
487}
488
489static int
490mac_bsdextended_check_vp(struct ucred *cred, struct vnode *vp, int acc_mode)
491{
492	int error;
493	struct vattr vap;
494
495	if (!mac_bsdextended_enabled)
496		return (0);
497
498	error = VOP_GETATTR(vp, &vap, cred, curthread);
499	if (error)
500		return (error);
501
502	return (mac_bsdextended_check(cred, vp, &vap, acc_mode));
503}
504
505static int
506mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp,
507    struct label *label)
508{
509
510	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
511}
512
513static int
514mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
515    struct label *label, int acc_mode)
516{
517
518	return (mac_bsdextended_check_vp(cred, vp, acc_mode));
519}
520
521static int
522mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
523    struct label *dlabel)
524{
525
526	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
527}
528
529static int
530mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
531    struct label *dlabel)
532{
533
534	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
535}
536
537static int
538mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
539    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
540{
541
542	return (mac_bsdextended_check_vp(cred, dvp, MBI_WRITE));
543}
544
545static int
546mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
547    struct label *dlabel, struct vnode *vp, struct label *label,
548    struct componentname *cnp)
549{
550	int error;
551
552	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
553	if (error)
554		return (error);
555
556	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
557}
558
559static int
560mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
561    struct label *label, acl_type_t type)
562{
563
564	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
565}
566
567static int
568mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
569    struct label *label, int attrnamespace, const char *name)
570{
571
572	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
573}
574
575static int
576mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
577    struct label *label, struct image_params *imgp,
578    struct label *execlabel)
579{
580
581	return (mac_bsdextended_check_vp(cred, vp, MBI_READ|MBI_EXEC));
582}
583
584static int
585mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
586    struct label *label, acl_type_t type)
587{
588
589	return (mac_bsdextended_check_vp(cred, vp, MBI_STAT));
590}
591
592static int
593mac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
594    struct label *label, int attrnamespace, const char *name, struct uio *uio)
595{
596
597	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
598}
599
600static int
601mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
602    struct label *dlabel, struct vnode *vp, struct label *label,
603    struct componentname *cnp)
604{
605	int error;
606
607	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
608	if (error)
609		return (error);
610
611	error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
612	if (error)
613		return (error);
614	return (0);
615}
616
617static int
618mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
619    struct label *label, int attrnamespace)
620{
621
622	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
623}
624
625static int
626mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
627    struct label *dlabel, struct componentname *cnp)
628{
629
630	return (mac_bsdextended_check_vp(cred, dvp, MBI_EXEC));
631}
632
633static int
634mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
635    struct label *filelabel, int acc_mode)
636{
637
638	return (mac_bsdextended_check_vp(cred, vp, acc_mode));
639}
640
641static int
642mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
643    struct label *dlabel)
644{
645
646	return (mac_bsdextended_check_vp(cred, dvp, MBI_READ));
647}
648
649static int
650mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
651    struct label *label)
652{
653
654	return (mac_bsdextended_check_vp(cred, vp, MBI_READ));
655}
656
657static int
658mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
659    struct label *dlabel, struct vnode *vp, struct label *label,
660    struct componentname *cnp)
661{
662	int error;
663
664	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
665	if (error)
666		return (error);
667	error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
668
669	return (error);
670}
671
672static int
673mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
674    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
675    struct componentname *cnp)
676{
677	int error;
678
679	error = mac_bsdextended_check_vp(cred, dvp, MBI_WRITE);
680	if (error)
681		return (error);
682
683	if (vp != NULL)
684		error = mac_bsdextended_check_vp(cred, vp, MBI_WRITE);
685
686	return (error);
687}
688
689static int
690mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
691    struct label *label)
692{
693
694	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
695}
696
697static int
698mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
699    struct label *label, acl_type_t type, struct acl *acl)
700{
701
702	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
703}
704
705static int
706mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
707    struct label *label, int attrnamespace, const char *name, struct uio *uio)
708{
709
710	return (mac_bsdextended_check_vp(cred, vp, MBI_WRITE));
711}
712
713static int
714mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
715    struct label *label, u_long flags)
716{
717
718	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
719}
720
721static int
722mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
723    struct label *label, mode_t mode)
724{
725
726	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
727}
728
729static int
730mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
731    struct label *label, uid_t uid, gid_t gid)
732{
733
734	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
735}
736
737static int
738mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
739    struct label *label, struct timespec atime, struct timespec utime)
740{
741
742	return (mac_bsdextended_check_vp(cred, vp, MBI_ADMIN));
743}
744
745static int
746mac_bsdextended_check_vnode_stat(struct ucred *active_cred,
747    struct ucred *file_cred, struct vnode *vp, struct label *label)
748{
749
750	return (mac_bsdextended_check_vp(active_cred, vp, MBI_STAT));
751}
752
753static struct mac_policy_ops mac_bsdextended_ops =
754{
755	.mpo_destroy = mac_bsdextended_destroy,
756	.mpo_init = mac_bsdextended_init,
757	.mpo_check_system_swapon = mac_bsdextended_check_system_swapon,
758	.mpo_check_vnode_access = mac_bsdextended_check_vnode_access,
759	.mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir,
760	.mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot,
761	.mpo_check_vnode_create = mac_bsdextended_check_create_vnode,
762	.mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete,
763	.mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl,
764	.mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr,
765	.mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec,
766	.mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl,
767	.mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr,
768	.mpo_check_vnode_link = mac_bsdextended_check_vnode_link,
769	.mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr,
770	.mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup,
771	.mpo_check_vnode_open = mac_bsdextended_check_vnode_open,
772	.mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir,
773	.mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink,
774	.mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from,
775	.mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to,
776	.mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke,
777	.mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode,
778	.mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr,
779	.mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags,
780	.mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode,
781	.mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner,
782	.mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes,
783	.mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat,
784};
785
786MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended,
787    "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
788