ugidfw_system.c revision 145412
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 145412 2005-04-22 18:49:30Z trhodes $
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
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;
95
96SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
97    &rule_count, 0, "Number of defined rules\n");
98SYSCTL_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 */
105static int mac_bsdextended_logging;
106SYSCTL_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 */
114static int
115mac_bsdextended_firstmatch_enabled;
116SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
117	CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
118	"Disable/enable match first rule functionality");
119
120static int
121mac_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
136static int
137sysctl_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
208out:
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		if (error)
215			return (error);
216	}
217
218	return (0);
219}
220
221SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
222    CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
223
224static void
225mac_bsdextended_init(struct mac_policy_conf *mpc)
226{
227
228	/* Initialize ruleset lock. */
229	mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF);
230
231	/* Register dynamic sysctl's for rules. */
232}
233
234static void
235mac_bsdextended_destroy(struct mac_policy_conf *mpc)
236{
237
238	/* Destroy ruleset lock. */
239	mtx_destroy(&mac_bsdextended_mtx);
240
241	/* Tear down sysctls. */
242}
243
244static int
245mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
246    struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode)
247{
248	int match;
249
250	/*
251	 * Is there a subject match?
252	 */
253	mtx_assert(&mac_bsdextended_mtx, MA_OWNED);
254	if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) {
255		match =  (rule->mbr_subject.mbi_uid == cred->cr_uid ||
256		    rule->mbr_subject.mbi_uid == cred->cr_ruid ||
257		    rule->mbr_subject.mbi_uid == cred->cr_svuid);
258
259		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
260			match = !match;
261
262		if (!match)
263			return (0);
264	}
265
266	if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) {
267		match = (groupmember(rule->mbr_subject.mbi_gid, cred) ||
268		    rule->mbr_subject.mbi_gid == cred->cr_rgid ||
269		    rule->mbr_subject.mbi_gid == cred->cr_svgid);
270
271		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
272			match = !match;
273
274		if (!match)
275			return (0);
276	}
277
278	/*
279	 * Is there an object match?
280	 */
281	if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) {
282		match = (rule->mbr_object.mbi_uid == object_uid);
283
284		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
285			match = !match;
286
287		if (!match)
288			return (0);
289	}
290
291	if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) {
292		match = (rule->mbr_object.mbi_gid == object_gid);
293
294		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
295			match = !match;
296
297		if (!match)
298			return (0);
299	}
300
301	/*
302	 * Is the access permitted?
303	 */
304	if ((rule->mbr_mode & acc_mode) != acc_mode) {
305		if (mac_bsdextended_logging)
306			log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
307			    " on %d:%d failed. \n", cred->cr_ruid,
308			    cred->cr_rgid, acc_mode, object_uid, object_gid);
309		return (EACCES); /* Matching rule denies access */
310	}
311
312	/*
313	 * If the rule matched, permits access, and first match is enabled,
314	 * return success.
315	 */
316	if (mac_bsdextended_firstmatch_enabled)
317		return (EJUSTRETURN);
318	else
319		return(0);
320}
321
322static int
323mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid,
324    int acc_mode)
325{
326	int error, i;
327
328	if (suser_cred(cred, 0) == 0)
329		return (0);
330
331	mtx_lock(&mac_bsdextended_mtx);
332	for (i = 0; i < rule_slots; i++) {
333		if (rules[i] == NULL)
334			continue;
335
336		/*
337		 * Since we do not separately handle append, map append to
338		 * write.
339		 */
340		if (acc_mode & MBI_APPEND) {
341			acc_mode &= ~MBI_APPEND;
342			acc_mode |= MBI_WRITE;
343		}
344
345		error = mac_bsdextended_rulecheck(rules[i], cred, object_uid,
346		    object_gid, acc_mode);
347		if (error == EJUSTRETURN)
348			break;
349		if (error) {
350			mtx_unlock(&mac_bsdextended_mtx);
351			return (error);
352		}
353	}
354	mtx_unlock(&mac_bsdextended_mtx);
355	return (0);
356}
357
358static int
359mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp,
360    struct label *label)
361{
362	struct vattr vap;
363	int error;
364
365	if (!mac_bsdextended_enabled)
366		return (0);
367
368	error = VOP_GETATTR(vp, &vap, cred, curthread);
369	if (error)
370		return (error);
371	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
372	    MBI_WRITE));
373}
374
375static int
376mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
377    struct label *label, int acc_mode)
378{
379	struct vattr vap;
380	int error;
381
382	if (!mac_bsdextended_enabled)
383		return (0);
384
385	error = VOP_GETATTR(vp, &vap, cred, curthread);
386	if (error)
387		return (error);
388	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
389}
390
391static int
392mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
393    struct label *dlabel)
394{
395	struct vattr vap;
396	int error;
397
398	if (!mac_bsdextended_enabled)
399		return (0);
400
401	error = VOP_GETATTR(dvp, &vap, cred, curthread);
402	if (error)
403		return (error);
404	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
405	    MBI_EXEC));
406}
407
408static int
409mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
410    struct label *dlabel)
411{
412	struct vattr vap;
413	int error;
414
415	if (!mac_bsdextended_enabled)
416		return (0);
417
418	error = VOP_GETATTR(dvp, &vap, cred, curthread);
419	if (error)
420		return (error);
421	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
422	    MBI_EXEC));
423}
424
425static int
426mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
427    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
428{
429	struct vattr dvap;
430	int error;
431
432	if (!mac_bsdextended_enabled)
433		return (0);
434
435	error = VOP_GETATTR(dvp, &dvap, cred, curthread);
436	if (error)
437		return (error);
438	return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid,
439	    MBI_WRITE));
440}
441
442static int
443mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
444    struct label *dlabel, struct vnode *vp, struct label *label,
445    struct componentname *cnp)
446{
447	struct vattr vap;
448	int error;
449
450	if (!mac_bsdextended_enabled)
451		return (0);
452
453	error = VOP_GETATTR(dvp, &vap, cred, curthread);
454	if (error)
455		return (error);
456	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
457	    MBI_WRITE);
458	if (error)
459		return (error);
460
461	error = VOP_GETATTR(vp, &vap, cred, curthread);
462	if (error)
463		return (error);
464	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
465	    MBI_WRITE));
466}
467
468static int
469mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
470    struct label *label, acl_type_t type)
471{
472	struct vattr vap;
473	int error;
474
475	if (!mac_bsdextended_enabled)
476		return (0);
477
478	error = VOP_GETATTR(vp, &vap, cred, curthread);
479	if (error)
480		return (error);
481	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
482	    MBI_ADMIN));
483}
484
485static int
486mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
487    struct label *label, int attrnamespace, const char *name)
488{
489	struct vattr vap;
490	int error;
491
492	if (!mac_bsdextended_enabled)
493		return (0);
494
495	error = VOP_GETATTR(vp, &vap, cred, curthread);
496	if (error)
497		return (error);
498	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
499	    MBI_WRITE));
500}
501
502static int
503mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
504    struct label *label, struct image_params *imgp,
505    struct label *execlabel)
506{
507	struct vattr vap;
508	int error;
509
510	if (!mac_bsdextended_enabled)
511		return (0);
512
513	error = VOP_GETATTR(vp, &vap, cred, curthread);
514	if (error)
515		return (error);
516	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
517	    MBI_READ|MBI_EXEC));
518}
519
520static int
521mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
522    struct label *label, acl_type_t type)
523{
524	struct vattr vap;
525	int error;
526
527	if (!mac_bsdextended_enabled)
528		return (0);
529
530	error = VOP_GETATTR(vp, &vap, cred, curthread);
531	if (error)
532		return (error);
533	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
534	    MBI_STAT));
535}
536
537static int
538mac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
539    struct label *label, int attrnamespace, const char *name, struct uio *uio)
540{
541	struct vattr vap;
542	int error;
543
544	if (!mac_bsdextended_enabled)
545		return (0);
546
547	error = VOP_GETATTR(vp, &vap, cred, curthread);
548	if (error)
549		return (error);
550	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
551	    MBI_READ));
552}
553
554static int
555mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
556    struct label *dlabel, struct vnode *vp, struct label *label,
557    struct componentname *cnp)
558{
559	struct vattr vap;
560	int error;
561
562	if (!mac_bsdextended_enabled)
563		return (0);
564
565	error = VOP_GETATTR(dvp, &vap, cred, curthread);
566	if (error)
567		return (error);
568	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
569	    MBI_WRITE);
570	if (error)
571		return (error);
572
573	error = VOP_GETATTR(vp, &vap, cred, curthread);
574	if (error)
575		return (error);
576	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
577	    MBI_WRITE);
578	if (error)
579		return (error);
580	return (0);
581}
582
583static int
584mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
585    struct label *label, int attrnamespace)
586{
587	struct vattr vap;
588	int error;
589
590	if (!mac_bsdextended_enabled)
591		return (0);
592
593	error = VOP_GETATTR(vp, &vap, cred, curthread);
594	if (error)
595		return (error);
596	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
597	    MBI_READ));
598}
599
600static int
601mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
602    struct label *dlabel, struct componentname *cnp)
603{
604	struct vattr vap;
605	int error;
606
607	if (!mac_bsdextended_enabled)
608		return (0);
609
610	error = VOP_GETATTR(dvp, &vap, cred, curthread);
611	if (error)
612		return (error);
613	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
614	    MBI_EXEC));
615}
616
617static int
618mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
619    struct label *filelabel, int acc_mode)
620{
621	struct vattr vap;
622	int error;
623
624	if (!mac_bsdextended_enabled)
625		return (0);
626
627	error = VOP_GETATTR(vp, &vap, cred, curthread);
628	if (error)
629		return (error);
630	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
631}
632
633static int
634mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
635    struct label *dlabel)
636{
637	struct vattr vap;
638	int error;
639
640	if (!mac_bsdextended_enabled)
641		return (0);
642
643	error = VOP_GETATTR(dvp, &vap, cred, curthread);
644	if (error)
645		return (error);
646	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
647	    MBI_READ));
648}
649
650static int
651mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
652    struct label *label)
653{
654	struct vattr vap;
655	int error;
656
657	if (!mac_bsdextended_enabled)
658		return (0);
659
660	error = VOP_GETATTR(vp, &vap, cred, curthread);
661	if (error)
662		return (error);
663	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
664	    MBI_READ));
665}
666
667static int
668mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
669    struct label *dlabel, struct vnode *vp, struct label *label,
670    struct componentname *cnp)
671{
672	struct vattr vap;
673	int error;
674
675	if (!mac_bsdextended_enabled)
676		return (0);
677
678	error = VOP_GETATTR(dvp, &vap, cred, curthread);
679	if (error)
680		return (error);
681	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
682	    MBI_WRITE);
683	if (error)
684		return (error);
685	error = VOP_GETATTR(vp, &vap, cred, curthread);
686	if (error)
687		return (error);
688	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
689	    MBI_WRITE);
690
691	return (error);
692}
693
694static int
695mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
696    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
697    struct componentname *cnp)
698{
699	struct vattr vap;
700	int error;
701
702	if (!mac_bsdextended_enabled)
703		return (0);
704
705	error = VOP_GETATTR(dvp, &vap, cred, curthread);
706	if (error)
707		return (error);
708	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
709	    MBI_WRITE);
710	if (error)
711		return (error);
712
713	if (vp != NULL) {
714		error = VOP_GETATTR(vp, &vap, cred, curthread);
715		if (error)
716			return (error);
717		error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
718		    MBI_WRITE);
719	}
720
721	return (error);
722}
723
724static int
725mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
726    struct label *label)
727{
728	struct vattr vap;
729	int error;
730
731	if (!mac_bsdextended_enabled)
732		return (0);
733
734	error = VOP_GETATTR(vp, &vap, cred, curthread);
735	if (error)
736		return (error);
737	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
738	    MBI_ADMIN));
739}
740
741static int
742mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
743    struct label *label, acl_type_t type, struct acl *acl)
744{
745	struct vattr vap;
746	int error;
747
748	if (!mac_bsdextended_enabled)
749		return (0);
750
751	error = VOP_GETATTR(vp, &vap, cred, curthread);
752	if (error)
753		return (error);
754	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
755	    MBI_ADMIN));
756}
757
758static int
759mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
760    struct label *label, int attrnamespace, const char *name, struct uio *uio)
761{
762	struct vattr vap;
763	int error;
764
765	if (!mac_bsdextended_enabled)
766		return (0);
767
768	error = VOP_GETATTR(vp, &vap, cred, curthread);
769	if (error)
770		return (error);
771	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
772	    MBI_WRITE));
773}
774
775static int
776mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
777    struct label *label, u_long flags)
778{
779	struct vattr vap;
780	int error;
781
782	if (!mac_bsdextended_enabled)
783		return (0);
784
785	error = VOP_GETATTR(vp, &vap, cred, curthread);
786	if (error)
787		return (error);
788	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
789	    MBI_ADMIN));
790}
791
792static int
793mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
794    struct label *label, mode_t mode)
795{
796	struct vattr vap;
797	int error;
798
799	if (!mac_bsdextended_enabled)
800		return (0);
801
802	error = VOP_GETATTR(vp, &vap, cred, curthread);
803	if (error)
804		return (error);
805	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
806	    MBI_ADMIN));
807}
808
809static int
810mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
811    struct label *label, uid_t uid, gid_t gid)
812{
813	struct vattr vap;
814	int error;
815
816	if (!mac_bsdextended_enabled)
817		return (0);
818
819	error = VOP_GETATTR(vp, &vap, cred, curthread);
820	if (error)
821		return (error);
822	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
823	   MBI_ADMIN));
824}
825
826static int
827mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
828    struct label *label, struct timespec atime, struct timespec utime)
829{
830	struct vattr vap;
831	int error;
832
833	if (!mac_bsdextended_enabled)
834		return (0);
835
836	error = VOP_GETATTR(vp, &vap, cred, curthread);
837	if (error)
838		return (error);
839	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
840	    MBI_ADMIN));
841}
842
843static int
844mac_bsdextended_check_vnode_stat(struct ucred *active_cred,
845    struct ucred *file_cred, struct vnode *vp, struct label *label)
846{
847	struct vattr vap;
848	int error;
849
850	if (!mac_bsdextended_enabled)
851		return (0);
852
853	error = VOP_GETATTR(vp, &vap, active_cred, curthread);
854	if (error)
855		return (error);
856	return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid,
857	    MBI_STAT));
858}
859
860static struct mac_policy_ops mac_bsdextended_ops =
861{
862	.mpo_destroy = mac_bsdextended_destroy,
863	.mpo_init = mac_bsdextended_init,
864	.mpo_check_system_swapon = mac_bsdextended_check_system_swapon,
865	.mpo_check_vnode_access = mac_bsdextended_check_vnode_access,
866	.mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir,
867	.mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot,
868	.mpo_check_vnode_create = mac_bsdextended_check_create_vnode,
869	.mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete,
870	.mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl,
871	.mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr,
872	.mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec,
873	.mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl,
874	.mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr,
875	.mpo_check_vnode_link = mac_bsdextended_check_vnode_link,
876	.mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr,
877	.mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup,
878	.mpo_check_vnode_open = mac_bsdextended_check_vnode_open,
879	.mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir,
880	.mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink,
881	.mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from,
882	.mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to,
883	.mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke,
884	.mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode,
885	.mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr,
886	.mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags,
887	.mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode,
888	.mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner,
889	.mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes,
890	.mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat,
891};
892
893MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended,
894    "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
895