ugidfw_vnode.c revision 104530
1101099Srwatson/*- 2101099Srwatson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 3101099Srwatson * Copyright (c) 2001, 2002 Networks Associates Technology, Inc. 4101099Srwatson * All rights reserved. 5101099Srwatson * 6101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 7101099Srwatson * 8101099Srwatson * This software was developed for the FreeBSD Project in part by NAI Labs, 9101099Srwatson * the Security Research Division of Network Associates, Inc. under 10101099Srwatson * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA 11101099Srwatson * 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 * 3. The names of the authors may not be used to endorse or promote 22101099Srwatson * products derived from this software without specific prior written 23101099Srwatson * permission. 24101099Srwatson * 25101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 26101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 29101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35101099Srwatson * SUCH DAMAGE. 36101099Srwatson * 37101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 104530 2002-10-05 18:25:48Z rwatson $ 38101099Srwatson */ 39101099Srwatson/* 40101099Srwatson * Developed by the TrustedBSD Project. 41101099Srwatson * "BSD Extended" MAC policy, allowing the administrator to impose 42101099Srwatson * mandatory rules regarding users and some system objects. 43101099Srwatson * 44101099Srwatson * XXX: Much locking support required here. 45101099Srwatson */ 46101099Srwatson 47101099Srwatson#include <sys/types.h> 48101099Srwatson#include <sys/param.h> 49101099Srwatson#include <sys/acl.h> 50101099Srwatson#include <sys/conf.h> 51101099Srwatson#include <sys/kernel.h> 52101099Srwatson#include <sys/mac.h> 53101099Srwatson#include <sys/malloc.h> 54101099Srwatson#include <sys/mount.h> 55101099Srwatson#include <sys/proc.h> 56101099Srwatson#include <sys/systm.h> 57101099Srwatson#include <sys/sysproto.h> 58101099Srwatson#include <sys/sysent.h> 59101099Srwatson#include <sys/vnode.h> 60101099Srwatson#include <sys/file.h> 61101099Srwatson#include <sys/socket.h> 62101099Srwatson#include <sys/socketvar.h> 63101099Srwatson#include <sys/sysctl.h> 64101099Srwatson 65101099Srwatson#include <net/bpfdesc.h> 66101099Srwatson#include <net/if.h> 67101099Srwatson#include <net/if_types.h> 68101099Srwatson#include <net/if_var.h> 69101099Srwatson 70101099Srwatson#include <vm/vm.h> 71101099Srwatson 72101099Srwatson#include <sys/mac_policy.h> 73101099Srwatson 74101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 75101099Srwatson 76101099SrwatsonSYSCTL_DECL(_security_mac); 77101099Srwatson 78101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 79101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 80101099Srwatson 81101099Srwatsonstatic int mac_bsdextended_enabled = 1; 82101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 83101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 84101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 85101099Srwatson 86101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 87101099Srwatson 88101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 89101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 90101099Srwatsonstatic int rule_count = 0; 91101099Srwatsonstatic int rule_slots = 0; 92101099Srwatson 93101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 94101099Srwatson &rule_count, 0, "Number of defined rules\n"); 95101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 96101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 97101099Srwatson 98101099Srwatsonstatic int mac_bsdextended_debugging; 99101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, debugging, CTLFLAG_RW, 100101099Srwatson &mac_bsdextended_debugging, 0, "Enable debugging on failure"); 101101099Srwatson 102101099Srwatsonstatic int 103101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 104101099Srwatson{ 105101099Srwatson 106101099Srwatson if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 107101099Srwatson return (EINVAL); 108101099Srwatson 109101099Srwatson if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 110101099Srwatson return (EINVAL); 111101099Srwatson 112101099Srwatson if ((rule->mbr_mode | VALLPERM) != VALLPERM) 113101099Srwatson return (EINVAL); 114101099Srwatson 115101099Srwatson return (0); 116101099Srwatson} 117101099Srwatson 118101099Srwatsonstatic int 119101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 120101099Srwatson{ 121101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 122101099Srwatson u_int namelen; 123101099Srwatson int error, index, *name; 124101099Srwatson 125101099Srwatson name = (int *)arg1; 126101099Srwatson namelen = arg2; 127101099Srwatson 128101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 129101099Srwatson 130101099Srwatson if (namelen != 1) 131101099Srwatson return (EINVAL); 132101099Srwatson 133101099Srwatson index = name[0]; 134101099Srwatson if (index < 0 || index > rule_slots + 1) 135101099Srwatson return (ENOENT); 136101099Srwatson if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 137101099Srwatson return (ENOENT); 138101099Srwatson 139101099Srwatson if (req->oldptr) { 140101099Srwatson if (rules[index] == NULL) 141101099Srwatson return (ENOENT); 142101099Srwatson 143101099Srwatson error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); 144101099Srwatson if (error) 145101099Srwatson return (error); 146101099Srwatson } 147101099Srwatson 148101099Srwatson if (req->newptr) { 149101099Srwatson if (req->newlen == 0) { 150101099Srwatson /* printf("deletion\n"); */ 151101099Srwatson ruleptr = rules[index]; 152101099Srwatson if (ruleptr == NULL) 153101099Srwatson return (ENOENT); 154101099Srwatson rule_count--; 155101099Srwatson rules[index] = NULL; 156101099Srwatson FREE(ruleptr, M_MACBSDEXTENDED); 157101099Srwatson return(0); 158101099Srwatson } 159101099Srwatson error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 160101099Srwatson if (error) 161101099Srwatson return (error); 162101099Srwatson 163101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 164101099Srwatson if (error) 165101099Srwatson return (error); 166101099Srwatson 167101099Srwatson if (rules[index] == NULL) { 168101099Srwatson /* printf("addition\n"); */ 169101099Srwatson MALLOC(ruleptr, struct mac_bsdextended_rule *, 170101099Srwatson sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 171101099Srwatson M_ZERO); 172101099Srwatson *ruleptr = temprule; 173101099Srwatson rules[index] = ruleptr; 174101099Srwatson if (index+1 > rule_slots) 175101099Srwatson rule_slots = index+1; 176101099Srwatson rule_count++; 177101099Srwatson } else { 178101099Srwatson /* printf("replacement\n"); */ 179101099Srwatson *rules[index] = temprule; 180101099Srwatson } 181101099Srwatson } 182101099Srwatson 183101099Srwatson return (0); 184101099Srwatson} 185101099Srwatson 186101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 187101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 188101099Srwatson 189101099Srwatsonstatic void 190101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 191101099Srwatson{ 192101099Srwatson 193101099Srwatson /* Initialize ruleset lock. */ 194101099Srwatson /* Register dynamic sysctl's for rules. */ 195101099Srwatson} 196101099Srwatson 197101099Srwatsonstatic void 198101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 199101099Srwatson{ 200101099Srwatson 201101099Srwatson /* Tear down sysctls. */ 202101099Srwatson /* Destroy ruleset lock. */ 203101099Srwatson} 204101099Srwatson 205101099Srwatsonstatic int 206101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 207101099Srwatson struct ucred *cred, uid_t object_uid, gid_t object_gid, mode_t acc_mode) 208101099Srwatson{ 209101099Srwatson int match; 210101099Srwatson 211101099Srwatson /* 212101099Srwatson * Is there a subject match? 213101099Srwatson */ 214101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 215101099Srwatson match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 216101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_ruid || 217101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_svuid); 218101099Srwatson 219101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 220101099Srwatson match = !match; 221101099Srwatson 222101099Srwatson if (!match) 223101099Srwatson return (0); 224101099Srwatson } 225101099Srwatson 226101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 227101099Srwatson match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 228101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_rgid || 229101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_svgid); 230101099Srwatson 231101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 232101099Srwatson match = !match; 233101099Srwatson 234101099Srwatson if (!match) 235101099Srwatson return (0); 236101099Srwatson } 237101099Srwatson 238101099Srwatson /* 239101099Srwatson * Is there an object match? 240101099Srwatson */ 241101099Srwatson if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 242101099Srwatson match = (rule->mbr_object.mbi_uid == object_uid); 243101099Srwatson 244101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 245101099Srwatson match = !match; 246101099Srwatson 247101099Srwatson if (!match) 248101099Srwatson return (0); 249101099Srwatson } 250101099Srwatson 251101099Srwatson if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 252101099Srwatson match = (rule->mbr_object.mbi_gid == object_gid); 253101099Srwatson 254101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 255101099Srwatson match = !match; 256101099Srwatson 257101099Srwatson if (!match) 258101099Srwatson return (0); 259101099Srwatson } 260101099Srwatson 261101099Srwatson /* 262101099Srwatson * Is the access permitted? 263101099Srwatson */ 264101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 265101099Srwatson if (mac_bsdextended_debugging) 266101099Srwatson printf("mac_bsdextended: %d:%d request %d on %d:%d" 267101099Srwatson " fails\n", cred->cr_ruid, cred->cr_rgid, 268101099Srwatson acc_mode, object_uid, object_gid); 269101099Srwatson return (EACCES); 270101099Srwatson } 271101099Srwatson 272101099Srwatson return (0); 273101099Srwatson} 274101099Srwatson 275101099Srwatsonstatic int 276101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 277101099Srwatson mode_t acc_mode) 278101099Srwatson{ 279101099Srwatson int error, i; 280101099Srwatson 281101099Srwatson for (i = 0; i < rule_slots; i++) { 282101099Srwatson if (rules[i] == NULL) 283101099Srwatson continue; 284101099Srwatson 285101099Srwatson error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 286101099Srwatson object_gid, acc_mode); 287101099Srwatson if (error) 288101099Srwatson return (error); 289101099Srwatson } 290101099Srwatson 291101099Srwatson return (0); 292101099Srwatson} 293101099Srwatson 294101099Srwatsonstatic int 295101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 296101099Srwatson struct label *label, mode_t flags) 297101099Srwatson{ 298101099Srwatson struct vattr vap; 299101099Srwatson int error; 300101099Srwatson 301101099Srwatson if (!mac_bsdextended_enabled) 302101099Srwatson return (0); 303101099Srwatson 304101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 305101099Srwatson if (error) 306101099Srwatson return (error); 307101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, flags)); 308101099Srwatson} 309101099Srwatson 310101099Srwatsonstatic int 311101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 312101099Srwatson struct label *dlabel) 313101099Srwatson{ 314101099Srwatson struct vattr vap; 315101099Srwatson int error; 316101099Srwatson 317101099Srwatson if (!mac_bsdextended_enabled) 318101099Srwatson return (0); 319101099Srwatson 320101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 321101099Srwatson if (error) 322101099Srwatson return (error); 323101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 324101099Srwatson} 325101099Srwatson 326101099Srwatsonstatic int 327101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 328101099Srwatson struct label *dlabel) 329101099Srwatson{ 330101099Srwatson struct vattr vap; 331101099Srwatson int error; 332101099Srwatson 333101099Srwatson if (!mac_bsdextended_enabled) 334101099Srwatson return (0); 335101099Srwatson 336101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 337101099Srwatson if (error) 338101099Srwatson return (error); 339101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 340101099Srwatson} 341101099Srwatson 342101099Srwatsonstatic int 343101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 344101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 345101099Srwatson{ 346101099Srwatson struct vattr dvap; 347101099Srwatson int error; 348101099Srwatson 349101099Srwatson if (!mac_bsdextended_enabled) 350101099Srwatson return (0); 351101099Srwatson 352101099Srwatson error = VOP_GETATTR(dvp, &dvap, cred, curthread); 353101099Srwatson if (error) 354101099Srwatson return (error); 355101099Srwatson return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, VWRITE)); 356101099Srwatson} 357101099Srwatson 358101099Srwatsonstatic int 359101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 360101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 361101099Srwatson struct componentname *cnp) 362101099Srwatson{ 363101099Srwatson struct vattr vap; 364101099Srwatson int error; 365101099Srwatson 366101099Srwatson if (!mac_bsdextended_enabled) 367101099Srwatson return (0); 368101099Srwatson 369101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 370101099Srwatson if (error) 371101099Srwatson return (error); 372101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 373101099Srwatson if (error) 374101099Srwatson return (error); 375101099Srwatson 376101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 377101099Srwatson if (error) 378101099Srwatson return (error); 379101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 380101099Srwatson} 381101099Srwatson 382101099Srwatsonstatic int 383101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 384101099Srwatson struct label *label, acl_type_t type) 385101099Srwatson{ 386101099Srwatson struct vattr vap; 387101099Srwatson int error; 388101099Srwatson 389101099Srwatson if (!mac_bsdextended_enabled) 390101099Srwatson return (0); 391101099Srwatson 392101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 393101099Srwatson if (error) 394101099Srwatson return (error); 395101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 396101099Srwatson} 397101099Srwatson 398101099Srwatsonstatic int 399101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 400101099Srwatson struct label *label) 401101099Srwatson{ 402101099Srwatson struct vattr vap; 403101099Srwatson int error; 404101099Srwatson 405101099Srwatson if (!mac_bsdextended_enabled) 406101099Srwatson return (0); 407101099Srwatson 408101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 409101099Srwatson if (error) 410101099Srwatson return (error); 411101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 412101099Srwatson VREAD|VEXEC)); 413101099Srwatson} 414101099Srwatson 415101099Srwatsonstatic int 416101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 417101099Srwatson struct label *label, acl_type_t type) 418101099Srwatson{ 419101099Srwatson struct vattr vap; 420101099Srwatson int error; 421101099Srwatson 422101099Srwatson if (!mac_bsdextended_enabled) 423101099Srwatson return (0); 424101099Srwatson 425101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 426101099Srwatson if (error) 427101099Srwatson return (error); 428101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VSTAT)); 429101099Srwatson} 430101099Srwatson 431101099Srwatsonstatic int 432101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 433101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 434101099Srwatson{ 435101099Srwatson struct vattr vap; 436101099Srwatson int error; 437101099Srwatson 438101099Srwatson if (!mac_bsdextended_enabled) 439101099Srwatson return (0); 440101099Srwatson 441101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 442101099Srwatson if (error) 443101099Srwatson return (error); 444101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 445101099Srwatson} 446101099Srwatson 447101099Srwatsonstatic int 448104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 449104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 450104530Srwatson struct componentname *cnp) 451104530Srwatson{ 452104530Srwatson struct vattr vap; 453104530Srwatson int error; 454104530Srwatson 455104530Srwatson if (!mac_bsdextended_enabled) 456104530Srwatson return (0); 457104530Srwatson 458104530Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 459104530Srwatson if (error) 460104530Srwatson return (error); 461104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 462104530Srwatson if (error) 463104530Srwatson return (error); 464104530Srwatson 465104530Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 466104530Srwatson if (error) 467104530Srwatson return (error); 468104530Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 469104530Srwatson if (error) 470104530Srwatson return (error); 471104530Srwatson return (0); 472104530Srwatson} 473104530Srwatson 474104530Srwatsonstatic int 475101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 476101099Srwatson struct label *dlabel, struct componentname *cnp) 477101099Srwatson{ 478101099Srwatson struct vattr vap; 479101099Srwatson int error; 480101099Srwatson 481101099Srwatson if (!mac_bsdextended_enabled) 482101099Srwatson return (0); 483101099Srwatson 484101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 485101099Srwatson if (error) 486101099Srwatson return (error); 487101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VEXEC)); 488101099Srwatson} 489101099Srwatson 490101099Srwatsonstatic int 491101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 492101099Srwatson struct label *filelabel, mode_t acc_mode) 493101099Srwatson{ 494101099Srwatson struct vattr vap; 495101099Srwatson int error; 496101099Srwatson 497101099Srwatson if (!mac_bsdextended_enabled) 498101099Srwatson return (0); 499101099Srwatson 500101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 501101099Srwatson if (error) 502101099Srwatson return (error); 503101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 504101099Srwatson} 505101099Srwatson 506101099Srwatsonstatic int 507101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 508101099Srwatson struct label *dlabel) 509101099Srwatson{ 510101099Srwatson struct vattr vap; 511101099Srwatson int error; 512101099Srwatson 513101099Srwatson if (!mac_bsdextended_enabled) 514101099Srwatson return (0); 515101099Srwatson 516101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 517101099Srwatson if (error) 518101099Srwatson return (error); 519101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 520101099Srwatson} 521101099Srwatson 522101099Srwatsonstatic int 523101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 524101099Srwatson struct label *label) 525101099Srwatson{ 526101099Srwatson struct vattr vap; 527101099Srwatson int error; 528101099Srwatson 529101099Srwatson if (!mac_bsdextended_enabled) 530101099Srwatson return (0); 531101099Srwatson 532101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 533101099Srwatson if (error) 534101099Srwatson return (error); 535101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VREAD)); 536101099Srwatson} 537101099Srwatson 538101099Srwatsonstatic int 539101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 540101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 541101099Srwatson struct componentname *cnp) 542101099Srwatson{ 543101099Srwatson struct vattr vap; 544101099Srwatson int error; 545101099Srwatson 546101099Srwatson if (!mac_bsdextended_enabled) 547101099Srwatson return (0); 548101099Srwatson 549101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 550101099Srwatson if (error) 551101099Srwatson return (error); 552101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 553101099Srwatson if (error) 554101099Srwatson return (error); 555101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 556101099Srwatson if (error) 557101099Srwatson return (error); 558101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 559101099Srwatson 560101099Srwatson return (error); 561101099Srwatson} 562101099Srwatson 563101099Srwatsonstatic int 564101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 565101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 566101099Srwatson struct componentname *cnp) 567101099Srwatson{ 568101099Srwatson struct vattr vap; 569101099Srwatson int error; 570101099Srwatson 571101099Srwatson if (!mac_bsdextended_enabled) 572101099Srwatson return (0); 573101099Srwatson 574101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 575101099Srwatson if (error) 576101099Srwatson return (error); 577101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE); 578101099Srwatson if (error) 579101099Srwatson return (error); 580101099Srwatson 581101099Srwatson if (vp != NULL) { 582101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 583101099Srwatson if (error) 584101099Srwatson return (error); 585101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 586101099Srwatson VWRITE); 587101099Srwatson } 588101099Srwatson 589101099Srwatson return (error); 590101099Srwatson} 591101099Srwatson 592101099Srwatsonstatic int 593101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 594101099Srwatson struct label *label) 595101099Srwatson{ 596101099Srwatson struct vattr vap; 597101099Srwatson int error; 598101099Srwatson 599101099Srwatson if (!mac_bsdextended_enabled) 600101099Srwatson return (0); 601101099Srwatson 602101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 603101099Srwatson if (error) 604101099Srwatson return (error); 605101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 606101099Srwatson} 607101099Srwatson 608101099Srwatsonstatic int 609101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 610101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 611101099Srwatson{ 612101099Srwatson struct vattr vap; 613101099Srwatson int error; 614101099Srwatson 615101099Srwatson if (!mac_bsdextended_enabled) 616101099Srwatson return (0); 617101099Srwatson 618101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 619101099Srwatson if (error) 620101099Srwatson return (error); 621101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 622101099Srwatson} 623101099Srwatson 624101099Srwatsonstatic int 625101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 626101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 627101099Srwatson{ 628101099Srwatson struct vattr vap; 629101099Srwatson int error; 630101099Srwatson 631101099Srwatson if (!mac_bsdextended_enabled) 632101099Srwatson return (0); 633101099Srwatson 634101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 635101099Srwatson if (error) 636101099Srwatson return (error); 637101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VWRITE)); 638101099Srwatson} 639101099Srwatson 640101099Srwatsonstatic int 641101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 642101099Srwatson struct label *label, u_long flags) 643101099Srwatson{ 644101099Srwatson struct vattr vap; 645101099Srwatson int error; 646101099Srwatson 647101099Srwatson if (!mac_bsdextended_enabled) 648101099Srwatson return (0); 649101099Srwatson 650101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 651101099Srwatson if (error) 652101099Srwatson return (error); 653101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 654101099Srwatson} 655101099Srwatson 656101099Srwatsonstatic int 657101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 658101099Srwatson struct label *label, mode_t mode) 659101099Srwatson{ 660101099Srwatson struct vattr vap; 661101099Srwatson int error; 662101099Srwatson 663101099Srwatson if (!mac_bsdextended_enabled) 664101099Srwatson return (0); 665101099Srwatson 666101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 667101099Srwatson if (error) 668101099Srwatson return (error); 669101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 670101099Srwatson} 671101099Srwatson 672101099Srwatsonstatic int 673101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 674101099Srwatson struct label *label, uid_t uid, gid_t gid) 675101099Srwatson{ 676101099Srwatson struct vattr vap; 677101099Srwatson int error; 678101099Srwatson 679101099Srwatson if (!mac_bsdextended_enabled) 680101099Srwatson return (0); 681101099Srwatson 682101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 683101099Srwatson if (error) 684101099Srwatson return (error); 685101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 686101099Srwatson} 687101099Srwatson 688101099Srwatsonstatic int 689101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 690101099Srwatson struct label *label, struct timespec atime, struct timespec utime) 691101099Srwatson{ 692101099Srwatson struct vattr vap; 693101099Srwatson int error; 694101099Srwatson 695101099Srwatson if (!mac_bsdextended_enabled) 696101099Srwatson return (0); 697101099Srwatson 698101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 699101099Srwatson if (error) 700101099Srwatson return (error); 701101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, VADMIN)); 702101099Srwatson} 703101099Srwatson 704101099Srwatsonstatic int 705102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 706102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 707101099Srwatson{ 708101099Srwatson struct vattr vap; 709101099Srwatson int error; 710101099Srwatson 711101099Srwatson if (!mac_bsdextended_enabled) 712101099Srwatson return (0); 713101099Srwatson 714102129Srwatson error = VOP_GETATTR(vp, &vap, active_cred, curthread); 715101099Srwatson if (error) 716101099Srwatson return (error); 717102129Srwatson return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 718102129Srwatson VSTAT)); 719101099Srwatson} 720101099Srwatson 721101099Srwatsonstatic struct mac_policy_op_entry mac_bsdextended_ops[] = 722101099Srwatson{ 723101099Srwatson { MAC_DESTROY, 724101099Srwatson (macop_t)mac_bsdextended_destroy }, 725101099Srwatson { MAC_INIT, 726101099Srwatson (macop_t)mac_bsdextended_init }, 727101099Srwatson { MAC_CHECK_VNODE_ACCESS, 728101099Srwatson (macop_t)mac_bsdextended_check_vnode_access }, 729101099Srwatson { MAC_CHECK_VNODE_CHDIR, 730101099Srwatson (macop_t)mac_bsdextended_check_vnode_chdir }, 731101099Srwatson { MAC_CHECK_VNODE_CHROOT, 732101099Srwatson (macop_t)mac_bsdextended_check_vnode_chroot }, 733101099Srwatson { MAC_CHECK_VNODE_CREATE, 734101099Srwatson (macop_t)mac_bsdextended_check_create_vnode }, 735101099Srwatson { MAC_CHECK_VNODE_DELETE, 736101099Srwatson (macop_t)mac_bsdextended_check_vnode_delete }, 737101099Srwatson { MAC_CHECK_VNODE_DELETEACL, 738101099Srwatson (macop_t)mac_bsdextended_check_vnode_deleteacl }, 739101099Srwatson { MAC_CHECK_VNODE_EXEC, 740101099Srwatson (macop_t)mac_bsdextended_check_vnode_exec }, 741101099Srwatson { MAC_CHECK_VNODE_GETACL, 742101099Srwatson (macop_t)mac_bsdextended_check_vnode_getacl }, 743101099Srwatson { MAC_CHECK_VNODE_GETEXTATTR, 744101099Srwatson (macop_t)mac_bsdextended_check_vnode_getextattr }, 745104530Srwatson { MAC_CHECK_VNODE_LINK, 746104530Srwatson (macop_t)mac_bsdextended_check_vnode_link }, 747101099Srwatson { MAC_CHECK_VNODE_LOOKUP, 748101099Srwatson (macop_t)mac_bsdextended_check_vnode_lookup }, 749101099Srwatson { MAC_CHECK_VNODE_OPEN, 750101099Srwatson (macop_t)mac_bsdextended_check_vnode_open }, 751101099Srwatson { MAC_CHECK_VNODE_READDIR, 752101099Srwatson (macop_t)mac_bsdextended_check_vnode_readdir }, 753101099Srwatson { MAC_CHECK_VNODE_READLINK, 754101099Srwatson (macop_t)mac_bsdextended_check_vnode_readdlink }, 755101099Srwatson { MAC_CHECK_VNODE_RENAME_FROM, 756101099Srwatson (macop_t)mac_bsdextended_check_vnode_rename_from }, 757101099Srwatson { MAC_CHECK_VNODE_RENAME_TO, 758101099Srwatson (macop_t)mac_bsdextended_check_vnode_rename_to }, 759101099Srwatson { MAC_CHECK_VNODE_REVOKE, 760101099Srwatson (macop_t)mac_bsdextended_check_vnode_revoke }, 761101099Srwatson { MAC_CHECK_VNODE_SETACL, 762101099Srwatson (macop_t)mac_bsdextended_check_setacl_vnode }, 763101099Srwatson { MAC_CHECK_VNODE_SETEXTATTR, 764101099Srwatson (macop_t)mac_bsdextended_check_vnode_setextattr }, 765101099Srwatson { MAC_CHECK_VNODE_SETFLAGS, 766101099Srwatson (macop_t)mac_bsdextended_check_vnode_setflags }, 767101099Srwatson { MAC_CHECK_VNODE_SETMODE, 768101099Srwatson (macop_t)mac_bsdextended_check_vnode_setmode }, 769101099Srwatson { MAC_CHECK_VNODE_SETOWNER, 770101099Srwatson (macop_t)mac_bsdextended_check_vnode_setowner }, 771101099Srwatson { MAC_CHECK_VNODE_SETUTIMES, 772101099Srwatson (macop_t)mac_bsdextended_check_vnode_setutimes }, 773101099Srwatson { MAC_CHECK_VNODE_STAT, 774101099Srwatson (macop_t)mac_bsdextended_check_vnode_stat }, 775101099Srwatson { MAC_OP_LAST, NULL } 776101099Srwatson}; 777101099Srwatson 778101099SrwatsonMAC_POLICY_SET(mac_bsdextended_ops, trustedbsd_mac_bsdextended, 779101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 780