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