ugidfw_system.c revision 134131
1101099Srwatson/*-
2126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson
3126097Srwatson * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8106393Srwatson * This software was developed for the FreeBSD Project in part by Network
9106393Srwatson * Associates Laboratories, the Security Research Division of Network
10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11106393Srwatson * as part of the DARPA CHATS research program.
12101099Srwatson *
13101099Srwatson * Redistribution and use in source and binary forms, with or without
14101099Srwatson * modification, are permitted provided that the following conditions
15101099Srwatson * are met:
16101099Srwatson * 1. Redistributions of source code must retain the above copyright
17101099Srwatson *    notice, this list of conditions and the following disclaimer.
18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright
19101099Srwatson *    notice, this list of conditions and the following disclaimer in the
20101099Srwatson *    documentation and/or other materials provided with the distribution.
21101099Srwatson *
22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32101099Srwatson * SUCH DAMAGE.
33101099Srwatson *
34101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 134131 2004-08-21 20:15:08Z trhodes $
35101099Srwatson */
36101099Srwatson/*
37101099Srwatson * Developed by the TrustedBSD Project.
38101099Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose
39101099Srwatson * mandatory rules regarding users and some system objects.
40101099Srwatson *
41101099Srwatson * XXX: Much locking support required here.
42101099Srwatson */
43101099Srwatson
44101099Srwatson#include <sys/types.h>
45101099Srwatson#include <sys/param.h>
46101099Srwatson#include <sys/acl.h>
47101099Srwatson#include <sys/conf.h>
48101099Srwatson#include <sys/kernel.h>
49101099Srwatson#include <sys/mac.h>
50101099Srwatson#include <sys/malloc.h>
51101099Srwatson#include <sys/mount.h>
52101099Srwatson#include <sys/proc.h>
53101099Srwatson#include <sys/systm.h>
54101099Srwatson#include <sys/sysproto.h>
55101099Srwatson#include <sys/sysent.h>
56101099Srwatson#include <sys/vnode.h>
57101099Srwatson#include <sys/file.h>
58101099Srwatson#include <sys/socket.h>
59101099Srwatson#include <sys/socketvar.h>
60101099Srwatson#include <sys/sysctl.h>
61101099Srwatson
62101099Srwatson#include <net/bpfdesc.h>
63101099Srwatson#include <net/if.h>
64101099Srwatson#include <net/if_types.h>
65101099Srwatson#include <net/if_var.h>
66101099Srwatson
67101099Srwatson#include <vm/vm.h>
68101099Srwatson
69101099Srwatson#include <sys/mac_policy.h>
70101099Srwatson
71101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h>
72101099Srwatson
73101099SrwatsonSYSCTL_DECL(_security_mac);
74101099Srwatson
75101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
76101099Srwatson    "TrustedBSD extended BSD MAC policy controls");
77101099Srwatson
78101099Srwatsonstatic int	mac_bsdextended_enabled = 1;
79101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
80101099Srwatson    &mac_bsdextended_enabled, 0, "Enforce extended BSD policy");
81101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled);
82101099Srwatson
83101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
84101099Srwatson
85101099Srwatson#define	MAC_BSDEXTENDED_MAXRULES	250
86101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
87101099Srwatsonstatic int rule_count = 0;
88101099Srwatsonstatic int rule_slots = 0;
89101099Srwatson
90101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
91101099Srwatson    &rule_count, 0, "Number of defined rules\n");
92101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
93101099Srwatson    &rule_slots, 0, "Number of used rule slots\n");
94101099Srwatson
95101099Srwatsonstatic int mac_bsdextended_debugging;
96101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, debugging, CTLFLAG_RW,
97101099Srwatson    &mac_bsdextended_debugging, 0, "Enable debugging on failure");
98101099Srwatson
99134131Strhodes/*
100134131Strhodes * This tunable is here for compatibility.  It will allow the user
101134131Strhodes * to switch between the new mode (first rule matches) and the old
102134131Strhodes * functionality (all rules match).
103134131Strhodes */
104101099Srwatsonstatic int
105134131Strhodesmac_bsdextended_firstmatch_enabled;
106134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
107134131Strhodes	CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 0,
108134131Strhodes	"Disable/enable match first rule functionality");
109134131Strhodes
110134131Strhodesstatic int
111101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
112101099Srwatson{
113101099Srwatson
114101099Srwatson	if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS)
115101099Srwatson		return (EINVAL);
116101099Srwatson
117101099Srwatson	if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS)
118101099Srwatson		return (EINVAL);
119101099Srwatson
120101099Srwatson	if ((rule->mbr_mode | VALLPERM) != VALLPERM)
121101099Srwatson		return (EINVAL);
122101099Srwatson
123101099Srwatson	return (0);
124101099Srwatson}
125101099Srwatson
126101099Srwatsonstatic int
127101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS)
128101099Srwatson{
129101099Srwatson	struct mac_bsdextended_rule temprule, *ruleptr;
130101099Srwatson	u_int namelen;
131101099Srwatson	int error, index, *name;
132101099Srwatson
133101099Srwatson	name = (int *)arg1;
134101099Srwatson	namelen = arg2;
135101099Srwatson
136101099Srwatson	/* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
137101099Srwatson
138101099Srwatson	if (namelen != 1)
139101099Srwatson		return (EINVAL);
140101099Srwatson
141101099Srwatson	index = name[0];
142101099Srwatson	if (index < 0 || index > rule_slots + 1)
143101099Srwatson		return (ENOENT);
144101099Srwatson	if (rule_slots >= MAC_BSDEXTENDED_MAXRULES)
145101099Srwatson		return (ENOENT);
146101099Srwatson
147101099Srwatson	if (req->oldptr) {
148101099Srwatson		if (rules[index] == NULL)
149101099Srwatson			return (ENOENT);
150101099Srwatson
151101099Srwatson		error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index]));
152101099Srwatson		if (error)
153101099Srwatson			return (error);
154101099Srwatson	}
155101099Srwatson
156101099Srwatson	if (req->newptr) {
157101099Srwatson		if (req->newlen == 0) {
158101099Srwatson			/* printf("deletion\n"); */
159101099Srwatson			ruleptr = rules[index];
160101099Srwatson			if (ruleptr == NULL)
161101099Srwatson				return (ENOENT);
162101099Srwatson			rule_count--;
163101099Srwatson			rules[index] = NULL;
164101099Srwatson			FREE(ruleptr, M_MACBSDEXTENDED);
165101099Srwatson			return(0);
166101099Srwatson		}
167101099Srwatson		error = SYSCTL_IN(req, &temprule, sizeof(temprule));
168101099Srwatson		if (error)
169101099Srwatson			return (error);
170101099Srwatson
171101099Srwatson		error = mac_bsdextended_rule_valid(&temprule);
172101099Srwatson		if (error)
173101099Srwatson			return (error);
174101099Srwatson
175101099Srwatson		if (rules[index] == NULL) {
176101099Srwatson			/* printf("addition\n"); */
177101099Srwatson			MALLOC(ruleptr, struct mac_bsdextended_rule *,
178111119Simp			    sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK |
179101099Srwatson			    M_ZERO);
180101099Srwatson			*ruleptr = temprule;
181101099Srwatson			rules[index] = ruleptr;
182101099Srwatson			if (index+1 > rule_slots)
183101099Srwatson				rule_slots = index+1;
184101099Srwatson			rule_count++;
185101099Srwatson		} else {
186101099Srwatson			/* printf("replacement\n"); */
187101099Srwatson			*rules[index] = temprule;
188101099Srwatson		}
189101099Srwatson	}
190101099Srwatson
191101099Srwatson	return (0);
192101099Srwatson}
193101099Srwatson
194101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
195101099Srwatson    CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
196101099Srwatson
197101099Srwatsonstatic void
198101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc)
199101099Srwatson{
200101099Srwatson
201101099Srwatson	/* Initialize ruleset lock. */
202101099Srwatson	/* Register dynamic sysctl's for rules. */
203101099Srwatson}
204101099Srwatson
205101099Srwatsonstatic void
206101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc)
207101099Srwatson{
208101099Srwatson
209101099Srwatson	/* Tear down sysctls. */
210101099Srwatson	/* Destroy ruleset lock. */
211101099Srwatson}
212101099Srwatson
213101099Srwatsonstatic int
214101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
215106212Srwatson    struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode)
216101099Srwatson{
217101099Srwatson	int match;
218101099Srwatson
219101099Srwatson	/*
220101099Srwatson	 * Is there a subject match?
221101099Srwatson	 */
222101099Srwatson	if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) {
223101099Srwatson		match =  (rule->mbr_subject.mbi_uid == cred->cr_uid ||
224101099Srwatson		    rule->mbr_subject.mbi_uid == cred->cr_ruid ||
225101099Srwatson		    rule->mbr_subject.mbi_uid == cred->cr_svuid);
226101099Srwatson
227101099Srwatson		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
228101099Srwatson			match = !match;
229101099Srwatson
230101099Srwatson		if (!match)
231101099Srwatson			return (0);
232101099Srwatson	}
233101099Srwatson
234101099Srwatson	if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) {
235101099Srwatson		match = (groupmember(rule->mbr_subject.mbi_gid, cred) ||
236101099Srwatson		    rule->mbr_subject.mbi_gid == cred->cr_rgid ||
237101099Srwatson		    rule->mbr_subject.mbi_gid == cred->cr_svgid);
238101099Srwatson
239101099Srwatson		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
240101099Srwatson			match = !match;
241101099Srwatson
242101099Srwatson		if (!match)
243101099Srwatson			return (0);
244101099Srwatson	}
245101099Srwatson
246101099Srwatson	/*
247101099Srwatson	 * Is there an object match?
248101099Srwatson	 */
249101099Srwatson	if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) {
250101099Srwatson		match = (rule->mbr_object.mbi_uid == object_uid);
251101099Srwatson
252101099Srwatson		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
253101099Srwatson			match = !match;
254101099Srwatson
255101099Srwatson		if (!match)
256101099Srwatson			return (0);
257101099Srwatson	}
258101099Srwatson
259101099Srwatson	if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) {
260101099Srwatson		match = (rule->mbr_object.mbi_gid == object_gid);
261101099Srwatson
262101099Srwatson		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
263101099Srwatson			match = !match;
264101099Srwatson
265101099Srwatson		if (!match)
266101099Srwatson			return (0);
267101099Srwatson	}
268101099Srwatson
269101099Srwatson	/*
270101099Srwatson	 * Is the access permitted?
271101099Srwatson	 */
272101099Srwatson	if ((rule->mbr_mode & acc_mode) != acc_mode) {
273101099Srwatson		if (mac_bsdextended_debugging)
274101099Srwatson			printf("mac_bsdextended: %d:%d request %d on %d:%d"
275101099Srwatson			    " fails\n", cred->cr_ruid, cred->cr_rgid,
276101099Srwatson			    acc_mode, object_uid, object_gid);
277101099Srwatson		return (EACCES);
278101099Srwatson	}
279134131Strhodes	/*
280134131Strhodes	 * If the rule matched and allowed access and first match is
281134131Strhodes	 * enabled, then return success.
282134131Strhodes	 */
283134131Strhodes	if (mac_bsdextended_firstmatch_enabled)
284134131Strhodes		return (EJUSTRETURN);
285134131Strhodes	else
286134131Strhodes		return(0);
287101099Srwatson}
288101099Srwatson
289101099Srwatsonstatic int
290101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid,
291106212Srwatson    int acc_mode)
292101099Srwatson{
293101099Srwatson	int error, i;
294101099Srwatson
295132563Srwatson	if (suser_cred(cred, 0) == 0)
296132563Srwatson		return (0);
297132563Srwatson
298101099Srwatson	for (i = 0; i < rule_slots; i++) {
299101099Srwatson		if (rules[i] == NULL)
300101099Srwatson			continue;
301101099Srwatson
302108376Srwatson		/*
303108376Srwatson		 * Since we don't separately handle append, map append to
304108376Srwatson		 * write.
305108376Srwatson		 */
306108376Srwatson		if (acc_mode & VAPPEND) {
307108376Srwatson			acc_mode &= ~VAPPEND;
308108376Srwatson			acc_mode |= VWRITE;
309108376Srwatson		}
310108376Srwatson
311101099Srwatson		error = mac_bsdextended_rulecheck(rules[i], cred, object_uid,
312101099Srwatson		    object_gid, acc_mode);
313134131Strhodes		if (error == EJUSTRETURN)
314134131Strhodes			break;
315101099Srwatson		if (error)
316101099Srwatson			return (error);
317101099Srwatson	}
318101099Srwatson
319101099Srwatson	return (0);
320101099Srwatson}
321101099Srwatson
322101099Srwatsonstatic int
323112575Srwatsonmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp,
324112575Srwatson    struct label *label)
325112575Srwatson{
326112575Srwatson	struct vattr vap;
327112575Srwatson	int error;
328112575Srwatson
329112575Srwatson	if (!mac_bsdextended_enabled)
330112575Srwatson		return (0);
331112575Srwatson
332112575Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
333112575Srwatson	if (error)
334112575Srwatson		return (error);
335112575Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
336112575Srwatson}
337112575Srwatson
338112575Srwatsonstatic int
339101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
340106212Srwatson    struct label *label, int acc_mode)
341101099Srwatson{
342101099Srwatson	struct vattr vap;
343101099Srwatson	int error;
344101099Srwatson
345101099Srwatson	if (!mac_bsdextended_enabled)
346101099Srwatson		return (0);
347101099Srwatson
348101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
349101099Srwatson	if (error)
350101099Srwatson		return (error);
351106212Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
352101099Srwatson}
353101099Srwatson
354101099Srwatsonstatic int
355101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
356101099Srwatson    struct label *dlabel)
357101099Srwatson{
358101099Srwatson	struct vattr vap;
359101099Srwatson	int error;
360101099Srwatson
361101099Srwatson	if (!mac_bsdextended_enabled)
362101099Srwatson		return (0);
363101099Srwatson
364101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
365101099Srwatson	if (error)
366101099Srwatson		return (error);
367101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
368101099Srwatson}
369101099Srwatson
370101099Srwatsonstatic int
371101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
372101099Srwatson    struct label *dlabel)
373101099Srwatson{
374101099Srwatson	struct vattr vap;
375101099Srwatson	int error;
376101099Srwatson
377101099Srwatson	if (!mac_bsdextended_enabled)
378101099Srwatson		return (0);
379101099Srwatson
380101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
381101099Srwatson	if (error)
382101099Srwatson		return (error);
383101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
384101099Srwatson}
385101099Srwatson
386101099Srwatsonstatic int
387101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
388101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
389101099Srwatson{
390101099Srwatson	struct vattr dvap;
391101099Srwatson	int error;
392101099Srwatson
393101099Srwatson	if (!mac_bsdextended_enabled)
394101099Srwatson		return (0);
395101099Srwatson
396101099Srwatson	error = VOP_GETATTR(dvp, &dvap, cred, curthread);
397101099Srwatson	if (error)
398101099Srwatson		return (error);
399101099Srwatson	return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE));
400101099Srwatson}
401101099Srwatson
402101099Srwatsonstatic int
403101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
404101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
405101099Srwatson    struct componentname *cnp)
406101099Srwatson{
407101099Srwatson	struct vattr vap;
408101099Srwatson	int error;
409101099Srwatson
410101099Srwatson	if (!mac_bsdextended_enabled)
411101099Srwatson		return (0);
412101099Srwatson
413101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
414101099Srwatson	if (error)
415101099Srwatson		return (error);
416101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
417101099Srwatson	if (error)
418101099Srwatson		return (error);
419101099Srwatson
420101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
421101099Srwatson	if (error)
422101099Srwatson		return (error);
423101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
424101099Srwatson}
425101099Srwatson
426101099Srwatsonstatic int
427101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
428101099Srwatson    struct label *label, acl_type_t type)
429101099Srwatson{
430101099Srwatson	struct vattr vap;
431101099Srwatson	int error;
432101099Srwatson
433101099Srwatson	if (!mac_bsdextended_enabled)
434101099Srwatson		return (0);
435101099Srwatson
436101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
437117247Srwatson	if (error)
438101099Srwatson		return (error);
439101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
440101099Srwatson}
441101099Srwatson
442101099Srwatsonstatic int
443119202Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
444119202Srwatson    struct label *label, int attrnamespace, const char *name)
445119202Srwatson{
446119202Srwatson	struct vattr vap;
447119202Srwatson	int error;
448119202Srwatson
449119202Srwatson	if (!mac_bsdextended_enabled)
450119202Srwatson		return (0);
451119202Srwatson
452119202Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
453119202Srwatson	if (error)
454119202Srwatson		return (error);
455119202Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
456119202Srwatson}
457119202Srwatson
458119202Srwatsonstatic int
459101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
460106648Srwatson    struct label *label, struct image_params *imgp,
461106648Srwatson    struct label *execlabel)
462101099Srwatson{
463101099Srwatson	struct vattr vap;
464101099Srwatson	int error;
465101099Srwatson
466101099Srwatson	if (!mac_bsdextended_enabled)
467101099Srwatson		return (0);
468101099Srwatson
469101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
470101099Srwatson	if (error)
471101099Srwatson		return (error);
472101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
473101099Srwatson	    VREAD|VEXEC));
474101099Srwatson}
475101099Srwatson
476101099Srwatsonstatic int
477101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
478101099Srwatson    struct label *label, acl_type_t type)
479101099Srwatson{
480101099Srwatson	struct vattr vap;
481101099Srwatson	int error;
482101099Srwatson
483101099Srwatson	if (!mac_bsdextended_enabled)
484101099Srwatson		return (0);
485101099Srwatson
486101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
487101099Srwatson	if (error)
488101099Srwatson		return (error);
489101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT));
490101099Srwatson}
491101099Srwatson
492101099Srwatsonstatic int
493101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
494101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
495101099Srwatson{
496101099Srwatson	struct vattr vap;
497101099Srwatson	int error;
498101099Srwatson
499101099Srwatson	if (!mac_bsdextended_enabled)
500101099Srwatson		return (0);
501101099Srwatson
502101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
503101099Srwatson	if (error)
504101099Srwatson		return (error);
505101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
506101099Srwatson}
507101099Srwatson
508101099Srwatsonstatic int
509104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
510104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
511104530Srwatson    struct componentname *cnp)
512104530Srwatson{
513104530Srwatson	struct vattr vap;
514104530Srwatson	int error;
515104530Srwatson
516104530Srwatson	if (!mac_bsdextended_enabled)
517104530Srwatson		return (0);
518104530Srwatson
519104530Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
520104530Srwatson	if (error)
521104530Srwatson		return (error);
522104530Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
523106214Srwatson	if (error)
524106214Srwatson		return (error);
525104530Srwatson
526104530Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
527104530Srwatson	if (error)
528104530Srwatson		return (error);
529104530Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
530104530Srwatson	if (error)
531104530Srwatson		return (error);
532104530Srwatson	return (0);
533104530Srwatson}
534104530Srwatson
535104530Srwatsonstatic int
536119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
537119202Srwatson    struct label *label, int attrnamespace)
538119202Srwatson{
539119202Srwatson	struct vattr vap;
540119202Srwatson	int error;
541119202Srwatson
542119202Srwatson	if (!mac_bsdextended_enabled)
543119202Srwatson		return (0);
544119202Srwatson
545119202Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
546119202Srwatson	if (error)
547119202Srwatson		return (error);
548119202Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
549119202Srwatson}
550119202Srwatson
551119202Srwatsonstatic int
552101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
553101099Srwatson    struct label *dlabel, struct componentname *cnp)
554101099Srwatson{
555101099Srwatson	struct vattr vap;
556101099Srwatson	int error;
557117247Srwatson
558101099Srwatson	if (!mac_bsdextended_enabled)
559101099Srwatson		return (0);
560117247Srwatson
561101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
562101099Srwatson	if (error)
563101099Srwatson		return (error);
564101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
565101099Srwatson}
566101099Srwatson
567101099Srwatsonstatic int
568101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
569106212Srwatson    struct label *filelabel, int acc_mode)
570101099Srwatson{
571101099Srwatson	struct vattr vap;
572101099Srwatson	int error;
573101099Srwatson
574101099Srwatson	if (!mac_bsdextended_enabled)
575101099Srwatson		return (0);
576101099Srwatson
577101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
578101099Srwatson	if (error)
579101099Srwatson		return (error);
580101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
581101099Srwatson}
582101099Srwatson
583101099Srwatsonstatic int
584101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
585101099Srwatson    struct label *dlabel)
586101099Srwatson{
587101099Srwatson	struct vattr vap;
588101099Srwatson	int error;
589101099Srwatson
590101099Srwatson	if (!mac_bsdextended_enabled)
591101099Srwatson		return (0);
592101099Srwatson
593101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
594101099Srwatson	if (error)
595101099Srwatson		return (error);
596101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
597101099Srwatson}
598101099Srwatson
599101099Srwatsonstatic int
600101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
601101099Srwatson    struct label *label)
602101099Srwatson{
603101099Srwatson	struct vattr vap;
604101099Srwatson	int error;
605101099Srwatson
606101099Srwatson	if (!mac_bsdextended_enabled)
607101099Srwatson		return (0);
608101099Srwatson
609101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
610101099Srwatson	if (error)
611101099Srwatson		return (error);
612101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
613101099Srwatson}
614101099Srwatson
615101099Srwatsonstatic int
616101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
617101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
618101099Srwatson    struct componentname *cnp)
619101099Srwatson{
620101099Srwatson	struct vattr vap;
621101099Srwatson	int error;
622101099Srwatson
623101099Srwatson	if (!mac_bsdextended_enabled)
624101099Srwatson		return (0);
625101099Srwatson
626101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
627101099Srwatson	if (error)
628101099Srwatson		return (error);
629101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
630101099Srwatson	if (error)
631101099Srwatson		return (error);
632101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
633101099Srwatson	if (error)
634101099Srwatson		return (error);
635101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
636101099Srwatson
637101099Srwatson	return (error);
638101099Srwatson}
639101099Srwatson
640101099Srwatsonstatic int
641101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
642101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
643101099Srwatson    struct componentname *cnp)
644101099Srwatson{
645101099Srwatson	struct vattr vap;
646101099Srwatson	int error;
647101099Srwatson
648101099Srwatson	if (!mac_bsdextended_enabled)
649101099Srwatson		return (0);
650101099Srwatson
651101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
652101099Srwatson	if (error)
653101099Srwatson		return (error);
654101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
655101099Srwatson	if (error)
656101099Srwatson		return (error);
657101099Srwatson
658101099Srwatson	if (vp != NULL) {
659101099Srwatson		error = VOP_GETATTR(vp, &vap, cred, curthread);
660101099Srwatson		if (error)
661101099Srwatson			return (error);
662101099Srwatson		error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
663101099Srwatson		    VWRITE);
664101099Srwatson	}
665101099Srwatson
666101099Srwatson	return (error);
667101099Srwatson}
668101099Srwatson
669101099Srwatsonstatic int
670101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
671101099Srwatson    struct label *label)
672101099Srwatson{
673101099Srwatson	struct vattr vap;
674101099Srwatson	int error;
675101099Srwatson
676101099Srwatson	if (!mac_bsdextended_enabled)
677101099Srwatson		return (0);
678101099Srwatson
679101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
680101099Srwatson	if (error)
681101099Srwatson		return (error);
682101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
683101099Srwatson}
684101099Srwatson
685101099Srwatsonstatic int
686101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
687101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
688101099Srwatson{
689101099Srwatson	struct vattr vap;
690101099Srwatson	int error;
691101099Srwatson
692101099Srwatson	if (!mac_bsdextended_enabled)
693101099Srwatson		return (0);
694101099Srwatson
695101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
696101099Srwatson	if (error)
697101099Srwatson		return (error);
698101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
699101099Srwatson}
700101099Srwatson
701101099Srwatsonstatic int
702101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
703101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
704101099Srwatson{
705101099Srwatson	struct vattr vap;
706101099Srwatson	int error;
707101099Srwatson
708101099Srwatson	if (!mac_bsdextended_enabled)
709101099Srwatson		return (0);
710101099Srwatson
711101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
712101099Srwatson	if (error)
713101099Srwatson		return (error);
714101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
715101099Srwatson}
716101099Srwatson
717101099Srwatsonstatic int
718101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
719101099Srwatson    struct label *label, u_long flags)
720101099Srwatson{
721101099Srwatson	struct vattr vap;
722101099Srwatson	int error;
723101099Srwatson
724101099Srwatson	if (!mac_bsdextended_enabled)
725101099Srwatson		return (0);
726101099Srwatson
727101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
728101099Srwatson	if (error)
729101099Srwatson		return (error);
730101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
731101099Srwatson}
732101099Srwatson
733101099Srwatsonstatic int
734101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
735101099Srwatson    struct label *label, mode_t mode)
736101099Srwatson{
737101099Srwatson	struct vattr vap;
738101099Srwatson	int error;
739101099Srwatson
740101099Srwatson	if (!mac_bsdextended_enabled)
741101099Srwatson		return (0);
742101099Srwatson
743101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
744101099Srwatson	if (error)
745101099Srwatson		return (error);
746101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
747101099Srwatson}
748101099Srwatson
749101099Srwatsonstatic int
750101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
751101099Srwatson    struct label *label, uid_t uid, gid_t gid)
752101099Srwatson{
753101099Srwatson	struct vattr vap;
754101099Srwatson	int error;
755101099Srwatson
756101099Srwatson	if (!mac_bsdextended_enabled)
757101099Srwatson		return (0);
758101099Srwatson
759101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
760101099Srwatson	if (error)
761101099Srwatson		return (error);
762101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
763101099Srwatson}
764101099Srwatson
765101099Srwatsonstatic int
766101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
767101099Srwatson    struct label *label, struct timespec atime, struct timespec utime)
768101099Srwatson{
769101099Srwatson	struct vattr vap;
770101099Srwatson	int error;
771101099Srwatson
772101099Srwatson	if (!mac_bsdextended_enabled)
773101099Srwatson		return (0);
774101099Srwatson
775101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
776101099Srwatson	if (error)
777101099Srwatson		return (error);
778101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
779101099Srwatson}
780101099Srwatson
781101099Srwatsonstatic int
782102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred,
783102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
784101099Srwatson{
785101099Srwatson	struct vattr vap;
786101099Srwatson	int error;
787101099Srwatson
788101099Srwatson	if (!mac_bsdextended_enabled)
789101099Srwatson		return (0);
790101099Srwatson
791102129Srwatson	error = VOP_GETATTR(vp, &vap, active_cred, curthread);
792101099Srwatson	if (error)
793101099Srwatson		return (error);
794102129Srwatson	return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid,
795102129Srwatson	    VSTAT));
796101099Srwatson}
797101099Srwatson
798106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops =
799101099Srwatson{
800106217Srwatson	.mpo_destroy = mac_bsdextended_destroy,
801106217Srwatson	.mpo_init = mac_bsdextended_init,
802112575Srwatson	.mpo_check_system_swapon = mac_bsdextended_check_system_swapon,
803106217Srwatson	.mpo_check_vnode_access = mac_bsdextended_check_vnode_access,
804106217Srwatson	.mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir,
805106217Srwatson	.mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot,
806106217Srwatson	.mpo_check_vnode_create = mac_bsdextended_check_create_vnode,
807106217Srwatson	.mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete,
808106217Srwatson	.mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl,
809119202Srwatson	.mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr,
810106217Srwatson	.mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec,
811106217Srwatson	.mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl,
812106217Srwatson	.mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr,
813106217Srwatson	.mpo_check_vnode_link = mac_bsdextended_check_vnode_link,
814119202Srwatson	.mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr,
815106217Srwatson	.mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup,
816106217Srwatson	.mpo_check_vnode_open = mac_bsdextended_check_vnode_open,
817106217Srwatson	.mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir,
818106217Srwatson	.mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink,
819106217Srwatson	.mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from,
820106217Srwatson	.mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to,
821106217Srwatson	.mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke,
822106217Srwatson	.mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode,
823106217Srwatson	.mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr,
824106217Srwatson	.mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags,
825106217Srwatson	.mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode,
826106217Srwatson	.mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner,
827106217Srwatson	.mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes,
828106217Srwatson	.mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat,
829101099Srwatson};
830101099Srwatson
831112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended,
832101099Srwatson    "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
833