Deleted Added
full compact
1/*-
2 * Copyright (c) 1999-2002 Robert N. M. Watson
3 * Copyright (c) 2001-2003 Networks Associates Technology, Inc.
3 * Copyright (c) 2001-2004 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed by Robert Watson for the TrustedBSD Project.
7 *
8 * This software was developed for the FreeBSD Project in part by Network
9 * Associates Laboratories, the Security Research Division of Network
10 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
11 * as part of the DARPA CHATS research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 136739 2004-10-21 11:19:02Z rwatson $
34 * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 136742 2004-10-21 11:29:56Z rwatson $
35 */
36/*
37 * Developed by the TrustedBSD Project.
38 * "BSD Extended" MAC policy, allowing the administrator to impose
39 * mandatory rules regarding users and some system objects.
40 *
41 * XXX: Much locking support required here.
42 */
43
44#include <sys/types.h>
45#include <sys/param.h>
46#include <sys/acl.h>
47#include <sys/conf.h>
48#include <sys/kernel.h>
49#include <sys/mac.h>
50#include <sys/malloc.h>
51#include <sys/mount.h>
52#include <sys/proc.h>
53#include <sys/systm.h>
54#include <sys/sysproto.h>
55#include <sys/sysent.h>
56#include <sys/vnode.h>
57#include <sys/file.h>
58#include <sys/socket.h>
59#include <sys/socketvar.h>
60#include <sys/sysctl.h>
61#include <sys/syslog.h>
62
63#include <net/bpfdesc.h>
64#include <net/if.h>
65#include <net/if_types.h>
66#include <net/if_var.h>
67
68#include <vm/vm.h>
69
70#include <sys/mac_policy.h>
71
72#include <security/mac_bsdextended/mac_bsdextended.h>
73
74SYSCTL_DECL(_security_mac);
75
76SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0,
77 "TrustedBSD extended BSD MAC policy controls");
78
79static int mac_bsdextended_enabled = 1;
80SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW,
81 &mac_bsdextended_enabled, 0, "Enforce extended BSD policy");
82TUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled);
83
84MALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule");
85
86#define MAC_BSDEXTENDED_MAXRULES 250
87static struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES];
88static int rule_count = 0;
89static int rule_slots = 0;
90
91SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD,
92 &rule_count, 0, "Number of defined rules\n");
93SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD,
94 &rule_slots, 0, "Number of used rule slots\n");
95
96/*
97 * This is just used for logging purposes as eventually we would like
98 * to log much more then failed requests.
99 */
100static int mac_bsdextended_logging;
101SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW,
102 &mac_bsdextended_logging, 0, "Log failed authorization requests");
103
104/*
105 * This tunable is here for compatibility. It will allow the user
106 * to switch between the new mode (first rule matches) and the old
107 * functionality (all rules match).
108 */
109static int
110mac_bsdextended_firstmatch_enabled;
111SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled,
112 CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1,
113 "Disable/enable match first rule functionality");
114
115static int
116mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule)
117{
118
119 if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS)
120 return (EINVAL);
121
122 if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS)
123 return (EINVAL);
124
125 if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM)
126 return (EINVAL);
127
128 return (0);
129}
130
131static int
132sysctl_rule(SYSCTL_HANDLER_ARGS)
133{
134 struct mac_bsdextended_rule temprule, *ruleptr;
135 u_int namelen;
136 int error, index, *name;
137
138 name = (int *)arg1;
139 namelen = arg2;
140
141 /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */
142
143 if (namelen != 1)
144 return (EINVAL);
145
146 index = name[0];
147 if (index < 0 || index > rule_slots + 1)
148 return (ENOENT);
149 if (rule_slots >= MAC_BSDEXTENDED_MAXRULES)
150 return (ENOENT);
151
152 if (req->oldptr) {
153 if (rules[index] == NULL)
154 return (ENOENT);
155
156 error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index]));
157 if (error)
158 return (error);
159 }
160
161 if (req->newptr) {
162 if (req->newlen == 0) {
163 /* printf("deletion\n"); */
164 ruleptr = rules[index];
165 if (ruleptr == NULL)
166 return (ENOENT);
167 rule_count--;
168 rules[index] = NULL;
169 FREE(ruleptr, M_MACBSDEXTENDED);
170 return(0);
171 }
172 error = SYSCTL_IN(req, &temprule, sizeof(temprule));
173 if (error)
174 return (error);
175
176 error = mac_bsdextended_rule_valid(&temprule);
177 if (error)
178 return (error);
179
180 if (rules[index] == NULL) {
181 /* printf("addition\n"); */
182 MALLOC(ruleptr, struct mac_bsdextended_rule *,
183 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK |
184 M_ZERO);
185 *ruleptr = temprule;
186 rules[index] = ruleptr;
187 if (index+1 > rule_slots)
188 rule_slots = index+1;
189 rule_count++;
190 } else {
191 /* printf("replacement\n"); */
192 *rules[index] = temprule;
193 }
194 }
195
196 return (0);
197}
198
199SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules,
200 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules");
201
202static void
203mac_bsdextended_init(struct mac_policy_conf *mpc)
204{
205
206 /* Initialize ruleset lock. */
207 /* Register dynamic sysctl's for rules. */
208}
209
210static void
211mac_bsdextended_destroy(struct mac_policy_conf *mpc)
212{
213
214 /* Tear down sysctls. */
215 /* Destroy ruleset lock. */
216}
217
218static int
219mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule,
220 struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode)
221{
222 int match;
223
224 /*
225 * Is there a subject match?
226 */
227 if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) {
228 match = (rule->mbr_subject.mbi_uid == cred->cr_uid ||
229 rule->mbr_subject.mbi_uid == cred->cr_ruid ||
230 rule->mbr_subject.mbi_uid == cred->cr_svuid);
231
232 if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
233 match = !match;
234
235 if (!match)
236 return (0);
237 }
238
239 if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) {
240 match = (groupmember(rule->mbr_subject.mbi_gid, cred) ||
241 rule->mbr_subject.mbi_gid == cred->cr_rgid ||
242 rule->mbr_subject.mbi_gid == cred->cr_svgid);
243
244 if (rule->mbr_subject.mbi_flags & MBI_NEGATED)
245 match = !match;
246
247 if (!match)
248 return (0);
249 }
250
251 /*
252 * Is there an object match?
253 */
254 if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) {
255 match = (rule->mbr_object.mbi_uid == object_uid);
256
257 if (rule->mbr_object.mbi_flags & MBI_NEGATED)
258 match = !match;
259
260 if (!match)
261 return (0);
262 }
263
264 if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) {
265 match = (rule->mbr_object.mbi_gid == object_gid);
266
267 if (rule->mbr_object.mbi_flags & MBI_NEGATED)
268 match = !match;
269
270 if (!match)
271 return (0);
272 }
273
274 /*
275 * Is the access permitted?
276 */
277 if ((rule->mbr_mode & acc_mode) != acc_mode) {
278 if (mac_bsdextended_logging)
279 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d"
280 " on %d:%d failed. \n", cred->cr_ruid,
281 cred->cr_rgid, acc_mode, object_uid, object_gid);
282 return (EACCES); /* Matching rule denies access */
283 }
284 /*
285 * If the rule matched and allowed access and first match is
286 * enabled, then return success.
287 */
288 if (mac_bsdextended_firstmatch_enabled)
289 return (EJUSTRETURN);
290 else
291 return(0);
292}
293
294static int
295mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid,
296 int acc_mode)
297{
298 int error, i;
299
300 if (suser_cred(cred, 0) == 0)
301 return (0);
302
303 for (i = 0; i < rule_slots; i++) {
304 if (rules[i] == NULL)
305 continue;
306
307 /*
308 * Since we don't separately handle append, map append to
309 * write.
310 */
311 if (acc_mode & MBI_APPEND) {
312 acc_mode &= ~MBI_APPEND;
313 acc_mode |= MBI_WRITE;
314 }
315
316 error = mac_bsdextended_rulecheck(rules[i], cred, object_uid,
317 object_gid, acc_mode);
318 if (error == EJUSTRETURN)
319 break;
320 if (error)
321 return (error);
322 }
323
324 return (0);
325}
326
327static int
328mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp,
329 struct label *label)
330{
331 struct vattr vap;
332 int error;
333
334 if (!mac_bsdextended_enabled)
335 return (0);
336
337 error = VOP_GETATTR(vp, &vap, cred, curthread);
338 if (error)
339 return (error);
340 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
341 MBI_WRITE));
342}
343
344static int
345mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp,
346 struct label *label, int acc_mode)
347{
348 struct vattr vap;
349 int error;
350
351 if (!mac_bsdextended_enabled)
352 return (0);
353
354 error = VOP_GETATTR(vp, &vap, cred, curthread);
355 if (error)
356 return (error);
357 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
358}
359
360static int
361mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
362 struct label *dlabel)
363{
364 struct vattr vap;
365 int error;
366
367 if (!mac_bsdextended_enabled)
368 return (0);
369
370 error = VOP_GETATTR(dvp, &vap, cred, curthread);
371 if (error)
372 return (error);
373 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
374 MBI_EXEC));
375}
376
377static int
378mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
379 struct label *dlabel)
380{
381 struct vattr vap;
382 int error;
383
384 if (!mac_bsdextended_enabled)
385 return (0);
386
387 error = VOP_GETATTR(dvp, &vap, cred, curthread);
388 if (error)
389 return (error);
390 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
391 MBI_EXEC));
392}
393
394static int
395mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp,
396 struct label *dlabel, struct componentname *cnp, struct vattr *vap)
397{
398 struct vattr dvap;
399 int error;
400
401 if (!mac_bsdextended_enabled)
402 return (0);
403
404 error = VOP_GETATTR(dvp, &dvap, cred, curthread);
405 if (error)
406 return (error);
407 return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid,
408 MBI_WRITE));
409}
410
411static int
412mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
413 struct label *dlabel, struct vnode *vp, struct label *label,
414 struct componentname *cnp)
415{
416 struct vattr vap;
417 int error;
418
419 if (!mac_bsdextended_enabled)
420 return (0);
421
422 error = VOP_GETATTR(dvp, &vap, cred, curthread);
423 if (error)
424 return (error);
425 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
426 MBI_WRITE);
427 if (error)
428 return (error);
429
430 error = VOP_GETATTR(vp, &vap, cred, curthread);
431 if (error)
432 return (error);
433 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
434 MBI_WRITE));
435}
436
437static int
438mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
439 struct label *label, acl_type_t type)
440{
441 struct vattr vap;
442 int error;
443
444 if (!mac_bsdextended_enabled)
445 return (0);
446
447 error = VOP_GETATTR(vp, &vap, cred, curthread);
448 if (error)
449 return (error);
450 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
451 MBI_ADMIN));
452}
453
454static int
455mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp,
456 struct label *label, int attrnamespace, const char *name)
457{
458 struct vattr vap;
459 int error;
460
461 if (!mac_bsdextended_enabled)
462 return (0);
463
464 error = VOP_GETATTR(vp, &vap, cred, curthread);
465 if (error)
466 return (error);
467 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
468 MBI_WRITE));
469}
470
471static int
472mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp,
473 struct label *label, struct image_params *imgp,
474 struct label *execlabel)
475{
476 struct vattr vap;
477 int error;
478
479 if (!mac_bsdextended_enabled)
480 return (0);
481
482 error = VOP_GETATTR(vp, &vap, cred, curthread);
483 if (error)
484 return (error);
485 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
486 MBI_READ|MBI_EXEC));
487}
488
489static int
490mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
491 struct label *label, acl_type_t type)
492{
493 struct vattr vap;
494 int error;
495
496 if (!mac_bsdextended_enabled)
497 return (0);
498
499 error = VOP_GETATTR(vp, &vap, cred, curthread);
500 if (error)
501 return (error);
502 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
503 MBI_STAT));
504}
505
506static int
507mac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
508 struct label *label, int attrnamespace, const char *name, struct uio *uio)
509{
510 struct vattr vap;
511 int error;
512
513 if (!mac_bsdextended_enabled)
514 return (0);
515
516 error = VOP_GETATTR(vp, &vap, cred, curthread);
517 if (error)
518 return (error);
519 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
520 MBI_READ));
521}
522
523static int
524mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp,
525 struct label *dlabel, struct vnode *vp, struct label *label,
526 struct componentname *cnp)
527{
528 struct vattr vap;
529 int error;
530
531 if (!mac_bsdextended_enabled)
532 return (0);
533
534 error = VOP_GETATTR(dvp, &vap, cred, curthread);
535 if (error)
536 return (error);
537 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
538 MBI_WRITE);
539 if (error)
540 return (error);
541
542 error = VOP_GETATTR(vp, &vap, cred, curthread);
543 if (error)
544 return (error);
545 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
546 MBI_WRITE);
547 if (error)
548 return (error);
549 return (0);
550}
551
552static int
553mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp,
554 struct label *label, int attrnamespace)
555{
556 struct vattr vap;
557 int error;
558
559 if (!mac_bsdextended_enabled)
560 return (0);
561
562 error = VOP_GETATTR(vp, &vap, cred, curthread);
563 if (error)
564 return (error);
565 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
566 MBI_READ));
567}
568
569static int
570mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
571 struct label *dlabel, struct componentname *cnp)
572{
573 struct vattr vap;
574 int error;
575
576 if (!mac_bsdextended_enabled)
577 return (0);
578
579 error = VOP_GETATTR(dvp, &vap, cred, curthread);
580 if (error)
581 return (error);
582 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
583 MBI_EXEC));
584}
585
586static int
587mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp,
588 struct label *filelabel, int acc_mode)
589{
590 struct vattr vap;
591 int error;
592
593 if (!mac_bsdextended_enabled)
594 return (0);
595
596 error = VOP_GETATTR(vp, &vap, cred, curthread);
597 if (error)
598 return (error);
599 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode));
600}
601
602static int
603mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
604 struct label *dlabel)
605{
606 struct vattr vap;
607 int error;
608
609 if (!mac_bsdextended_enabled)
610 return (0);
611
612 error = VOP_GETATTR(dvp, &vap, cred, curthread);
613 if (error)
614 return (error);
615 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
616 MBI_READ));
617}
618
619static int
620mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp,
621 struct label *label)
622{
623 struct vattr vap;
624 int error;
625
626 if (!mac_bsdextended_enabled)
627 return (0);
628
629 error = VOP_GETATTR(vp, &vap, cred, curthread);
630 if (error)
631 return (error);
632 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
633 MBI_READ));
634}
635
636static int
637mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
638 struct label *dlabel, struct vnode *vp, struct label *label,
639 struct componentname *cnp)
640{
641 struct vattr vap;
642 int error;
643
644 if (!mac_bsdextended_enabled)
645 return (0);
646
647 error = VOP_GETATTR(dvp, &vap, cred, curthread);
648 if (error)
649 return (error);
650 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
651 MBI_WRITE);
652 if (error)
653 return (error);
654 error = VOP_GETATTR(vp, &vap, cred, curthread);
655 if (error)
656 return (error);
657 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
658 MBI_WRITE);
659
660 return (error);
661}
662
663static int
664mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
665 struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
666 struct componentname *cnp)
667{
668 struct vattr vap;
669 int error;
670
671 if (!mac_bsdextended_enabled)
672 return (0);
673
674 error = VOP_GETATTR(dvp, &vap, cred, curthread);
675 if (error)
676 return (error);
677 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
678 MBI_WRITE);
679 if (error)
680 return (error);
681
682 if (vp != NULL) {
683 error = VOP_GETATTR(vp, &vap, cred, curthread);
684 if (error)
685 return (error);
686 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
687 MBI_WRITE);
688 }
689
690 return (error);
691}
692
693static int
694mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
695 struct label *label)
696{
697 struct vattr vap;
698 int error;
699
700 if (!mac_bsdextended_enabled)
701 return (0);
702
703 error = VOP_GETATTR(vp, &vap, cred, curthread);
704 if (error)
705 return (error);
706 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
707 MBI_ADMIN));
708}
709
710static int
711mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp,
712 struct label *label, acl_type_t type, struct acl *acl)
713{
714 struct vattr vap;
715 int error;
716
717 if (!mac_bsdextended_enabled)
718 return (0);
719
720 error = VOP_GETATTR(vp, &vap, cred, curthread);
721 if (error)
722 return (error);
723 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
724 MBI_ADMIN));
725}
726
727static int
728mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
729 struct label *label, int attrnamespace, const char *name, struct uio *uio)
730{
731 struct vattr vap;
732 int error;
733
734 if (!mac_bsdextended_enabled)
735 return (0);
736
737 error = VOP_GETATTR(vp, &vap, cred, curthread);
738 if (error)
739 return (error);
740 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
741 MBI_WRITE));
742}
743
744static int
745mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
746 struct label *label, u_long flags)
747{
748 struct vattr vap;
749 int error;
750
751 if (!mac_bsdextended_enabled)
752 return (0);
753
754 error = VOP_GETATTR(vp, &vap, cred, curthread);
755 if (error)
756 return (error);
757 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
758 MBI_ADMIN));
759}
760
761static int
762mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
763 struct label *label, mode_t mode)
764{
765 struct vattr vap;
766 int error;
767
768 if (!mac_bsdextended_enabled)
769 return (0);
770
771 error = VOP_GETATTR(vp, &vap, cred, curthread);
772 if (error)
773 return (error);
774 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
775 MBI_ADMIN));
776}
777
778static int
779mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
780 struct label *label, uid_t uid, gid_t gid)
781{
782 struct vattr vap;
783 int error;
784
785 if (!mac_bsdextended_enabled)
786 return (0);
787
788 error = VOP_GETATTR(vp, &vap, cred, curthread);
789 if (error)
790 return (error);
791 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
792 MBI_ADMIN));
793}
794
795static int
796mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
797 struct label *label, struct timespec atime, struct timespec utime)
798{
799 struct vattr vap;
800 int error;
801
802 if (!mac_bsdextended_enabled)
803 return (0);
804
805 error = VOP_GETATTR(vp, &vap, cred, curthread);
806 if (error)
807 return (error);
808 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid,
809 MBI_ADMIN));
810}
811
812static int
813mac_bsdextended_check_vnode_stat(struct ucred *active_cred,
814 struct ucred *file_cred, struct vnode *vp, struct label *label)
815{
816 struct vattr vap;
817 int error;
818
819 if (!mac_bsdextended_enabled)
820 return (0);
821
822 error = VOP_GETATTR(vp, &vap, active_cred, curthread);
823 if (error)
824 return (error);
825 return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid,
826 MBI_STAT));
827}
828
829static struct mac_policy_ops mac_bsdextended_ops =
830{
831 .mpo_destroy = mac_bsdextended_destroy,
832 .mpo_init = mac_bsdextended_init,
833 .mpo_check_system_swapon = mac_bsdextended_check_system_swapon,
834 .mpo_check_vnode_access = mac_bsdextended_check_vnode_access,
835 .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir,
836 .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot,
837 .mpo_check_vnode_create = mac_bsdextended_check_create_vnode,
838 .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete,
839 .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl,
840 .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr,
841 .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec,
842 .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl,
843 .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr,
844 .mpo_check_vnode_link = mac_bsdextended_check_vnode_link,
845 .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr,
846 .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup,
847 .mpo_check_vnode_open = mac_bsdextended_check_vnode_open,
848 .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir,
849 .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink,
850 .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from,
851 .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to,
852 .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke,
853 .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode,
854 .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr,
855 .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags,
856 .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode,
857 .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner,
858 .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes,
859 .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat,
860};
861
862MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended,
863 "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL);