ugidfw_vnode.c revision 126097
1101099Srwatson/*- 2126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson 3126097Srwatson * Copyright (c) 2001-2003 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8106393Srwatson * This software was developed for the FreeBSD Project in part by Network 9106393Srwatson * Associates Laboratories, the Security Research Division of Network 10106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 11106393Srwatson * as part of the DARPA CHATS research program. 12101099Srwatson * 13101099Srwatson * Redistribution and use in source and binary forms, with or without 14101099Srwatson * modification, are permitted provided that the following conditions 15101099Srwatson * are met: 16101099Srwatson * 1. Redistributions of source code must retain the above copyright 17101099Srwatson * notice, this list of conditions and the following disclaimer. 18101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer in the 20101099Srwatson * documentation and/or other materials provided with the distribution. 21101099Srwatson * 22101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32101099Srwatson * SUCH DAMAGE. 33101099Srwatson * 34101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 126097 2004-02-22 00:33:12Z rwatson $ 35101099Srwatson */ 36101099Srwatson/* 37101099Srwatson * Developed by the TrustedBSD Project. 38101099Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose 39101099Srwatson * mandatory rules regarding users and some system objects. 40101099Srwatson * 41101099Srwatson * XXX: Much locking support required here. 42101099Srwatson */ 43101099Srwatson 44101099Srwatson#include <sys/types.h> 45101099Srwatson#include <sys/param.h> 46101099Srwatson#include <sys/acl.h> 47101099Srwatson#include <sys/conf.h> 48101099Srwatson#include <sys/kernel.h> 49101099Srwatson#include <sys/mac.h> 50101099Srwatson#include <sys/malloc.h> 51101099Srwatson#include <sys/mount.h> 52101099Srwatson#include <sys/proc.h> 53101099Srwatson#include <sys/systm.h> 54101099Srwatson#include <sys/sysproto.h> 55101099Srwatson#include <sys/sysent.h> 56101099Srwatson#include <sys/vnode.h> 57101099Srwatson#include <sys/file.h> 58101099Srwatson#include <sys/socket.h> 59101099Srwatson#include <sys/socketvar.h> 60101099Srwatson#include <sys/sysctl.h> 61101099Srwatson 62101099Srwatson#include <net/bpfdesc.h> 63101099Srwatson#include <net/if.h> 64101099Srwatson#include <net/if_types.h> 65101099Srwatson#include <net/if_var.h> 66101099Srwatson 67101099Srwatson#include <vm/vm.h> 68101099Srwatson 69101099Srwatson#include <sys/mac_policy.h> 70101099Srwatson 71101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 72101099Srwatson 73101099SrwatsonSYSCTL_DECL(_security_mac); 74101099Srwatson 75101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 76101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 77101099Srwatson 78101099Srwatsonstatic int mac_bsdextended_enabled = 1; 79101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 80101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 81101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 82101099Srwatson 83101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 84101099Srwatson 85101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 86101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 87101099Srwatsonstatic int rule_count = 0; 88101099Srwatsonstatic int rule_slots = 0; 89101099Srwatson 90101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 91101099Srwatson &rule_count, 0, "Number of defined rules\n"); 92101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 93101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 94101099Srwatson 95101099Srwatsonstatic int mac_bsdextended_debugging; 96101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, debugging, CTLFLAG_RW, 97101099Srwatson &mac_bsdextended_debugging, 0, "Enable debugging on failure"); 98101099Srwatson 99101099Srwatsonstatic int 100101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 101101099Srwatson{ 102101099Srwatson 103101099Srwatson if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 104101099Srwatson return (EINVAL); 105101099Srwatson 106101099Srwatson if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 107101099Srwatson return (EINVAL); 108101099Srwatson 109101099Srwatson if ((rule->mbr_mode | VALLPERM) != VALLPERM) 110101099Srwatson return (EINVAL); 111101099Srwatson 112101099Srwatson return (0); 113101099Srwatson} 114101099Srwatson 115101099Srwatsonstatic int 116101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 117101099Srwatson{ 118101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 119101099Srwatson u_int namelen; 120101099Srwatson int error, index, *name; 121101099Srwatson 122101099Srwatson name = (int *)arg1; 123101099Srwatson namelen = arg2; 124101099Srwatson 125101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 126101099Srwatson 127101099Srwatson if (namelen != 1) 128101099Srwatson return (EINVAL); 129101099Srwatson 130101099Srwatson index = name[0]; 131101099Srwatson if (index < 0 || index > rule_slots + 1) 132101099Srwatson return (ENOENT); 133101099Srwatson if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 134101099Srwatson return (ENOENT); 135101099Srwatson 136101099Srwatson if (req->oldptr) { 137101099Srwatson if (rules[index] == NULL) 138101099Srwatson return (ENOENT); 139101099Srwatson 140101099Srwatson error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); 141101099Srwatson if (error) 142101099Srwatson return (error); 143101099Srwatson } 144101099Srwatson 145101099Srwatson if (req->newptr) { 146101099Srwatson if (req->newlen == 0) { 147101099Srwatson /* printf("deletion\n"); */ 148101099Srwatson ruleptr = rules[index]; 149101099Srwatson if (ruleptr == NULL) 150101099Srwatson return (ENOENT); 151101099Srwatson rule_count--; 152101099Srwatson rules[index] = NULL; 153101099Srwatson FREE(ruleptr, M_MACBSDEXTENDED); 154101099Srwatson return(0); 155101099Srwatson } 156101099Srwatson error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 157101099Srwatson if (error) 158101099Srwatson return (error); 159101099Srwatson 160101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 161101099Srwatson if (error) 162101099Srwatson return (error); 163101099Srwatson 164101099Srwatson if (rules[index] == NULL) { 165101099Srwatson /* printf("addition\n"); */ 166101099Srwatson MALLOC(ruleptr, struct mac_bsdextended_rule *, 167111119Simp sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 168101099Srwatson M_ZERO); 169101099Srwatson *ruleptr = temprule; 170101099Srwatson rules[index] = ruleptr; 171101099Srwatson if (index+1 > rule_slots) 172101099Srwatson rule_slots = index+1; 173101099Srwatson rule_count++; 174101099Srwatson } else { 175101099Srwatson /* printf("replacement\n"); */ 176101099Srwatson *rules[index] = temprule; 177101099Srwatson } 178101099Srwatson } 179101099Srwatson 180101099Srwatson return (0); 181101099Srwatson} 182101099Srwatson 183101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 184101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 185101099Srwatson 186101099Srwatsonstatic void 187101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 188101099Srwatson{ 189101099Srwatson 190101099Srwatson /* Initialize ruleset lock. */ 191101099Srwatson /* Register dynamic sysctl's for rules. */ 192101099Srwatson} 193101099Srwatson 194101099Srwatsonstatic void 195101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 196101099Srwatson{ 197101099Srwatson 198101099Srwatson /* Tear down sysctls. */ 199101099Srwatson /* Destroy ruleset lock. */ 200101099Srwatson} 201101099Srwatson 202101099Srwatsonstatic int 203101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 204106212Srwatson struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 205101099Srwatson{ 206101099Srwatson int match; 207101099Srwatson 208101099Srwatson /* 209101099Srwatson * Is there a subject match? 210101099Srwatson */ 211101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 212101099Srwatson match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 213101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_ruid || 214101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_svuid); 215101099Srwatson 216101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 217101099Srwatson match = !match; 218101099Srwatson 219101099Srwatson if (!match) 220101099Srwatson return (0); 221101099Srwatson } 222101099Srwatson 223101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 224101099Srwatson match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 225101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_rgid || 226101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_svgid); 227101099Srwatson 228101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 229101099Srwatson match = !match; 230101099Srwatson 231101099Srwatson if (!match) 232101099Srwatson return (0); 233101099Srwatson } 234101099Srwatson 235101099Srwatson /* 236101099Srwatson * Is there an object match? 237101099Srwatson */ 238101099Srwatson if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 239101099Srwatson match = (rule->mbr_object.mbi_uid == object_uid); 240101099Srwatson 241101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 242101099Srwatson match = !match; 243101099Srwatson 244101099Srwatson if (!match) 245101099Srwatson return (0); 246101099Srwatson } 247101099Srwatson 248101099Srwatson if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 249101099Srwatson match = (rule->mbr_object.mbi_gid == object_gid); 250101099Srwatson 251101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 252101099Srwatson match = !match; 253101099Srwatson 254101099Srwatson if (!match) 255101099Srwatson return (0); 256101099Srwatson } 257101099Srwatson 258101099Srwatson /* 259101099Srwatson * Is the access permitted? 260101099Srwatson */ 261101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 262101099Srwatson if (mac_bsdextended_debugging) 263101099Srwatson printf("mac_bsdextended: %d:%d request %d on %d:%d" 264101099Srwatson " fails\n", cred->cr_ruid, cred->cr_rgid, 265101099Srwatson acc_mode, object_uid, object_gid); 266101099Srwatson return (EACCES); 267101099Srwatson } 268101099Srwatson 269101099Srwatson return (0); 270101099Srwatson} 271101099Srwatson 272101099Srwatsonstatic int 273101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 274106212Srwatson int acc_mode) 275101099Srwatson{ 276101099Srwatson int error, i; 277101099Srwatson 278101099Srwatson for (i = 0; i < rule_slots; i++) { 279101099Srwatson if (rules[i] == NULL) 280101099Srwatson continue; 281101099Srwatson 282108376Srwatson /* 283108376Srwatson * Since we don't separately handle append, map append to 284108376Srwatson * write. 285108376Srwatson */ 286108376Srwatson if (acc_mode & VAPPEND) { 287108376Srwatson acc_mode &= ~VAPPEND; 288108376Srwatson acc_mode |= VWRITE; 289108376Srwatson } 290108376Srwatson 291101099Srwatson error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 292101099Srwatson object_gid, acc_mode); 293101099Srwatson if (error) 294101099Srwatson return (error); 295101099Srwatson } 296101099Srwatson 297101099Srwatson return (0); 298101099Srwatson} 299101099Srwatson 300101099Srwatsonstatic int 301112575Srwatsonmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 302112575Srwatson struct label *label) 303112575Srwatson{ 304112575Srwatson struct vattr vap; 305112575Srwatson int error; 306112575Srwatson 307112575Srwatson if (!mac_bsdextended_enabled) 308112575Srwatson return (0); 309112575Srwatson 310112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 311112575Srwatson if (error) 312112575Srwatson return (error); 313112575Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 314112575Srwatson} 315112575Srwatson 316112575Srwatsonstatic int 317101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 318106212Srwatson struct label *label, int acc_mode) 319101099Srwatson{ 320101099Srwatson struct vattr vap; 321101099Srwatson int error; 322101099Srwatson 323101099Srwatson if (!mac_bsdextended_enabled) 324101099Srwatson return (0); 325101099Srwatson 326101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 327101099Srwatson if (error) 328101099Srwatson return (error); 329106212Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 330101099Srwatson} 331101099Srwatson 332101099Srwatsonstatic int 333101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 334101099Srwatson struct label *dlabel) 335101099Srwatson{ 336101099Srwatson struct vattr vap; 337101099Srwatson int error; 338101099Srwatson 339101099Srwatson if (!mac_bsdextended_enabled) 340101099Srwatson return (0); 341101099Srwatson 342101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 343101099Srwatson if (error) 344101099Srwatson return (error); 345101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 346101099Srwatson} 347101099Srwatson 348101099Srwatsonstatic int 349101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 350101099Srwatson struct label *dlabel) 351101099Srwatson{ 352101099Srwatson struct vattr vap; 353101099Srwatson int error; 354101099Srwatson 355101099Srwatson if (!mac_bsdextended_enabled) 356101099Srwatson return (0); 357101099Srwatson 358101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 359101099Srwatson if (error) 360101099Srwatson return (error); 361101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 362101099Srwatson} 363101099Srwatson 364101099Srwatsonstatic int 365101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 366101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 367101099Srwatson{ 368101099Srwatson struct vattr dvap; 369101099Srwatson int error; 370101099Srwatson 371101099Srwatson if (!mac_bsdextended_enabled) 372101099Srwatson return (0); 373101099Srwatson 374101099Srwatson error = VOP_GETATTR(dvp, &dvap, cred, curthread); 375101099Srwatson if (error) 376101099Srwatson return (error); 377101099Srwatson return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE)); 378101099Srwatson} 379101099Srwatson 380101099Srwatsonstatic int 381101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 382101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 383101099Srwatson struct componentname *cnp) 384101099Srwatson{ 385101099Srwatson struct vattr vap; 386101099Srwatson int error; 387101099Srwatson 388101099Srwatson if (!mac_bsdextended_enabled) 389101099Srwatson return (0); 390101099Srwatson 391101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 392101099Srwatson if (error) 393101099Srwatson return (error); 394101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 395101099Srwatson if (error) 396101099Srwatson return (error); 397101099Srwatson 398101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 399101099Srwatson if (error) 400101099Srwatson return (error); 401101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 402101099Srwatson} 403101099Srwatson 404101099Srwatsonstatic int 405101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 406101099Srwatson struct label *label, acl_type_t type) 407101099Srwatson{ 408101099Srwatson struct vattr vap; 409101099Srwatson int error; 410101099Srwatson 411101099Srwatson if (!mac_bsdextended_enabled) 412101099Srwatson return (0); 413101099Srwatson 414101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 415117247Srwatson if (error) 416101099Srwatson return (error); 417101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 418101099Srwatson} 419101099Srwatson 420101099Srwatsonstatic int 421119202Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 422119202Srwatson struct label *label, int attrnamespace, const char *name) 423119202Srwatson{ 424119202Srwatson struct vattr vap; 425119202Srwatson int error; 426119202Srwatson 427119202Srwatson if (!mac_bsdextended_enabled) 428119202Srwatson return (0); 429119202Srwatson 430119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 431119202Srwatson if (error) 432119202Srwatson return (error); 433119202Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 434119202Srwatson} 435119202Srwatson 436119202Srwatsonstatic int 437101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 438106648Srwatson struct label *label, struct image_params *imgp, 439106648Srwatson struct label *execlabel) 440101099Srwatson{ 441101099Srwatson struct vattr vap; 442101099Srwatson int error; 443101099Srwatson 444101099Srwatson if (!mac_bsdextended_enabled) 445101099Srwatson return (0); 446101099Srwatson 447101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 448101099Srwatson if (error) 449101099Srwatson return (error); 450101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 451101099Srwatson VREAD|VEXEC)); 452101099Srwatson} 453101099Srwatson 454101099Srwatsonstatic int 455101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 456101099Srwatson struct label *label, acl_type_t type) 457101099Srwatson{ 458101099Srwatson struct vattr vap; 459101099Srwatson int error; 460101099Srwatson 461101099Srwatson if (!mac_bsdextended_enabled) 462101099Srwatson return (0); 463101099Srwatson 464101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 465101099Srwatson if (error) 466101099Srwatson return (error); 467101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT)); 468101099Srwatson} 469101099Srwatson 470101099Srwatsonstatic int 471101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 472101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 473101099Srwatson{ 474101099Srwatson struct vattr vap; 475101099Srwatson int error; 476101099Srwatson 477101099Srwatson if (!mac_bsdextended_enabled) 478101099Srwatson return (0); 479101099Srwatson 480101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 481101099Srwatson if (error) 482101099Srwatson return (error); 483101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 484101099Srwatson} 485101099Srwatson 486101099Srwatsonstatic int 487104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 488104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 489104530Srwatson struct componentname *cnp) 490104530Srwatson{ 491104530Srwatson struct vattr vap; 492104530Srwatson int error; 493104530Srwatson 494104530Srwatson if (!mac_bsdextended_enabled) 495104530Srwatson return (0); 496104530Srwatson 497104530Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 498104530Srwatson if (error) 499104530Srwatson return (error); 500104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 501106214Srwatson if (error) 502106214Srwatson return (error); 503104530Srwatson 504104530Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 505104530Srwatson if (error) 506104530Srwatson return (error); 507104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 508104530Srwatson if (error) 509104530Srwatson return (error); 510104530Srwatson return (0); 511104530Srwatson} 512104530Srwatson 513104530Srwatsonstatic int 514119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 515119202Srwatson struct label *label, int attrnamespace) 516119202Srwatson{ 517119202Srwatson struct vattr vap; 518119202Srwatson int error; 519119202Srwatson 520119202Srwatson if (!mac_bsdextended_enabled) 521119202Srwatson return (0); 522119202Srwatson 523119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 524119202Srwatson if (error) 525119202Srwatson return (error); 526119202Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 527119202Srwatson} 528119202Srwatson 529119202Srwatsonstatic int 530101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 531101099Srwatson struct label *dlabel, struct componentname *cnp) 532101099Srwatson{ 533101099Srwatson struct vattr vap; 534101099Srwatson int error; 535117247Srwatson 536101099Srwatson if (!mac_bsdextended_enabled) 537101099Srwatson return (0); 538117247Srwatson 539101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 540101099Srwatson if (error) 541101099Srwatson return (error); 542101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 543101099Srwatson} 544101099Srwatson 545101099Srwatsonstatic int 546101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 547106212Srwatson struct label *filelabel, int acc_mode) 548101099Srwatson{ 549101099Srwatson struct vattr vap; 550101099Srwatson int error; 551101099Srwatson 552101099Srwatson if (!mac_bsdextended_enabled) 553101099Srwatson return (0); 554101099Srwatson 555101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 556101099Srwatson if (error) 557101099Srwatson return (error); 558101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 559101099Srwatson} 560101099Srwatson 561101099Srwatsonstatic int 562101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 563101099Srwatson struct label *dlabel) 564101099Srwatson{ 565101099Srwatson struct vattr vap; 566101099Srwatson int error; 567101099Srwatson 568101099Srwatson if (!mac_bsdextended_enabled) 569101099Srwatson return (0); 570101099Srwatson 571101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 572101099Srwatson if (error) 573101099Srwatson return (error); 574101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 575101099Srwatson} 576101099Srwatson 577101099Srwatsonstatic int 578101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 579101099Srwatson struct label *label) 580101099Srwatson{ 581101099Srwatson struct vattr vap; 582101099Srwatson int error; 583101099Srwatson 584101099Srwatson if (!mac_bsdextended_enabled) 585101099Srwatson return (0); 586101099Srwatson 587101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 588101099Srwatson if (error) 589101099Srwatson return (error); 590101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 591101099Srwatson} 592101099Srwatson 593101099Srwatsonstatic int 594101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 595101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 596101099Srwatson struct componentname *cnp) 597101099Srwatson{ 598101099Srwatson struct vattr vap; 599101099Srwatson int error; 600101099Srwatson 601101099Srwatson if (!mac_bsdextended_enabled) 602101099Srwatson return (0); 603101099Srwatson 604101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 605101099Srwatson if (error) 606101099Srwatson return (error); 607101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 608101099Srwatson if (error) 609101099Srwatson return (error); 610101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 611101099Srwatson if (error) 612101099Srwatson return (error); 613101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 614101099Srwatson 615101099Srwatson return (error); 616101099Srwatson} 617101099Srwatson 618101099Srwatsonstatic int 619101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 620101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 621101099Srwatson struct componentname *cnp) 622101099Srwatson{ 623101099Srwatson struct vattr vap; 624101099Srwatson int error; 625101099Srwatson 626101099Srwatson if (!mac_bsdextended_enabled) 627101099Srwatson return (0); 628101099Srwatson 629101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 630101099Srwatson if (error) 631101099Srwatson return (error); 632101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 633101099Srwatson if (error) 634101099Srwatson return (error); 635101099Srwatson 636101099Srwatson if (vp != NULL) { 637101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 638101099Srwatson if (error) 639101099Srwatson return (error); 640101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 641101099Srwatson VWRITE); 642101099Srwatson } 643101099Srwatson 644101099Srwatson return (error); 645101099Srwatson} 646101099Srwatson 647101099Srwatsonstatic int 648101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 649101099Srwatson struct label *label) 650101099Srwatson{ 651101099Srwatson struct vattr vap; 652101099Srwatson int error; 653101099Srwatson 654101099Srwatson if (!mac_bsdextended_enabled) 655101099Srwatson return (0); 656101099Srwatson 657101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 658101099Srwatson if (error) 659101099Srwatson return (error); 660101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 661101099Srwatson} 662101099Srwatson 663101099Srwatsonstatic int 664101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 665101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 666101099Srwatson{ 667101099Srwatson struct vattr vap; 668101099Srwatson int error; 669101099Srwatson 670101099Srwatson if (!mac_bsdextended_enabled) 671101099Srwatson return (0); 672101099Srwatson 673101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 674101099Srwatson if (error) 675101099Srwatson return (error); 676101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 677101099Srwatson} 678101099Srwatson 679101099Srwatsonstatic int 680101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 681101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 682101099Srwatson{ 683101099Srwatson struct vattr vap; 684101099Srwatson int error; 685101099Srwatson 686101099Srwatson if (!mac_bsdextended_enabled) 687101099Srwatson return (0); 688101099Srwatson 689101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 690101099Srwatson if (error) 691101099Srwatson return (error); 692101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 693101099Srwatson} 694101099Srwatson 695101099Srwatsonstatic int 696101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 697101099Srwatson struct label *label, u_long flags) 698101099Srwatson{ 699101099Srwatson struct vattr vap; 700101099Srwatson int error; 701101099Srwatson 702101099Srwatson if (!mac_bsdextended_enabled) 703101099Srwatson return (0); 704101099Srwatson 705101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 706101099Srwatson if (error) 707101099Srwatson return (error); 708101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 709101099Srwatson} 710101099Srwatson 711101099Srwatsonstatic int 712101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 713101099Srwatson struct label *label, mode_t mode) 714101099Srwatson{ 715101099Srwatson struct vattr vap; 716101099Srwatson int error; 717101099Srwatson 718101099Srwatson if (!mac_bsdextended_enabled) 719101099Srwatson return (0); 720101099Srwatson 721101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 722101099Srwatson if (error) 723101099Srwatson return (error); 724101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 725101099Srwatson} 726101099Srwatson 727101099Srwatsonstatic int 728101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 729101099Srwatson struct label *label, uid_t uid, gid_t gid) 730101099Srwatson{ 731101099Srwatson struct vattr vap; 732101099Srwatson int error; 733101099Srwatson 734101099Srwatson if (!mac_bsdextended_enabled) 735101099Srwatson return (0); 736101099Srwatson 737101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 738101099Srwatson if (error) 739101099Srwatson return (error); 740101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 741101099Srwatson} 742101099Srwatson 743101099Srwatsonstatic int 744101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 745101099Srwatson struct label *label, struct timespec atime, struct timespec utime) 746101099Srwatson{ 747101099Srwatson struct vattr vap; 748101099Srwatson int error; 749101099Srwatson 750101099Srwatson if (!mac_bsdextended_enabled) 751101099Srwatson return (0); 752101099Srwatson 753101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 754101099Srwatson if (error) 755101099Srwatson return (error); 756101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 757101099Srwatson} 758101099Srwatson 759101099Srwatsonstatic int 760102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 761102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 762101099Srwatson{ 763101099Srwatson struct vattr vap; 764101099Srwatson int error; 765101099Srwatson 766101099Srwatson if (!mac_bsdextended_enabled) 767101099Srwatson return (0); 768101099Srwatson 769102129Srwatson error = VOP_GETATTR(vp, &vap, active_cred, curthread); 770101099Srwatson if (error) 771101099Srwatson return (error); 772102129Srwatson return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 773102129Srwatson VSTAT)); 774101099Srwatson} 775101099Srwatson 776106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 777101099Srwatson{ 778106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 779106217Srwatson .mpo_init = mac_bsdextended_init, 780112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 781106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 782106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 783106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 784106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 785106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 786106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 787119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 788106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 789106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 790106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 791106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 792119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 793106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 794106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 795106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 796106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 797106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 798106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 799106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 800106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 801106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 802106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 803106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 804106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 805106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 806106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 807101099Srwatson}; 808101099Srwatson 809112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 810101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 811