ugidfw_system.c revision 134131
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 134131 2004-08-21 20:15:08Z trhodes $ 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 99134131Strhodes/* 100134131Strhodes * This tunable is here for compatibility. It will allow the user 101134131Strhodes * to switch between the new mode (first rule matches) and the old 102134131Strhodes * functionality (all rules match). 103134131Strhodes */ 104101099Srwatsonstatic int 105134131Strhodesmac_bsdextended_firstmatch_enabled; 106134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 107134131Strhodes CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 0, 108134131Strhodes "Disable/enable match first rule functionality"); 109134131Strhodes 110134131Strhodesstatic int 111101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 112101099Srwatson{ 113101099Srwatson 114101099Srwatson if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 115101099Srwatson return (EINVAL); 116101099Srwatson 117101099Srwatson if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 118101099Srwatson return (EINVAL); 119101099Srwatson 120101099Srwatson if ((rule->mbr_mode | VALLPERM) != VALLPERM) 121101099Srwatson return (EINVAL); 122101099Srwatson 123101099Srwatson return (0); 124101099Srwatson} 125101099Srwatson 126101099Srwatsonstatic int 127101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 128101099Srwatson{ 129101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 130101099Srwatson u_int namelen; 131101099Srwatson int error, index, *name; 132101099Srwatson 133101099Srwatson name = (int *)arg1; 134101099Srwatson namelen = arg2; 135101099Srwatson 136101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 137101099Srwatson 138101099Srwatson if (namelen != 1) 139101099Srwatson return (EINVAL); 140101099Srwatson 141101099Srwatson index = name[0]; 142101099Srwatson if (index < 0 || index > rule_slots + 1) 143101099Srwatson return (ENOENT); 144101099Srwatson if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 145101099Srwatson return (ENOENT); 146101099Srwatson 147101099Srwatson if (req->oldptr) { 148101099Srwatson if (rules[index] == NULL) 149101099Srwatson return (ENOENT); 150101099Srwatson 151101099Srwatson error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); 152101099Srwatson if (error) 153101099Srwatson return (error); 154101099Srwatson } 155101099Srwatson 156101099Srwatson if (req->newptr) { 157101099Srwatson if (req->newlen == 0) { 158101099Srwatson /* printf("deletion\n"); */ 159101099Srwatson ruleptr = rules[index]; 160101099Srwatson if (ruleptr == NULL) 161101099Srwatson return (ENOENT); 162101099Srwatson rule_count--; 163101099Srwatson rules[index] = NULL; 164101099Srwatson FREE(ruleptr, M_MACBSDEXTENDED); 165101099Srwatson return(0); 166101099Srwatson } 167101099Srwatson error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 168101099Srwatson if (error) 169101099Srwatson return (error); 170101099Srwatson 171101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 172101099Srwatson if (error) 173101099Srwatson return (error); 174101099Srwatson 175101099Srwatson if (rules[index] == NULL) { 176101099Srwatson /* printf("addition\n"); */ 177101099Srwatson MALLOC(ruleptr, struct mac_bsdextended_rule *, 178111119Simp sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 179101099Srwatson M_ZERO); 180101099Srwatson *ruleptr = temprule; 181101099Srwatson rules[index] = ruleptr; 182101099Srwatson if (index+1 > rule_slots) 183101099Srwatson rule_slots = index+1; 184101099Srwatson rule_count++; 185101099Srwatson } else { 186101099Srwatson /* printf("replacement\n"); */ 187101099Srwatson *rules[index] = temprule; 188101099Srwatson } 189101099Srwatson } 190101099Srwatson 191101099Srwatson return (0); 192101099Srwatson} 193101099Srwatson 194101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 195101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 196101099Srwatson 197101099Srwatsonstatic void 198101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 199101099Srwatson{ 200101099Srwatson 201101099Srwatson /* Initialize ruleset lock. */ 202101099Srwatson /* Register dynamic sysctl's for rules. */ 203101099Srwatson} 204101099Srwatson 205101099Srwatsonstatic void 206101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 207101099Srwatson{ 208101099Srwatson 209101099Srwatson /* Tear down sysctls. */ 210101099Srwatson /* Destroy ruleset lock. */ 211101099Srwatson} 212101099Srwatson 213101099Srwatsonstatic int 214101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 215106212Srwatson struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 216101099Srwatson{ 217101099Srwatson int match; 218101099Srwatson 219101099Srwatson /* 220101099Srwatson * Is there a subject match? 221101099Srwatson */ 222101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 223101099Srwatson match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 224101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_ruid || 225101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_svuid); 226101099Srwatson 227101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 228101099Srwatson match = !match; 229101099Srwatson 230101099Srwatson if (!match) 231101099Srwatson return (0); 232101099Srwatson } 233101099Srwatson 234101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 235101099Srwatson match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 236101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_rgid || 237101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_svgid); 238101099Srwatson 239101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 240101099Srwatson match = !match; 241101099Srwatson 242101099Srwatson if (!match) 243101099Srwatson return (0); 244101099Srwatson } 245101099Srwatson 246101099Srwatson /* 247101099Srwatson * Is there an object match? 248101099Srwatson */ 249101099Srwatson if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 250101099Srwatson match = (rule->mbr_object.mbi_uid == object_uid); 251101099Srwatson 252101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 253101099Srwatson match = !match; 254101099Srwatson 255101099Srwatson if (!match) 256101099Srwatson return (0); 257101099Srwatson } 258101099Srwatson 259101099Srwatson if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 260101099Srwatson match = (rule->mbr_object.mbi_gid == object_gid); 261101099Srwatson 262101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 263101099Srwatson match = !match; 264101099Srwatson 265101099Srwatson if (!match) 266101099Srwatson return (0); 267101099Srwatson } 268101099Srwatson 269101099Srwatson /* 270101099Srwatson * Is the access permitted? 271101099Srwatson */ 272101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 273101099Srwatson if (mac_bsdextended_debugging) 274101099Srwatson printf("mac_bsdextended: %d:%d request %d on %d:%d" 275101099Srwatson " fails\n", cred->cr_ruid, cred->cr_rgid, 276101099Srwatson acc_mode, object_uid, object_gid); 277101099Srwatson return (EACCES); 278101099Srwatson } 279134131Strhodes /* 280134131Strhodes * If the rule matched and allowed access and first match is 281134131Strhodes * enabled, then return success. 282134131Strhodes */ 283134131Strhodes if (mac_bsdextended_firstmatch_enabled) 284134131Strhodes return (EJUSTRETURN); 285134131Strhodes else 286134131Strhodes return(0); 287101099Srwatson} 288101099Srwatson 289101099Srwatsonstatic int 290101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 291106212Srwatson int acc_mode) 292101099Srwatson{ 293101099Srwatson int error, i; 294101099Srwatson 295132563Srwatson if (suser_cred(cred, 0) == 0) 296132563Srwatson return (0); 297132563Srwatson 298101099Srwatson for (i = 0; i < rule_slots; i++) { 299101099Srwatson if (rules[i] == NULL) 300101099Srwatson continue; 301101099Srwatson 302108376Srwatson /* 303108376Srwatson * Since we don't separately handle append, map append to 304108376Srwatson * write. 305108376Srwatson */ 306108376Srwatson if (acc_mode & VAPPEND) { 307108376Srwatson acc_mode &= ~VAPPEND; 308108376Srwatson acc_mode |= VWRITE; 309108376Srwatson } 310108376Srwatson 311101099Srwatson error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 312101099Srwatson object_gid, acc_mode); 313134131Strhodes if (error == EJUSTRETURN) 314134131Strhodes break; 315101099Srwatson if (error) 316101099Srwatson return (error); 317101099Srwatson } 318101099Srwatson 319101099Srwatson return (0); 320101099Srwatson} 321101099Srwatson 322101099Srwatsonstatic int 323112575Srwatsonmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 324112575Srwatson struct label *label) 325112575Srwatson{ 326112575Srwatson struct vattr vap; 327112575Srwatson int error; 328112575Srwatson 329112575Srwatson if (!mac_bsdextended_enabled) 330112575Srwatson return (0); 331112575Srwatson 332112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 333112575Srwatson if (error) 334112575Srwatson return (error); 335112575Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 336112575Srwatson} 337112575Srwatson 338112575Srwatsonstatic int 339101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 340106212Srwatson struct label *label, int acc_mode) 341101099Srwatson{ 342101099Srwatson struct vattr vap; 343101099Srwatson int error; 344101099Srwatson 345101099Srwatson if (!mac_bsdextended_enabled) 346101099Srwatson return (0); 347101099Srwatson 348101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 349101099Srwatson if (error) 350101099Srwatson return (error); 351106212Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 352101099Srwatson} 353101099Srwatson 354101099Srwatsonstatic int 355101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 356101099Srwatson struct label *dlabel) 357101099Srwatson{ 358101099Srwatson struct vattr vap; 359101099Srwatson int error; 360101099Srwatson 361101099Srwatson if (!mac_bsdextended_enabled) 362101099Srwatson return (0); 363101099Srwatson 364101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 365101099Srwatson if (error) 366101099Srwatson return (error); 367101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 368101099Srwatson} 369101099Srwatson 370101099Srwatsonstatic int 371101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 372101099Srwatson struct label *dlabel) 373101099Srwatson{ 374101099Srwatson struct vattr vap; 375101099Srwatson int error; 376101099Srwatson 377101099Srwatson if (!mac_bsdextended_enabled) 378101099Srwatson return (0); 379101099Srwatson 380101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 381101099Srwatson if (error) 382101099Srwatson return (error); 383101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 384101099Srwatson} 385101099Srwatson 386101099Srwatsonstatic int 387101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 388101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 389101099Srwatson{ 390101099Srwatson struct vattr dvap; 391101099Srwatson int error; 392101099Srwatson 393101099Srwatson if (!mac_bsdextended_enabled) 394101099Srwatson return (0); 395101099Srwatson 396101099Srwatson error = VOP_GETATTR(dvp, &dvap, cred, curthread); 397101099Srwatson if (error) 398101099Srwatson return (error); 399101099Srwatson return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE)); 400101099Srwatson} 401101099Srwatson 402101099Srwatsonstatic int 403101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 404101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 405101099Srwatson struct componentname *cnp) 406101099Srwatson{ 407101099Srwatson struct vattr vap; 408101099Srwatson int error; 409101099Srwatson 410101099Srwatson if (!mac_bsdextended_enabled) 411101099Srwatson return (0); 412101099Srwatson 413101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 414101099Srwatson if (error) 415101099Srwatson return (error); 416101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 417101099Srwatson if (error) 418101099Srwatson return (error); 419101099Srwatson 420101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 421101099Srwatson if (error) 422101099Srwatson return (error); 423101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 424101099Srwatson} 425101099Srwatson 426101099Srwatsonstatic int 427101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 428101099Srwatson struct label *label, acl_type_t type) 429101099Srwatson{ 430101099Srwatson struct vattr vap; 431101099Srwatson int error; 432101099Srwatson 433101099Srwatson if (!mac_bsdextended_enabled) 434101099Srwatson return (0); 435101099Srwatson 436101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 437117247Srwatson if (error) 438101099Srwatson return (error); 439101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 440101099Srwatson} 441101099Srwatson 442101099Srwatsonstatic int 443119202Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 444119202Srwatson struct label *label, int attrnamespace, const char *name) 445119202Srwatson{ 446119202Srwatson struct vattr vap; 447119202Srwatson int error; 448119202Srwatson 449119202Srwatson if (!mac_bsdextended_enabled) 450119202Srwatson return (0); 451119202Srwatson 452119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 453119202Srwatson if (error) 454119202Srwatson return (error); 455119202Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 456119202Srwatson} 457119202Srwatson 458119202Srwatsonstatic int 459101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 460106648Srwatson struct label *label, struct image_params *imgp, 461106648Srwatson struct label *execlabel) 462101099Srwatson{ 463101099Srwatson struct vattr vap; 464101099Srwatson int error; 465101099Srwatson 466101099Srwatson if (!mac_bsdextended_enabled) 467101099Srwatson return (0); 468101099Srwatson 469101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 470101099Srwatson if (error) 471101099Srwatson return (error); 472101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 473101099Srwatson VREAD|VEXEC)); 474101099Srwatson} 475101099Srwatson 476101099Srwatsonstatic int 477101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 478101099Srwatson struct label *label, acl_type_t type) 479101099Srwatson{ 480101099Srwatson struct vattr vap; 481101099Srwatson int error; 482101099Srwatson 483101099Srwatson if (!mac_bsdextended_enabled) 484101099Srwatson return (0); 485101099Srwatson 486101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 487101099Srwatson if (error) 488101099Srwatson return (error); 489101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT)); 490101099Srwatson} 491101099Srwatson 492101099Srwatsonstatic int 493101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 494101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 495101099Srwatson{ 496101099Srwatson struct vattr vap; 497101099Srwatson int error; 498101099Srwatson 499101099Srwatson if (!mac_bsdextended_enabled) 500101099Srwatson return (0); 501101099Srwatson 502101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 503101099Srwatson if (error) 504101099Srwatson return (error); 505101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 506101099Srwatson} 507101099Srwatson 508101099Srwatsonstatic int 509104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 510104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 511104530Srwatson struct componentname *cnp) 512104530Srwatson{ 513104530Srwatson struct vattr vap; 514104530Srwatson int error; 515104530Srwatson 516104530Srwatson if (!mac_bsdextended_enabled) 517104530Srwatson return (0); 518104530Srwatson 519104530Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 520104530Srwatson if (error) 521104530Srwatson return (error); 522104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 523106214Srwatson if (error) 524106214Srwatson return (error); 525104530Srwatson 526104530Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 527104530Srwatson if (error) 528104530Srwatson return (error); 529104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 530104530Srwatson if (error) 531104530Srwatson return (error); 532104530Srwatson return (0); 533104530Srwatson} 534104530Srwatson 535104530Srwatsonstatic int 536119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 537119202Srwatson struct label *label, int attrnamespace) 538119202Srwatson{ 539119202Srwatson struct vattr vap; 540119202Srwatson int error; 541119202Srwatson 542119202Srwatson if (!mac_bsdextended_enabled) 543119202Srwatson return (0); 544119202Srwatson 545119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 546119202Srwatson if (error) 547119202Srwatson return (error); 548119202Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 549119202Srwatson} 550119202Srwatson 551119202Srwatsonstatic int 552101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 553101099Srwatson struct label *dlabel, struct componentname *cnp) 554101099Srwatson{ 555101099Srwatson struct vattr vap; 556101099Srwatson int error; 557117247Srwatson 558101099Srwatson if (!mac_bsdextended_enabled) 559101099Srwatson return (0); 560117247Srwatson 561101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 562101099Srwatson if (error) 563101099Srwatson return (error); 564101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 565101099Srwatson} 566101099Srwatson 567101099Srwatsonstatic int 568101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 569106212Srwatson struct label *filelabel, int acc_mode) 570101099Srwatson{ 571101099Srwatson struct vattr vap; 572101099Srwatson int error; 573101099Srwatson 574101099Srwatson if (!mac_bsdextended_enabled) 575101099Srwatson return (0); 576101099Srwatson 577101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 578101099Srwatson if (error) 579101099Srwatson return (error); 580101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 581101099Srwatson} 582101099Srwatson 583101099Srwatsonstatic int 584101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 585101099Srwatson struct label *dlabel) 586101099Srwatson{ 587101099Srwatson struct vattr vap; 588101099Srwatson int error; 589101099Srwatson 590101099Srwatson if (!mac_bsdextended_enabled) 591101099Srwatson return (0); 592101099Srwatson 593101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 594101099Srwatson if (error) 595101099Srwatson return (error); 596101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 597101099Srwatson} 598101099Srwatson 599101099Srwatsonstatic int 600101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 601101099Srwatson struct label *label) 602101099Srwatson{ 603101099Srwatson struct vattr vap; 604101099Srwatson int error; 605101099Srwatson 606101099Srwatson if (!mac_bsdextended_enabled) 607101099Srwatson return (0); 608101099Srwatson 609101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 610101099Srwatson if (error) 611101099Srwatson return (error); 612101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 613101099Srwatson} 614101099Srwatson 615101099Srwatsonstatic int 616101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 617101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 618101099Srwatson struct componentname *cnp) 619101099Srwatson{ 620101099Srwatson struct vattr vap; 621101099Srwatson int error; 622101099Srwatson 623101099Srwatson if (!mac_bsdextended_enabled) 624101099Srwatson return (0); 625101099Srwatson 626101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 627101099Srwatson if (error) 628101099Srwatson return (error); 629101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 630101099Srwatson if (error) 631101099Srwatson return (error); 632101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 633101099Srwatson if (error) 634101099Srwatson return (error); 635101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 636101099Srwatson 637101099Srwatson return (error); 638101099Srwatson} 639101099Srwatson 640101099Srwatsonstatic int 641101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 642101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 643101099Srwatson struct componentname *cnp) 644101099Srwatson{ 645101099Srwatson struct vattr vap; 646101099Srwatson int error; 647101099Srwatson 648101099Srwatson if (!mac_bsdextended_enabled) 649101099Srwatson return (0); 650101099Srwatson 651101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 652101099Srwatson if (error) 653101099Srwatson return (error); 654101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 655101099Srwatson if (error) 656101099Srwatson return (error); 657101099Srwatson 658101099Srwatson if (vp != NULL) { 659101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 660101099Srwatson if (error) 661101099Srwatson return (error); 662101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 663101099Srwatson VWRITE); 664101099Srwatson } 665101099Srwatson 666101099Srwatson return (error); 667101099Srwatson} 668101099Srwatson 669101099Srwatsonstatic int 670101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 671101099Srwatson struct label *label) 672101099Srwatson{ 673101099Srwatson struct vattr vap; 674101099Srwatson int error; 675101099Srwatson 676101099Srwatson if (!mac_bsdextended_enabled) 677101099Srwatson return (0); 678101099Srwatson 679101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 680101099Srwatson if (error) 681101099Srwatson return (error); 682101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 683101099Srwatson} 684101099Srwatson 685101099Srwatsonstatic int 686101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 687101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 688101099Srwatson{ 689101099Srwatson struct vattr vap; 690101099Srwatson int error; 691101099Srwatson 692101099Srwatson if (!mac_bsdextended_enabled) 693101099Srwatson return (0); 694101099Srwatson 695101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 696101099Srwatson if (error) 697101099Srwatson return (error); 698101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 699101099Srwatson} 700101099Srwatson 701101099Srwatsonstatic int 702101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 703101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 704101099Srwatson{ 705101099Srwatson struct vattr vap; 706101099Srwatson int error; 707101099Srwatson 708101099Srwatson if (!mac_bsdextended_enabled) 709101099Srwatson return (0); 710101099Srwatson 711101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 712101099Srwatson if (error) 713101099Srwatson return (error); 714101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 715101099Srwatson} 716101099Srwatson 717101099Srwatsonstatic int 718101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 719101099Srwatson struct label *label, u_long flags) 720101099Srwatson{ 721101099Srwatson struct vattr vap; 722101099Srwatson int error; 723101099Srwatson 724101099Srwatson if (!mac_bsdextended_enabled) 725101099Srwatson return (0); 726101099Srwatson 727101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 728101099Srwatson if (error) 729101099Srwatson return (error); 730101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 731101099Srwatson} 732101099Srwatson 733101099Srwatsonstatic int 734101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 735101099Srwatson struct label *label, mode_t mode) 736101099Srwatson{ 737101099Srwatson struct vattr vap; 738101099Srwatson int error; 739101099Srwatson 740101099Srwatson if (!mac_bsdextended_enabled) 741101099Srwatson return (0); 742101099Srwatson 743101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 744101099Srwatson if (error) 745101099Srwatson return (error); 746101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 747101099Srwatson} 748101099Srwatson 749101099Srwatsonstatic int 750101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 751101099Srwatson struct label *label, uid_t uid, gid_t gid) 752101099Srwatson{ 753101099Srwatson struct vattr vap; 754101099Srwatson int error; 755101099Srwatson 756101099Srwatson if (!mac_bsdextended_enabled) 757101099Srwatson return (0); 758101099Srwatson 759101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 760101099Srwatson if (error) 761101099Srwatson return (error); 762101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 763101099Srwatson} 764101099Srwatson 765101099Srwatsonstatic int 766101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 767101099Srwatson struct label *label, struct timespec atime, struct timespec utime) 768101099Srwatson{ 769101099Srwatson struct vattr vap; 770101099Srwatson int error; 771101099Srwatson 772101099Srwatson if (!mac_bsdextended_enabled) 773101099Srwatson return (0); 774101099Srwatson 775101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 776101099Srwatson if (error) 777101099Srwatson return (error); 778101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 779101099Srwatson} 780101099Srwatson 781101099Srwatsonstatic int 782102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 783102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 784101099Srwatson{ 785101099Srwatson struct vattr vap; 786101099Srwatson int error; 787101099Srwatson 788101099Srwatson if (!mac_bsdextended_enabled) 789101099Srwatson return (0); 790101099Srwatson 791102129Srwatson error = VOP_GETATTR(vp, &vap, active_cred, curthread); 792101099Srwatson if (error) 793101099Srwatson return (error); 794102129Srwatson return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 795102129Srwatson VSTAT)); 796101099Srwatson} 797101099Srwatson 798106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 799101099Srwatson{ 800106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 801106217Srwatson .mpo_init = mac_bsdextended_init, 802112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 803106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 804106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 805106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 806106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 807106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 808106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 809119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 810106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 811106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 812106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 813106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 814119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 815106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 816106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 817106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 818106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 819106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 820106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 821106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 822106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 823106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 824106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 825106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 826106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 827106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 828106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 829101099Srwatson}; 830101099Srwatson 831112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 832101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 833