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