ugidfw_vnode.c revision 104530
1101099Srwatson/*-
2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3101099Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
4101099Srwatson * All rights reserved.
5101099Srwatson *
6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project.
7101099Srwatson *
8101099Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs,
9101099Srwatson * the Security Research Division of Network Associates, Inc. under
10101099Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
11101099Srwatson * 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 * 3. The names of the authors may not be used to endorse or promote
22101099Srwatson *    products derived from this software without specific prior written
23101099Srwatson *    permission.
24101099Srwatson *
25101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28101099Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35101099Srwatson * SUCH DAMAGE.
36101099Srwatson *
37101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 104530 2002-10-05 18:25:48Z rwatson $
38101099Srwatson */
39101099Srwatson/*
40101099Srwatson * Developed by the TrustedBSD Project.
41101099Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose
42101099Srwatson * mandatory rules regarding users and some system objects.
43101099Srwatson *
44101099Srwatson * XXX: Much locking support required here.
45101099Srwatson */
46101099Srwatson
47101099Srwatson#include <sys/types.h>
48101099Srwatson#include <sys/param.h>
49101099Srwatson#include <sys/acl.h>
50101099Srwatson#include <sys/conf.h>
51101099Srwatson#include <sys/kernel.h>
52101099Srwatson#include <sys/mac.h>
53101099Srwatson#include <sys/malloc.h>
54101099Srwatson#include <sys/mount.h>
55101099Srwatson#include <sys/proc.h>
56101099Srwatson#include <sys/systm.h>
57101099Srwatson#include <sys/sysproto.h>
58101099Srwatson#include <sys/sysent.h>
59101099Srwatson#include <sys/vnode.h>
60101099Srwatson#include <sys/file.h>
61101099Srwatson#include <sys/socket.h>
62101099Srwatson#include <sys/socketvar.h>
63101099Srwatson#include <sys/sysctl.h>
64101099Srwatson
65101099Srwatson#include <net/bpfdesc.h>
66101099Srwatson#include <net/if.h>
67101099Srwatson#include <net/if_types.h>
68101099Srwatson#include <net/if_var.h>
69101099Srwatson
70101099Srwatson#include <vm/vm.h>
71101099Srwatson
72101099Srwatson#include <sys/mac_policy.h>
73101099Srwatson
74101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h>
75101099Srwatson
76101099SrwatsonSYSCTL_DECL(_security_mac);
77101099Srwatson
78101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
79101099Srwatson    "TrustedBSD extended BSD MAC policy controls");
80101099Srwatson
81101099Srwatsonstatic int	mac_bsdextended_enabled = 1;
82101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
83101099Srwatson    &mac_bsdextended_enabled, 0, "Enforce extended BSD policy");
84101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled);
85101099Srwatson
86101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
87101099Srwatson
88101099Srwatson#define	MAC_BSDEXTENDED_MAXRULES	250
89101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
90101099Srwatsonstatic int rule_count = 0;
91101099Srwatsonstatic int rule_slots = 0;
92101099Srwatson
93101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
94101099Srwatson    &rule_count, 0, "Number of defined rules\n");
95101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
96101099Srwatson    &rule_slots, 0, "Number of used rule slots\n");
97101099Srwatson
98101099Srwatsonstatic int mac_bsdextended_debugging;
99101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, debugging, CTLFLAG_RW,
100101099Srwatson    &mac_bsdextended_debugging, 0, "Enable debugging on failure");
101101099Srwatson
102101099Srwatsonstatic int
103101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
104101099Srwatson{
105101099Srwatson
106101099Srwatson	if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS)
107101099Srwatson		return (EINVAL);
108101099Srwatson
109101099Srwatson	if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS)
110101099Srwatson		return (EINVAL);
111101099Srwatson
112101099Srwatson	if ((rule->mbr_mode | VALLPERM) != VALLPERM)
113101099Srwatson		return (EINVAL);
114101099Srwatson
115101099Srwatson	return (0);
116101099Srwatson}
117101099Srwatson
118101099Srwatsonstatic int
119101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS)
120101099Srwatson{
121101099Srwatson	struct mac_bsdextended_rule temprule, *ruleptr;
122101099Srwatson	u_int namelen;
123101099Srwatson	int error, index, *name;
124101099Srwatson
125101099Srwatson	name = (int *)arg1;
126101099Srwatson	namelen = arg2;
127101099Srwatson
128101099Srwatson	/* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
129101099Srwatson
130101099Srwatson	if (namelen != 1)
131101099Srwatson		return (EINVAL);
132101099Srwatson
133101099Srwatson	index = name[0];
134101099Srwatson	if (index < 0 || index > rule_slots + 1)
135101099Srwatson		return (ENOENT);
136101099Srwatson	if (rule_slots >= MAC_BSDEXTENDED_MAXRULES)
137101099Srwatson		return (ENOENT);
138101099Srwatson
139101099Srwatson	if (req->oldptr) {
140101099Srwatson		if (rules[index] == NULL)
141101099Srwatson			return (ENOENT);
142101099Srwatson
143101099Srwatson		error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index]));
144101099Srwatson		if (error)
145101099Srwatson			return (error);
146101099Srwatson	}
147101099Srwatson
148101099Srwatson	if (req->newptr) {
149101099Srwatson		if (req->newlen == 0) {
150101099Srwatson			/* printf("deletion\n"); */
151101099Srwatson			ruleptr = rules[index];
152101099Srwatson			if (ruleptr == NULL)
153101099Srwatson				return (ENOENT);
154101099Srwatson			rule_count--;
155101099Srwatson			rules[index] = NULL;
156101099Srwatson			FREE(ruleptr, M_MACBSDEXTENDED);
157101099Srwatson			return(0);
158101099Srwatson		}
159101099Srwatson		error = SYSCTL_IN(req, &temprule, sizeof(temprule));
160101099Srwatson		if (error)
161101099Srwatson			return (error);
162101099Srwatson
163101099Srwatson		error = mac_bsdextended_rule_valid(&temprule);
164101099Srwatson		if (error)
165101099Srwatson			return (error);
166101099Srwatson
167101099Srwatson		if (rules[index] == NULL) {
168101099Srwatson			/* printf("addition\n"); */
169101099Srwatson			MALLOC(ruleptr, struct mac_bsdextended_rule *,
170101099Srwatson			    sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK |
171101099Srwatson			    M_ZERO);
172101099Srwatson			*ruleptr = temprule;
173101099Srwatson			rules[index] = ruleptr;
174101099Srwatson			if (index+1 > rule_slots)
175101099Srwatson				rule_slots = index+1;
176101099Srwatson			rule_count++;
177101099Srwatson		} else {
178101099Srwatson			/* printf("replacement\n"); */
179101099Srwatson			*rules[index] = temprule;
180101099Srwatson		}
181101099Srwatson	}
182101099Srwatson
183101099Srwatson	return (0);
184101099Srwatson}
185101099Srwatson
186101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
187101099Srwatson    CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
188101099Srwatson
189101099Srwatsonstatic void
190101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc)
191101099Srwatson{
192101099Srwatson
193101099Srwatson	/* Initialize ruleset lock. */
194101099Srwatson	/* Register dynamic sysctl's for rules. */
195101099Srwatson}
196101099Srwatson
197101099Srwatsonstatic void
198101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc)
199101099Srwatson{
200101099Srwatson
201101099Srwatson	/* Tear down sysctls. */
202101099Srwatson	/* Destroy ruleset lock. */
203101099Srwatson}
204101099Srwatson
205101099Srwatsonstatic int
206101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
207101099Srwatson    struct ucred *cred, uid_t object_uid, gid_t object_gid, mode_t acc_mode)
208101099Srwatson{
209101099Srwatson	int match;
210101099Srwatson
211101099Srwatson	/*
212101099Srwatson	 * Is there a subject match?
213101099Srwatson	 */
214101099Srwatson	if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) {
215101099Srwatson		match =  (rule->mbr_subject.mbi_uid == cred->cr_uid ||
216101099Srwatson		    rule->mbr_subject.mbi_uid == cred->cr_ruid ||
217101099Srwatson		    rule->mbr_subject.mbi_uid == cred->cr_svuid);
218101099Srwatson
219101099Srwatson		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
220101099Srwatson			match = !match;
221101099Srwatson
222101099Srwatson		if (!match)
223101099Srwatson			return (0);
224101099Srwatson	}
225101099Srwatson
226101099Srwatson	if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) {
227101099Srwatson		match = (groupmember(rule->mbr_subject.mbi_gid, cred) ||
228101099Srwatson		    rule->mbr_subject.mbi_gid == cred->cr_rgid ||
229101099Srwatson		    rule->mbr_subject.mbi_gid == cred->cr_svgid);
230101099Srwatson
231101099Srwatson		if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
232101099Srwatson			match = !match;
233101099Srwatson
234101099Srwatson		if (!match)
235101099Srwatson			return (0);
236101099Srwatson	}
237101099Srwatson
238101099Srwatson	/*
239101099Srwatson	 * Is there an object match?
240101099Srwatson	 */
241101099Srwatson	if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) {
242101099Srwatson		match = (rule->mbr_object.mbi_uid == object_uid);
243101099Srwatson
244101099Srwatson		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
245101099Srwatson			match = !match;
246101099Srwatson
247101099Srwatson		if (!match)
248101099Srwatson			return (0);
249101099Srwatson	}
250101099Srwatson
251101099Srwatson	if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) {
252101099Srwatson		match = (rule->mbr_object.mbi_gid == object_gid);
253101099Srwatson
254101099Srwatson		if (rule->mbr_object.mbi_flags & MBI_NEGATED)
255101099Srwatson			match = !match;
256101099Srwatson
257101099Srwatson		if (!match)
258101099Srwatson			return (0);
259101099Srwatson	}
260101099Srwatson
261101099Srwatson	/*
262101099Srwatson	 * Is the access permitted?
263101099Srwatson	 */
264101099Srwatson	if ((rule->mbr_mode & acc_mode) != acc_mode) {
265101099Srwatson		if (mac_bsdextended_debugging)
266101099Srwatson			printf("mac_bsdextended: %d:%d request %d on %d:%d"
267101099Srwatson			    " fails\n", cred->cr_ruid, cred->cr_rgid,
268101099Srwatson			    acc_mode, object_uid, object_gid);
269101099Srwatson		return (EACCES);
270101099Srwatson	}
271101099Srwatson
272101099Srwatson	return (0);
273101099Srwatson}
274101099Srwatson
275101099Srwatsonstatic int
276101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid,
277101099Srwatson    mode_t acc_mode)
278101099Srwatson{
279101099Srwatson	int error, i;
280101099Srwatson
281101099Srwatson	for (i = 0; i < rule_slots; i++) {
282101099Srwatson		if (rules[i] == NULL)
283101099Srwatson			continue;
284101099Srwatson
285101099Srwatson		error = mac_bsdextended_rulecheck(rules[i], cred, object_uid,
286101099Srwatson		    object_gid, acc_mode);
287101099Srwatson		if (error)
288101099Srwatson			return (error);
289101099Srwatson	}
290101099Srwatson
291101099Srwatson	return (0);
292101099Srwatson}
293101099Srwatson
294101099Srwatsonstatic int
295101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
296101099Srwatson    struct label *label, mode_t flags)
297101099Srwatson{
298101099Srwatson	struct vattr vap;
299101099Srwatson	int error;
300101099Srwatson
301101099Srwatson	if (!mac_bsdextended_enabled)
302101099Srwatson		return (0);
303101099Srwatson
304101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
305101099Srwatson	if (error)
306101099Srwatson		return (error);
307101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, flags));
308101099Srwatson}
309101099Srwatson
310101099Srwatsonstatic int
311101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
312101099Srwatson    struct label *dlabel)
313101099Srwatson{
314101099Srwatson	struct vattr vap;
315101099Srwatson	int error;
316101099Srwatson
317101099Srwatson	if (!mac_bsdextended_enabled)
318101099Srwatson		return (0);
319101099Srwatson
320101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
321101099Srwatson	if (error)
322101099Srwatson		return (error);
323101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
324101099Srwatson}
325101099Srwatson
326101099Srwatsonstatic int
327101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
328101099Srwatson    struct label *dlabel)
329101099Srwatson{
330101099Srwatson	struct vattr vap;
331101099Srwatson	int error;
332101099Srwatson
333101099Srwatson	if (!mac_bsdextended_enabled)
334101099Srwatson		return (0);
335101099Srwatson
336101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
337101099Srwatson	if (error)
338101099Srwatson		return (error);
339101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
340101099Srwatson}
341101099Srwatson
342101099Srwatsonstatic int
343101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
344101099Srwatson    struct label *dlabel, struct componentname *cnp, struct vattr *vap)
345101099Srwatson{
346101099Srwatson	struct vattr dvap;
347101099Srwatson	int error;
348101099Srwatson
349101099Srwatson	if (!mac_bsdextended_enabled)
350101099Srwatson		return (0);
351101099Srwatson
352101099Srwatson	error = VOP_GETATTR(dvp, &dvap, cred, curthread);
353101099Srwatson	if (error)
354101099Srwatson		return (error);
355101099Srwatson	return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE));
356101099Srwatson}
357101099Srwatson
358101099Srwatsonstatic int
359101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
360101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
361101099Srwatson    struct componentname *cnp)
362101099Srwatson{
363101099Srwatson	struct vattr vap;
364101099Srwatson	int error;
365101099Srwatson
366101099Srwatson	if (!mac_bsdextended_enabled)
367101099Srwatson		return (0);
368101099Srwatson
369101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
370101099Srwatson	if (error)
371101099Srwatson		return (error);
372101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
373101099Srwatson	if (error)
374101099Srwatson		return (error);
375101099Srwatson
376101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
377101099Srwatson	if (error)
378101099Srwatson		return (error);
379101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
380101099Srwatson}
381101099Srwatson
382101099Srwatsonstatic int
383101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
384101099Srwatson    struct label *label, acl_type_t type)
385101099Srwatson{
386101099Srwatson	struct vattr vap;
387101099Srwatson	int error;
388101099Srwatson
389101099Srwatson	if (!mac_bsdextended_enabled)
390101099Srwatson		return (0);
391101099Srwatson
392101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
393101099Srwatson	if (error)
394101099Srwatson		return (error);
395101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
396101099Srwatson}
397101099Srwatson
398101099Srwatsonstatic int
399101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
400101099Srwatson    struct label *label)
401101099Srwatson{
402101099Srwatson	struct vattr vap;
403101099Srwatson	int error;
404101099Srwatson
405101099Srwatson	if (!mac_bsdextended_enabled)
406101099Srwatson		return (0);
407101099Srwatson
408101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
409101099Srwatson	if (error)
410101099Srwatson		return (error);
411101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
412101099Srwatson	    VREAD|VEXEC));
413101099Srwatson}
414101099Srwatson
415101099Srwatsonstatic int
416101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
417101099Srwatson    struct label *label, acl_type_t type)
418101099Srwatson{
419101099Srwatson	struct vattr vap;
420101099Srwatson	int error;
421101099Srwatson
422101099Srwatson	if (!mac_bsdextended_enabled)
423101099Srwatson		return (0);
424101099Srwatson
425101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
426101099Srwatson	if (error)
427101099Srwatson		return (error);
428101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT));
429101099Srwatson}
430101099Srwatson
431101099Srwatsonstatic int
432101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
433101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
434101099Srwatson{
435101099Srwatson	struct vattr vap;
436101099Srwatson	int error;
437101099Srwatson
438101099Srwatson	if (!mac_bsdextended_enabled)
439101099Srwatson		return (0);
440101099Srwatson
441101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
442101099Srwatson	if (error)
443101099Srwatson		return (error);
444101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
445101099Srwatson}
446101099Srwatson
447101099Srwatsonstatic int
448104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
449104530Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
450104530Srwatson    struct componentname *cnp)
451104530Srwatson{
452104530Srwatson	struct vattr vap;
453104530Srwatson	int error;
454104530Srwatson
455104530Srwatson	if (!mac_bsdextended_enabled)
456104530Srwatson		return (0);
457104530Srwatson
458104530Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
459104530Srwatson	if (error)
460104530Srwatson		return (error);
461104530Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
462104530Srwatson		if (error)
463104530Srwatson	return (error);
464104530Srwatson
465104530Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
466104530Srwatson	if (error)
467104530Srwatson		return (error);
468104530Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
469104530Srwatson	if (error)
470104530Srwatson		return (error);
471104530Srwatson	return (0);
472104530Srwatson}
473104530Srwatson
474104530Srwatsonstatic int
475101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
476101099Srwatson    struct label *dlabel, struct componentname *cnp)
477101099Srwatson{
478101099Srwatson	struct vattr vap;
479101099Srwatson	int error;
480101099Srwatson
481101099Srwatson	if (!mac_bsdextended_enabled)
482101099Srwatson		return (0);
483101099Srwatson
484101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
485101099Srwatson	if (error)
486101099Srwatson		return (error);
487101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC));
488101099Srwatson}
489101099Srwatson
490101099Srwatsonstatic int
491101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
492101099Srwatson    struct label *filelabel, mode_t acc_mode)
493101099Srwatson{
494101099Srwatson	struct vattr vap;
495101099Srwatson	int error;
496101099Srwatson
497101099Srwatson	if (!mac_bsdextended_enabled)
498101099Srwatson		return (0);
499101099Srwatson
500101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
501101099Srwatson	if (error)
502101099Srwatson		return (error);
503101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
504101099Srwatson}
505101099Srwatson
506101099Srwatsonstatic int
507101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
508101099Srwatson    struct label *dlabel)
509101099Srwatson{
510101099Srwatson	struct vattr vap;
511101099Srwatson	int error;
512101099Srwatson
513101099Srwatson	if (!mac_bsdextended_enabled)
514101099Srwatson		return (0);
515101099Srwatson
516101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
517101099Srwatson	if (error)
518101099Srwatson		return (error);
519101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
520101099Srwatson}
521101099Srwatson
522101099Srwatsonstatic int
523101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
524101099Srwatson    struct label *label)
525101099Srwatson{
526101099Srwatson	struct vattr vap;
527101099Srwatson	int error;
528101099Srwatson
529101099Srwatson	if (!mac_bsdextended_enabled)
530101099Srwatson		return (0);
531101099Srwatson
532101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
533101099Srwatson	if (error)
534101099Srwatson		return (error);
535101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD));
536101099Srwatson}
537101099Srwatson
538101099Srwatsonstatic int
539101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
540101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label,
541101099Srwatson    struct componentname *cnp)
542101099Srwatson{
543101099Srwatson	struct vattr vap;
544101099Srwatson	int error;
545101099Srwatson
546101099Srwatson	if (!mac_bsdextended_enabled)
547101099Srwatson		return (0);
548101099Srwatson
549101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
550101099Srwatson	if (error)
551101099Srwatson		return (error);
552101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
553101099Srwatson	if (error)
554101099Srwatson		return (error);
555101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
556101099Srwatson	if (error)
557101099Srwatson		return (error);
558101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
559101099Srwatson
560101099Srwatson	return (error);
561101099Srwatson}
562101099Srwatson
563101099Srwatsonstatic int
564101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
565101099Srwatson    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
566101099Srwatson    struct componentname *cnp)
567101099Srwatson{
568101099Srwatson	struct vattr vap;
569101099Srwatson	int error;
570101099Srwatson
571101099Srwatson	if (!mac_bsdextended_enabled)
572101099Srwatson		return (0);
573101099Srwatson
574101099Srwatson	error = VOP_GETATTR(dvp, &vap, cred, curthread);
575101099Srwatson	if (error)
576101099Srwatson		return (error);
577101099Srwatson	error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE);
578101099Srwatson	if (error)
579101099Srwatson		return (error);
580101099Srwatson
581101099Srwatson	if (vp != NULL) {
582101099Srwatson		error = VOP_GETATTR(vp, &vap, cred, curthread);
583101099Srwatson		if (error)
584101099Srwatson			return (error);
585101099Srwatson		error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
586101099Srwatson		    VWRITE);
587101099Srwatson	}
588101099Srwatson
589101099Srwatson	return (error);
590101099Srwatson}
591101099Srwatson
592101099Srwatsonstatic int
593101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
594101099Srwatson    struct label *label)
595101099Srwatson{
596101099Srwatson	struct vattr vap;
597101099Srwatson	int error;
598101099Srwatson
599101099Srwatson	if (!mac_bsdextended_enabled)
600101099Srwatson		return (0);
601101099Srwatson
602101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
603101099Srwatson	if (error)
604101099Srwatson		return (error);
605101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
606101099Srwatson}
607101099Srwatson
608101099Srwatsonstatic int
609101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
610101099Srwatson    struct label *label, acl_type_t type, struct acl *acl)
611101099Srwatson{
612101099Srwatson	struct vattr vap;
613101099Srwatson	int error;
614101099Srwatson
615101099Srwatson	if (!mac_bsdextended_enabled)
616101099Srwatson		return (0);
617101099Srwatson
618101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
619101099Srwatson	if (error)
620101099Srwatson		return (error);
621101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
622101099Srwatson}
623101099Srwatson
624101099Srwatsonstatic int
625101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
626101099Srwatson    struct label *label, int attrnamespace, const char *name, struct uio *uio)
627101099Srwatson{
628101099Srwatson	struct vattr vap;
629101099Srwatson	int error;
630101099Srwatson
631101099Srwatson	if (!mac_bsdextended_enabled)
632101099Srwatson		return (0);
633101099Srwatson
634101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
635101099Srwatson	if (error)
636101099Srwatson		return (error);
637101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE));
638101099Srwatson}
639101099Srwatson
640101099Srwatsonstatic int
641101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
642101099Srwatson    struct label *label, u_long flags)
643101099Srwatson{
644101099Srwatson	struct vattr vap;
645101099Srwatson	int error;
646101099Srwatson
647101099Srwatson	if (!mac_bsdextended_enabled)
648101099Srwatson		return (0);
649101099Srwatson
650101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
651101099Srwatson	if (error)
652101099Srwatson		return (error);
653101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
654101099Srwatson}
655101099Srwatson
656101099Srwatsonstatic int
657101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
658101099Srwatson    struct label *label, mode_t mode)
659101099Srwatson{
660101099Srwatson	struct vattr vap;
661101099Srwatson	int error;
662101099Srwatson
663101099Srwatson	if (!mac_bsdextended_enabled)
664101099Srwatson		return (0);
665101099Srwatson
666101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
667101099Srwatson	if (error)
668101099Srwatson		return (error);
669101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
670101099Srwatson}
671101099Srwatson
672101099Srwatsonstatic int
673101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
674101099Srwatson    struct label *label, uid_t uid, gid_t gid)
675101099Srwatson{
676101099Srwatson	struct vattr vap;
677101099Srwatson	int error;
678101099Srwatson
679101099Srwatson	if (!mac_bsdextended_enabled)
680101099Srwatson		return (0);
681101099Srwatson
682101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
683101099Srwatson	if (error)
684101099Srwatson		return (error);
685101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
686101099Srwatson}
687101099Srwatson
688101099Srwatsonstatic int
689101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
690101099Srwatson    struct label *label, struct timespec atime, struct timespec utime)
691101099Srwatson{
692101099Srwatson	struct vattr vap;
693101099Srwatson	int error;
694101099Srwatson
695101099Srwatson	if (!mac_bsdextended_enabled)
696101099Srwatson		return (0);
697101099Srwatson
698101099Srwatson	error = VOP_GETATTR(vp, &vap, cred, curthread);
699101099Srwatson	if (error)
700101099Srwatson		return (error);
701101099Srwatson	return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN));
702101099Srwatson}
703101099Srwatson
704101099Srwatsonstatic int
705102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred,
706102129Srwatson    struct ucred *file_cred, struct vnode *vp, struct label *label)
707101099Srwatson{
708101099Srwatson	struct vattr vap;
709101099Srwatson	int error;
710101099Srwatson
711101099Srwatson	if (!mac_bsdextended_enabled)
712101099Srwatson		return (0);
713101099Srwatson
714102129Srwatson	error = VOP_GETATTR(vp, &vap, active_cred, curthread);
715101099Srwatson	if (error)
716101099Srwatson		return (error);
717102129Srwatson	return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid,
718102129Srwatson	    VSTAT));
719101099Srwatson}
720101099Srwatson
721101099Srwatsonstatic struct mac_policy_op_entry mac_bsdextended_ops[] =
722101099Srwatson{
723101099Srwatson	{ MAC_DESTROY,
724101099Srwatson	    (macop_t)mac_bsdextended_destroy },
725101099Srwatson	{ MAC_INIT,
726101099Srwatson	    (macop_t)mac_bsdextended_init },
727101099Srwatson	{ MAC_CHECK_VNODE_ACCESS,
728101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_access },
729101099Srwatson	{ MAC_CHECK_VNODE_CHDIR,
730101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_chdir },
731101099Srwatson	{ MAC_CHECK_VNODE_CHROOT,
732101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_chroot },
733101099Srwatson	{ MAC_CHECK_VNODE_CREATE,
734101099Srwatson	    (macop_t)mac_bsdextended_check_create_vnode },
735101099Srwatson	{ MAC_CHECK_VNODE_DELETE,
736101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_delete },
737101099Srwatson	{ MAC_CHECK_VNODE_DELETEACL,
738101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_deleteacl },
739101099Srwatson	{ MAC_CHECK_VNODE_EXEC,
740101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_exec },
741101099Srwatson	{ MAC_CHECK_VNODE_GETACL,
742101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_getacl },
743101099Srwatson	{ MAC_CHECK_VNODE_GETEXTATTR,
744101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_getextattr },
745104530Srwatson	{ MAC_CHECK_VNODE_LINK,
746104530Srwatson	    (macop_t)mac_bsdextended_check_vnode_link },
747101099Srwatson	{ MAC_CHECK_VNODE_LOOKUP,
748101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_lookup },
749101099Srwatson	{ MAC_CHECK_VNODE_OPEN,
750101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_open },
751101099Srwatson	{ MAC_CHECK_VNODE_READDIR,
752101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_readdir },
753101099Srwatson	{ MAC_CHECK_VNODE_READLINK,
754101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_readdlink },
755101099Srwatson	{ MAC_CHECK_VNODE_RENAME_FROM,
756101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_rename_from },
757101099Srwatson	{ MAC_CHECK_VNODE_RENAME_TO,
758101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_rename_to },
759101099Srwatson	{ MAC_CHECK_VNODE_REVOKE,
760101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_revoke },
761101099Srwatson	{ MAC_CHECK_VNODE_SETACL,
762101099Srwatson	    (macop_t)mac_bsdextended_check_setacl_vnode },
763101099Srwatson	{ MAC_CHECK_VNODE_SETEXTATTR,
764101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_setextattr },
765101099Srwatson	{ MAC_CHECK_VNODE_SETFLAGS,
766101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_setflags },
767101099Srwatson	{ MAC_CHECK_VNODE_SETMODE,
768101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_setmode },
769101099Srwatson	{ MAC_CHECK_VNODE_SETOWNER,
770101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_setowner },
771101099Srwatson	{ MAC_CHECK_VNODE_SETUTIMES,
772101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_setutimes },
773101099Srwatson	{ MAC_CHECK_VNODE_STAT,
774101099Srwatson	    (macop_t)mac_bsdextended_check_vnode_stat },
775101099Srwatson	{ MAC_OP_LAST, NULL }
776101099Srwatson};
777101099Srwatson
778101099SrwatsonMAC_POLICY_SET(mac_bsdextended_ops, trustedbsd_mac_bsdextended,
779101099Srwatson    "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
780