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 tunable spits out information about what is going on which 98 * would be more suited for a log file. Eventually 99 * this will go away as we do not currently use it. 100 */ 101 static int mac_bsdextended_debugging; 102 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, debugging, CTLFLAG_RW, 103 &mac_bsdextended_debugging, 0, "Enable debugging on failure"); 104 105 /* 106 * This is just used for logging purposes as eventually we would like 107 * to log much more then failed requests. 108 */ 109 static int mac_bsdextended_logging; 110 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 111 &mac_bsdextended_logging, 0, "Log failed authorization requests"); 112 113 /* 114 * This tunable is here for compatibility. It will allow the user 115 * to switch between the new mode (first rule matches) and the old 116 * functionality (all rules match). 117 */ 118 static int 119 mac_bsdextended_firstmatch_enabled; 120 SYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 121 CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 0, 122 "Disable/enable match first rule functionality"); 123 124 static int 125 mac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 126 { 127 128 if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 129 return (EINVAL); 130 131 if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 132 return (EINVAL); 133 134 if ((rule->mbr_mode | VALLPERM) != VALLPERM) 135 return (EINVAL); 136 137 return (0); 138 } 139 140 static int 141 sysctl_rule(SYSCTL_HANDLER_ARGS) 142 { 143 struct mac_bsdextended_rule temprule, *ruleptr; 144 u_int namelen; 145 int error, index, *name; 146 147 name = (int *)arg1; 148 namelen = arg2; 149 150 /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 151 152 if (namelen != 1) 153 return (EINVAL); 154 155 index = name[0]; 156 if (index < 0 || index > rule_slots + 1) 157 return (ENOENT); 158 if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 159 return (ENOENT); 160 161 if (req->oldptr) { 162 if (rules[index] == NULL) 163 return (ENOENT); 164 165 error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); 166 if (error) 167 return (error); 168 } 169 170 if (req->newptr) { 171 if (req->newlen == 0) { 172 /* printf("deletion\n"); */ 173 ruleptr = rules[index]; 174 if (ruleptr == NULL) 175 return (ENOENT); 176 rule_count--; 177 rules[index] = NULL; 178 FREE(ruleptr, M_MACBSDEXTENDED); 179 return(0); 180 } 181 error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 182 if (error) 183 return (error); 184 185 error = mac_bsdextended_rule_valid(&temprule); 186 if (error) 187 return (error); 188 189 if (rules[index] == NULL) { 190 /* printf("addition\n"); */ 191 MALLOC(ruleptr, struct mac_bsdextended_rule *, 192 sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 193 M_ZERO); 194 *ruleptr = temprule; 195 rules[index] = ruleptr; 196 if (index+1 > rule_slots) 197 rule_slots = index+1; 198 rule_count++; 199 } else { 200 /* printf("replacement\n"); */ 201 *rules[index] = temprule; 202 } 203 } 204 205 return (0); 206 } 207 208 SYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 209 CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 210 211 static void 212 mac_bsdextended_init(struct mac_policy_conf *mpc) 213 { 214 215 /* Initialize ruleset lock. */ 216 /* Register dynamic sysctl's for rules. */ 217 } 218 219 static void 220 mac_bsdextended_destroy(struct mac_policy_conf *mpc) 221 { 222 223 /* Tear down sysctls. */ 224 /* Destroy ruleset lock. */ 225 } 226 227 static int 228 mac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 229 struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 230 { 231 int match; 232 233 /* 234 * Is there a subject match? 235 */ 236 if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 237 match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 238 rule->mbr_subject.mbi_uid == cred->cr_ruid || 239 rule->mbr_subject.mbi_uid == cred->cr_svuid); 240 241 if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 242 match = !match; 243 244 if (!match) 245 return (0); 246 } 247 248 if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 249 match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 250 rule->mbr_subject.mbi_gid == cred->cr_rgid || 251 rule->mbr_subject.mbi_gid == cred->cr_svgid); 252 253 if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 254 match = !match; 255 256 if (!match) 257 return (0); 258 } 259 260 /* 261 * Is there an object match? 262 */ 263 if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 264 match = (rule->mbr_object.mbi_uid == object_uid); 265 266 if (rule->mbr_object.mbi_flags & MBI_NEGATED) 267 match = !match; 268 269 if (!match) 270 return (0); 271 } 272 273 if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 274 match = (rule->mbr_object.mbi_gid == object_gid); 275 276 if (rule->mbr_object.mbi_flags & MBI_NEGATED) 277 match = !match; 278 279 if (!match) 280 return (0); 281 } 282 283 /* 284 * Is the access permitted? 285 */ 286 if ((rule->mbr_mode & acc_mode) != acc_mode) { 287 if (mac_bsdextended_logging) 288 log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 289 " on %d:%d failed. \n", cred->cr_ruid, 290 cred->cr_rgid, acc_mode, object_uid, object_gid); 291 return (EACCES); /* Matching rule denies access */ 292 } 293 /* 294 * If the rule matched and allowed access and first match is 295 * enabled, then return success. 296 */ 297 if (mac_bsdextended_firstmatch_enabled) 298 return (EJUSTRETURN); 299 else 300 return(0); 301 } 302 303 static int 304 mac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 305 int acc_mode) 306 { 307 int error, i; 308 309 if (suser_cred(cred, 0) == 0) 310 return (0); 311 312 for (i = 0; i < rule_slots; i++) { 313 if (rules[i] == NULL) 314 continue; 315 316 /* 317 * Since we don't separately handle append, map append to 318 * write. 319 */ 320 if (acc_mode & VAPPEND) { 321 acc_mode &= ~VAPPEND; 322 acc_mode |= VWRITE; 323 } 324 325 error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 326 object_gid, acc_mode); 327 if (error == EJUSTRETURN) 328 break; 329 if (error) 330 return (error); 331 } 332 333 return (0); 334 } 335 336 static int 337 mac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 338 struct label *label) 339 { 340 struct vattr vap; 341 int error; 342 343 if (!mac_bsdextended_enabled) 344 return (0); 345 346 error = VOP_GETATTR(vp, &vap, cred, curthread); 347 if (error) 348 return (error); 349 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 350 } 351 352 static int 353 mac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 354 struct label *label, int acc_mode) 355 { 356 struct vattr vap; 357 int error; 358 359 if (!mac_bsdextended_enabled) 360 return (0); 361 362 error = VOP_GETATTR(vp, &vap, cred, curthread); 363 if (error) 364 return (error); 365 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 366 } 367 368 static int 369 mac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 370 struct label *dlabel) 371 { 372 struct vattr vap; 373 int error; 374 375 if (!mac_bsdextended_enabled) 376 return (0); 377 378 error = VOP_GETATTR(dvp, &vap, cred, curthread); 379 if (error) 380 return (error); 381 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 382 } 383 384 static int 385 mac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 386 struct label *dlabel) 387 { 388 struct vattr vap; 389 int error; 390 391 if (!mac_bsdextended_enabled) 392 return (0); 393 394 error = VOP_GETATTR(dvp, &vap, cred, curthread); 395 if (error) 396 return (error); 397 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 398 } 399 400 static int 401 mac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 402 struct label *dlabel, struct componentname *cnp, struct vattr *vap) 403 { 404 struct vattr dvap; 405 int error; 406 407 if (!mac_bsdextended_enabled) 408 return (0); 409 410 error = VOP_GETATTR(dvp, &dvap, cred, curthread); 411 if (error) 412 return (error); 413 return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE)); 414 } 415 416 static int 417 mac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 418 struct label *dlabel, struct vnode *vp, struct label *label, 419 struct componentname *cnp) 420 { 421 struct vattr vap; 422 int error; 423 424 if (!mac_bsdextended_enabled) 425 return (0); 426 427 error = VOP_GETATTR(dvp, &vap, cred, curthread); 428 if (error) 429 return (error); 430 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 431 if (error) 432 return (error); 433 434 error = VOP_GETATTR(vp, &vap, cred, curthread); 435 if (error) 436 return (error); 437 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 438 } 439 440 static int 441 mac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 442 struct label *label, acl_type_t type) 443 { 444 struct vattr vap; 445 int error; 446 447 if (!mac_bsdextended_enabled) 448 return (0); 449 450 error = VOP_GETATTR(vp, &vap, cred, curthread); 451 if (error) 452 return (error); 453 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 454 } 455 456 static int 457 mac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 458 struct label *label, int attrnamespace, const char *name) 459 { 460 struct vattr vap; 461 int error; 462 463 if (!mac_bsdextended_enabled) 464 return (0); 465 466 error = VOP_GETATTR(vp, &vap, cred, curthread); 467 if (error) 468 return (error); 469 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 470 } 471 472 static int 473 mac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 474 struct label *label, struct image_params *imgp, 475 struct label *execlabel) 476 { 477 struct vattr vap; 478 int error; 479 480 if (!mac_bsdextended_enabled) 481 return (0); 482 483 error = VOP_GETATTR(vp, &vap, cred, curthread); 484 if (error) 485 return (error); 486 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 487 VREAD|VEXEC)); 488 } 489 490 static int 491 mac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 492 struct label *label, acl_type_t type) 493 { 494 struct vattr vap; 495 int error; 496 497 if (!mac_bsdextended_enabled) 498 return (0); 499 500 error = VOP_GETATTR(vp, &vap, cred, curthread); 501 if (error) 502 return (error); 503 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT)); 504 } 505 506 static int 507 mac_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, VREAD)); 520 } 521 522 static int 523 mac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 524 struct label *dlabel, struct vnode *vp, struct label *label, 525 struct componentname *cnp) 526 { 527 struct vattr vap; 528 int error; 529 530 if (!mac_bsdextended_enabled) 531 return (0); 532 533 error = VOP_GETATTR(dvp, &vap, cred, curthread); 534 if (error) 535 return (error); 536 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 537 if (error) 538 return (error); 539 540 error = VOP_GETATTR(vp, &vap, cred, curthread); 541 if (error) 542 return (error); 543 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 544 if (error) 545 return (error); 546 return (0); 547 } 548 549 static int 550 mac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 551 struct label *label, int attrnamespace) 552 { 553 struct vattr vap; 554 int error; 555 556 if (!mac_bsdextended_enabled) 557 return (0); 558 559 error = VOP_GETATTR(vp, &vap, cred, curthread); 560 if (error) 561 return (error); 562 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 563 } 564 565 static int 566 mac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 567 struct label *dlabel, struct componentname *cnp) 568 { 569 struct vattr vap; 570 int error; 571 572 if (!mac_bsdextended_enabled) 573 return (0); 574 575 error = VOP_GETATTR(dvp, &vap, cred, curthread); 576 if (error) 577 return (error); 578 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 579 } 580 581 static int 582 mac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 583 struct label *filelabel, int acc_mode) 584 { 585 struct vattr vap; 586 int error; 587 588 if (!mac_bsdextended_enabled) 589 return (0); 590 591 error = VOP_GETATTR(vp, &vap, cred, curthread); 592 if (error) 593 return (error); 594 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 595 } 596 597 static int 598 mac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 599 struct label *dlabel) 600 { 601 struct vattr vap; 602 int error; 603 604 if (!mac_bsdextended_enabled) 605 return (0); 606 607 error = VOP_GETATTR(dvp, &vap, cred, curthread); 608 if (error) 609 return (error); 610 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 611 } 612 613 static int 614 mac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 615 struct label *label) 616 { 617 struct vattr vap; 618 int error; 619 620 if (!mac_bsdextended_enabled) 621 return (0); 622 623 error = VOP_GETATTR(vp, &vap, cred, curthread); 624 if (error) 625 return (error); 626 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 627 } 628 629 static int 630 mac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 631 struct label *dlabel, struct vnode *vp, struct label *label, 632 struct componentname *cnp) 633 { 634 struct vattr vap; 635 int error; 636 637 if (!mac_bsdextended_enabled) 638 return (0); 639 640 error = VOP_GETATTR(dvp, &vap, cred, curthread); 641 if (error) 642 return (error); 643 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 644 if (error) 645 return (error); 646 error = VOP_GETATTR(vp, &vap, cred, curthread); 647 if (error) 648 return (error); 649 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 650 651 return (error); 652 } 653 654 static int 655 mac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 656 struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 657 struct componentname *cnp) 658 { 659 struct vattr vap; 660 int error; 661 662 if (!mac_bsdextended_enabled) 663 return (0); 664 665 error = VOP_GETATTR(dvp, &vap, cred, curthread); 666 if (error) 667 return (error); 668 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 669 if (error) 670 return (error); 671 672 if (vp != NULL) { 673 error = VOP_GETATTR(vp, &vap, cred, curthread); 674 if (error) 675 return (error); 676 error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 677 VWRITE); 678 } 679 680 return (error); 681 } 682 683 static int 684 mac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 685 struct label *label) 686 { 687 struct vattr vap; 688 int error; 689 690 if (!mac_bsdextended_enabled) 691 return (0); 692 693 error = VOP_GETATTR(vp, &vap, cred, curthread); 694 if (error) 695 return (error); 696 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 697 } 698 699 static int 700 mac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 701 struct label *label, acl_type_t type, struct acl *acl) 702 { 703 struct vattr vap; 704 int error; 705 706 if (!mac_bsdextended_enabled) 707 return (0); 708 709 error = VOP_GETATTR(vp, &vap, cred, curthread); 710 if (error) 711 return (error); 712 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 713 } 714 715 static int 716 mac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 717 struct label *label, int attrnamespace, const char *name, struct uio *uio) 718 { 719 struct vattr vap; 720 int error; 721 722 if (!mac_bsdextended_enabled) 723 return (0); 724 725 error = VOP_GETATTR(vp, &vap, cred, curthread); 726 if (error) 727 return (error); 728 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 729 } 730 731 static int 732 mac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 733 struct label *label, u_long flags) 734 { 735 struct vattr vap; 736 int error; 737 738 if (!mac_bsdextended_enabled) 739 return (0); 740 741 error = VOP_GETATTR(vp, &vap, cred, curthread); 742 if (error) 743 return (error); 744 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 745 } 746 747 static int 748 mac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 749 struct label *label, mode_t mode) 750 { 751 struct vattr vap; 752 int error; 753 754 if (!mac_bsdextended_enabled) 755 return (0); 756 757 error = VOP_GETATTR(vp, &vap, cred, curthread); 758 if (error) 759 return (error); 760 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 761 } 762 763 static int 764 mac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 765 struct label *label, uid_t uid, gid_t gid) 766 { 767 struct vattr vap; 768 int error; 769 770 if (!mac_bsdextended_enabled) 771 return (0); 772 773 error = VOP_GETATTR(vp, &vap, cred, curthread); 774 if (error) 775 return (error); 776 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 777 } 778 779 static int 780 mac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 781 struct label *label, struct timespec atime, struct timespec utime) 782 { 783 struct vattr vap; 784 int error; 785 786 if (!mac_bsdextended_enabled) 787 return (0); 788 789 error = VOP_GETATTR(vp, &vap, cred, curthread); 790 if (error) 791 return (error); 792 return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 793 } 794 795 static int 796 mac_bsdextended_check_vnode_stat(struct ucred *active_cred, 797 struct ucred *file_cred, struct vnode *vp, struct label *label) 798 { 799 struct vattr vap; 800 int error; 801 802 if (!mac_bsdextended_enabled) 803 return (0); 804 805 error = VOP_GETATTR(vp, &vap, active_cred, curthread); 806 if (error) 807 return (error); 808 return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 809 VSTAT)); 810 } 811 812 static struct mac_policy_ops mac_bsdextended_ops = 813 { 814 .mpo_destroy = mac_bsdextended_destroy, 815 .mpo_init = mac_bsdextended_init, 816 .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 817 .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 818 .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 819 .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 820 .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 821 .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 822 .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 823 .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 824 .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 825 .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 826 .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 827 .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 828 .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 829 .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 830 .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 831 .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 832 .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 833 .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 834 .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 835 .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 836 .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 837 .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 838 .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 839 .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 840 .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 841 .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 842 .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 843 }; 844 845 MAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 846 "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 847