1 /*- 2 * Copyright (c) 1999-2002 Robert N. M. Watson 3 * Copyright (c) 2001-2003 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$ 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 74 SYSCTL_DECL(_security_mac); 75 76 SYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 77 "TrustedBSD extended BSD MAC policy controls"); 78 79 static int mac_bsdextended_enabled = 1; 80 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 81 &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 82 TUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 83 84 MALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 85 86 #define MAC_BSDEXTENDED_MAXRULES 250 87 static struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 88 static int rule_count = 0; 89 static int rule_slots = 0; 90 91 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 92 &rule_count, 0, "Number of defined rules\n"); 93 SYSCTL_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 */ 100 static int mac_bsdextended_logging; 101 SYSCTL_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 */ 109 static int 110 mac_bsdextended_firstmatch_enabled; 111 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 112 CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 113 "Disable/enable match first rule functionality"); 114 115 static int 116 mac_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 | VALLPERM) != VALLPERM) 126 return (EINVAL); 127 128 return (0); 129 } 130 131 static int 132 sysctl_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 199 SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 200 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 201 202 static void 203 mac_bsdextended_init(struct mac_policy_conf *mpc) 204 { 205 206 /* Initialize ruleset lock. */ 207 /* Register dynamic sysctl's for rules. */ 208 } 209 210 static void 211 mac_bsdextended_destroy(struct mac_policy_conf *mpc) 212 { 213 214 /* Tear down sysctls. */ 215 /* Destroy ruleset lock. */ 216 } 217 218 static int 219 mac_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 294 static int 295 mac_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 & VAPPEND) { 312 acc_mode &= ~VAPPEND; 313 acc_mode |= VWRITE; 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 327 static int 328 mac_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, VWRITE)); 341 } 342 343 static int 344 mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 345 struct label *label, int acc_mode) 346 { 347 struct vattr vap; 348 int error; 349 350 if (!mac_bsdextended_enabled) 351 return (0); 352 353 error = VOP_GETATTR(vp, &vap, cred, curthread); 354 if (error) 355 return (error); 356 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 357 } 358 359 static int 360 mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 361 struct label *dlabel) 362 { 363 struct vattr vap; 364 int error; 365 366 if (!mac_bsdextended_enabled) 367 return (0); 368 369 error = VOP_GETATTR(dvp, &vap, cred, curthread); 370 if (error) 371 return (error); 372 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 373 } 374 375 static int 376 mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 377 struct label *dlabel) 378 { 379 struct vattr vap; 380 int error; 381 382 if (!mac_bsdextended_enabled) 383 return (0); 384 385 error = VOP_GETATTR(dvp, &vap, cred, curthread); 386 if (error) 387 return (error); 388 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 389 } 390 391 static int 392 mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 393 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 394 { 395 struct vattr dvap; 396 int error; 397 398 if (!mac_bsdextended_enabled) 399 return (0); 400 401 error = VOP_GETATTR(dvp, &dvap, cred, curthread); 402 if (error) 403 return (error); 404 return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE)); 405 } 406 407 static int 408 mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 409 struct label *dlabel, struct vnode *vp, struct label *label, 410 struct componentname *cnp) 411 { 412 struct vattr vap; 413 int error; 414 415 if (!mac_bsdextended_enabled) 416 return (0); 417 418 error = VOP_GETATTR(dvp, &vap, cred, curthread); 419 if (error) 420 return (error); 421 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 422 if (error) 423 return (error); 424 425 error = VOP_GETATTR(vp, &vap, cred, curthread); 426 if (error) 427 return (error); 428 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 429 } 430 431 static int 432 mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 433 struct label *label, acl_type_t type) 434 { 435 struct vattr vap; 436 int error; 437 438 if (!mac_bsdextended_enabled) 439 return (0); 440 441 error = VOP_GETATTR(vp, &vap, cred, curthread); 442 if (error) 443 return (error); 444 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 445 } 446 447 static int 448 mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 449 struct label *label, int attrnamespace, const char *name) 450 { 451 struct vattr vap; 452 int error; 453 454 if (!mac_bsdextended_enabled) 455 return (0); 456 457 error = VOP_GETATTR(vp, &vap, cred, curthread); 458 if (error) 459 return (error); 460 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 461 } 462 463 static int 464 mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 465 struct label *label, struct image_params *imgp, 466 struct label *execlabel) 467 { 468 struct vattr vap; 469 int error; 470 471 if (!mac_bsdextended_enabled) 472 return (0); 473 474 error = VOP_GETATTR(vp, &vap, cred, curthread); 475 if (error) 476 return (error); 477 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 478 VREAD|VEXEC)); 479 } 480 481 static int 482 mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 483 struct label *label, acl_type_t type) 484 { 485 struct vattr vap; 486 int error; 487 488 if (!mac_bsdextended_enabled) 489 return (0); 490 491 error = VOP_GETATTR(vp, &vap, cred, curthread); 492 if (error) 493 return (error); 494 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT)); 495 } 496 497 static int 498 mac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 499 struct label *label, int attrnamespace, const char *name, struct uio *uio) 500 { 501 struct vattr vap; 502 int error; 503 504 if (!mac_bsdextended_enabled) 505 return (0); 506 507 error = VOP_GETATTR(vp, &vap, cred, curthread); 508 if (error) 509 return (error); 510 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 511 } 512 513 static int 514 mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 515 struct label *dlabel, struct vnode *vp, struct label *label, 516 struct componentname *cnp) 517 { 518 struct vattr vap; 519 int error; 520 521 if (!mac_bsdextended_enabled) 522 return (0); 523 524 error = VOP_GETATTR(dvp, &vap, cred, curthread); 525 if (error) 526 return (error); 527 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 528 if (error) 529 return (error); 530 531 error = VOP_GETATTR(vp, &vap, cred, curthread); 532 if (error) 533 return (error); 534 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 535 if (error) 536 return (error); 537 return (0); 538 } 539 540 static int 541 mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 542 struct label *label, int attrnamespace) 543 { 544 struct vattr vap; 545 int error; 546 547 if (!mac_bsdextended_enabled) 548 return (0); 549 550 error = VOP_GETATTR(vp, &vap, cred, curthread); 551 if (error) 552 return (error); 553 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 554 } 555 556 static int 557 mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 558 struct label *dlabel, struct componentname *cnp) 559 { 560 struct vattr vap; 561 int error; 562 563 if (!mac_bsdextended_enabled) 564 return (0); 565 566 error = VOP_GETATTR(dvp, &vap, cred, curthread); 567 if (error) 568 return (error); 569 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 570 } 571 572 static int 573 mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 574 struct label *filelabel, int acc_mode) 575 { 576 struct vattr vap; 577 int error; 578 579 if (!mac_bsdextended_enabled) 580 return (0); 581 582 error = VOP_GETATTR(vp, &vap, cred, curthread); 583 if (error) 584 return (error); 585 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 586 } 587 588 static int 589 mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 590 struct label *dlabel) 591 { 592 struct vattr vap; 593 int error; 594 595 if (!mac_bsdextended_enabled) 596 return (0); 597 598 error = VOP_GETATTR(dvp, &vap, cred, curthread); 599 if (error) 600 return (error); 601 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 602 } 603 604 static int 605 mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 606 struct label *label) 607 { 608 struct vattr vap; 609 int error; 610 611 if (!mac_bsdextended_enabled) 612 return (0); 613 614 error = VOP_GETATTR(vp, &vap, cred, curthread); 615 if (error) 616 return (error); 617 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 618 } 619 620 static int 621 mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 622 struct label *dlabel, struct vnode *vp, struct label *label, 623 struct componentname *cnp) 624 { 625 struct vattr vap; 626 int error; 627 628 if (!mac_bsdextended_enabled) 629 return (0); 630 631 error = VOP_GETATTR(dvp, &vap, cred, curthread); 632 if (error) 633 return (error); 634 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 635 if (error) 636 return (error); 637 error = VOP_GETATTR(vp, &vap, cred, curthread); 638 if (error) 639 return (error); 640 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 641 642 return (error); 643 } 644 645 static int 646 mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 647 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 648 struct componentname *cnp) 649 { 650 struct vattr vap; 651 int error; 652 653 if (!mac_bsdextended_enabled) 654 return (0); 655 656 error = VOP_GETATTR(dvp, &vap, cred, curthread); 657 if (error) 658 return (error); 659 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 660 if (error) 661 return (error); 662 663 if (vp != NULL) { 664 error = VOP_GETATTR(vp, &vap, cred, curthread); 665 if (error) 666 return (error); 667 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 668 VWRITE); 669 } 670 671 return (error); 672 } 673 674 static int 675 mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 676 struct label *label) 677 { 678 struct vattr vap; 679 int error; 680 681 if (!mac_bsdextended_enabled) 682 return (0); 683 684 error = VOP_GETATTR(vp, &vap, cred, curthread); 685 if (error) 686 return (error); 687 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 688 } 689 690 static int 691 mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 692 struct label *label, acl_type_t type, struct acl *acl) 693 { 694 struct vattr vap; 695 int error; 696 697 if (!mac_bsdextended_enabled) 698 return (0); 699 700 error = VOP_GETATTR(vp, &vap, cred, curthread); 701 if (error) 702 return (error); 703 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 704 } 705 706 static int 707 mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 708 struct label *label, int attrnamespace, const char *name, struct uio *uio) 709 { 710 struct vattr vap; 711 int error; 712 713 if (!mac_bsdextended_enabled) 714 return (0); 715 716 error = VOP_GETATTR(vp, &vap, cred, curthread); 717 if (error) 718 return (error); 719 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 720 } 721 722 static int 723 mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 724 struct label *label, u_long flags) 725 { 726 struct vattr vap; 727 int error; 728 729 if (!mac_bsdextended_enabled) 730 return (0); 731 732 error = VOP_GETATTR(vp, &vap, cred, curthread); 733 if (error) 734 return (error); 735 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 736 } 737 738 static int 739 mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 740 struct label *label, mode_t mode) 741 { 742 struct vattr vap; 743 int error; 744 745 if (!mac_bsdextended_enabled) 746 return (0); 747 748 error = VOP_GETATTR(vp, &vap, cred, curthread); 749 if (error) 750 return (error); 751 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 752 } 753 754 static int 755 mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 756 struct label *label, uid_t uid, gid_t gid) 757 { 758 struct vattr vap; 759 int error; 760 761 if (!mac_bsdextended_enabled) 762 return (0); 763 764 error = VOP_GETATTR(vp, &vap, cred, curthread); 765 if (error) 766 return (error); 767 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 768 } 769 770 static int 771 mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 772 struct label *label, struct timespec atime, struct timespec utime) 773 { 774 struct vattr vap; 775 int error; 776 777 if (!mac_bsdextended_enabled) 778 return (0); 779 780 error = VOP_GETATTR(vp, &vap, cred, curthread); 781 if (error) 782 return (error); 783 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 784 } 785 786 static int 787 mac_bsdextended_check_vnode_stat(struct ucred *active_cred, 788 struct ucred *file_cred, struct vnode *vp, struct label *label) 789 { 790 struct vattr vap; 791 int error; 792 793 if (!mac_bsdextended_enabled) 794 return (0); 795 796 error = VOP_GETATTR(vp, &vap, active_cred, curthread); 797 if (error) 798 return (error); 799 return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 800 VSTAT)); 801 } 802 803 static struct mac_policy_ops mac_bsdextended_ops = 804 { 805 .mpo_destroy = mac_bsdextended_destroy, 806 .mpo_init = mac_bsdextended_init, 807 .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 808 .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 809 .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 810 .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 811 .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 812 .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 813 .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 814 .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 815 .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 816 .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 817 .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 818 .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 819 .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 820 .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 821 .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 822 .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 823 .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 824 .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 825 .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 826 .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 827 .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 828 .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 829 .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 830 .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 831 .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 832 .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 833 .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 834 }; 835 836 MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 837 "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 838