ugidfw_system.c revision 136742
1/*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 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 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); 864