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