ugidfw_system.c revision 136739
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 136739 2004-10-21 11:19:02Z 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> 61134132Strhodes#include <sys/syslog.h> 62101099Srwatson 63101099Srwatson#include <net/bpfdesc.h> 64101099Srwatson#include <net/if.h> 65101099Srwatson#include <net/if_types.h> 66101099Srwatson#include <net/if_var.h> 67101099Srwatson 68101099Srwatson#include <vm/vm.h> 69101099Srwatson 70101099Srwatson#include <sys/mac_policy.h> 71101099Srwatson 72101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 73101099Srwatson 74101099SrwatsonSYSCTL_DECL(_security_mac); 75101099Srwatson 76101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 77101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 78101099Srwatson 79101099Srwatsonstatic int mac_bsdextended_enabled = 1; 80101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 81101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 82101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 83101099Srwatson 84101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 85101099Srwatson 86101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 87101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 88101099Srwatsonstatic int rule_count = 0; 89101099Srwatsonstatic int rule_slots = 0; 90101099Srwatson 91101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 92101099Srwatson &rule_count, 0, "Number of defined rules\n"); 93101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 94101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 95101099Srwatson 96134132Strhodes/* 97134132Strhodes * This is just used for logging purposes as eventually we would like 98134132Strhodes * to log much more then failed requests. 99134132Strhodes */ 100134132Strhodesstatic int mac_bsdextended_logging; 101134132StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 102134132Strhodes &mac_bsdextended_logging, 0, "Log failed authorization requests"); 103134132Strhodes 104134132Strhodes/* 105134131Strhodes * This tunable is here for compatibility. It will allow the user 106134131Strhodes * to switch between the new mode (first rule matches) and the old 107134131Strhodes * functionality (all rules match). 108134131Strhodes */ 109101099Srwatsonstatic int 110134131Strhodesmac_bsdextended_firstmatch_enabled; 111134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 112135039Strhodes CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 113134131Strhodes "Disable/enable match first rule functionality"); 114134131Strhodes 115134131Strhodesstatic int 116101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 117101099Srwatson{ 118101099Srwatson 119101099Srwatson if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 120101099Srwatson return (EINVAL); 121101099Srwatson 122101099Srwatson if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 123101099Srwatson return (EINVAL); 124101099Srwatson 125136739Srwatson if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 126101099Srwatson return (EINVAL); 127101099Srwatson 128101099Srwatson return (0); 129101099Srwatson} 130101099Srwatson 131101099Srwatsonstatic int 132101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 133101099Srwatson{ 134101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 135101099Srwatson u_int namelen; 136101099Srwatson int error, index, *name; 137101099Srwatson 138101099Srwatson name = (int *)arg1; 139101099Srwatson namelen = arg2; 140101099Srwatson 141101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 142101099Srwatson 143101099Srwatson if (namelen != 1) 144101099Srwatson return (EINVAL); 145101099Srwatson 146101099Srwatson index = name[0]; 147101099Srwatson if (index < 0 || index > rule_slots + 1) 148101099Srwatson return (ENOENT); 149101099Srwatson if (rule_slots >= MAC_BSDEXTENDED_MAXRULES) 150101099Srwatson return (ENOENT); 151101099Srwatson 152101099Srwatson if (req->oldptr) { 153101099Srwatson if (rules[index] == NULL) 154101099Srwatson return (ENOENT); 155101099Srwatson 156101099Srwatson error = SYSCTL_OUT(req, rules[index], sizeof(*rules[index])); 157101099Srwatson if (error) 158101099Srwatson return (error); 159101099Srwatson } 160101099Srwatson 161101099Srwatson if (req->newptr) { 162101099Srwatson if (req->newlen == 0) { 163101099Srwatson /* printf("deletion\n"); */ 164101099Srwatson ruleptr = rules[index]; 165101099Srwatson if (ruleptr == NULL) 166101099Srwatson return (ENOENT); 167101099Srwatson rule_count--; 168101099Srwatson rules[index] = NULL; 169101099Srwatson FREE(ruleptr, M_MACBSDEXTENDED); 170101099Srwatson return(0); 171101099Srwatson } 172101099Srwatson error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 173101099Srwatson if (error) 174101099Srwatson return (error); 175101099Srwatson 176101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 177101099Srwatson if (error) 178101099Srwatson return (error); 179101099Srwatson 180101099Srwatson if (rules[index] == NULL) { 181101099Srwatson /* printf("addition\n"); */ 182101099Srwatson MALLOC(ruleptr, struct mac_bsdextended_rule *, 183111119Simp sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | 184101099Srwatson M_ZERO); 185101099Srwatson *ruleptr = temprule; 186101099Srwatson rules[index] = ruleptr; 187101099Srwatson if (index+1 > rule_slots) 188101099Srwatson rule_slots = index+1; 189101099Srwatson rule_count++; 190101099Srwatson } else { 191101099Srwatson /* printf("replacement\n"); */ 192101099Srwatson *rules[index] = temprule; 193101099Srwatson } 194101099Srwatson } 195101099Srwatson 196101099Srwatson return (0); 197101099Srwatson} 198101099Srwatson 199101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 200101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 201101099Srwatson 202101099Srwatsonstatic void 203101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 204101099Srwatson{ 205101099Srwatson 206101099Srwatson /* Initialize ruleset lock. */ 207101099Srwatson /* Register dynamic sysctl's for rules. */ 208101099Srwatson} 209101099Srwatson 210101099Srwatsonstatic void 211101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 212101099Srwatson{ 213101099Srwatson 214101099Srwatson /* Tear down sysctls. */ 215101099Srwatson /* Destroy ruleset lock. */ 216101099Srwatson} 217101099Srwatson 218101099Srwatsonstatic int 219101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 220106212Srwatson struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 221101099Srwatson{ 222101099Srwatson int match; 223101099Srwatson 224101099Srwatson /* 225101099Srwatson * Is there a subject match? 226101099Srwatson */ 227101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 228101099Srwatson match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 229101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_ruid || 230101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_svuid); 231101099Srwatson 232101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 233101099Srwatson match = !match; 234101099Srwatson 235101099Srwatson if (!match) 236101099Srwatson return (0); 237101099Srwatson } 238101099Srwatson 239101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 240101099Srwatson match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 241101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_rgid || 242101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_svgid); 243101099Srwatson 244101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 245101099Srwatson match = !match; 246101099Srwatson 247101099Srwatson if (!match) 248101099Srwatson return (0); 249101099Srwatson } 250101099Srwatson 251101099Srwatson /* 252101099Srwatson * Is there an object match? 253101099Srwatson */ 254101099Srwatson if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 255101099Srwatson match = (rule->mbr_object.mbi_uid == object_uid); 256101099Srwatson 257101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 258101099Srwatson match = !match; 259101099Srwatson 260101099Srwatson if (!match) 261101099Srwatson return (0); 262101099Srwatson } 263101099Srwatson 264101099Srwatson if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 265101099Srwatson match = (rule->mbr_object.mbi_gid == object_gid); 266101099Srwatson 267101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 268101099Srwatson match = !match; 269101099Srwatson 270101099Srwatson if (!match) 271101099Srwatson return (0); 272101099Srwatson } 273101099Srwatson 274101099Srwatson /* 275101099Srwatson * Is the access permitted? 276101099Srwatson */ 277101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 278134132Strhodes if (mac_bsdextended_logging) 279134132Strhodes log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 280134132Strhodes " on %d:%d failed. \n", cred->cr_ruid, 281134132Strhodes cred->cr_rgid, acc_mode, object_uid, object_gid); 282134132Strhodes return (EACCES); /* Matching rule denies access */ 283101099Srwatson } 284134131Strhodes /* 285134131Strhodes * If the rule matched and allowed access and first match is 286134131Strhodes * enabled, then return success. 287134131Strhodes */ 288134131Strhodes if (mac_bsdextended_firstmatch_enabled) 289134131Strhodes return (EJUSTRETURN); 290134131Strhodes else 291134131Strhodes return(0); 292101099Srwatson} 293101099Srwatson 294101099Srwatsonstatic int 295101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 296106212Srwatson int acc_mode) 297101099Srwatson{ 298101099Srwatson int error, i; 299101099Srwatson 300132563Srwatson if (suser_cred(cred, 0) == 0) 301132563Srwatson return (0); 302132563Srwatson 303101099Srwatson for (i = 0; i < rule_slots; i++) { 304101099Srwatson if (rules[i] == NULL) 305101099Srwatson continue; 306101099Srwatson 307108376Srwatson /* 308108376Srwatson * Since we don't separately handle append, map append to 309108376Srwatson * write. 310108376Srwatson */ 311136739Srwatson if (acc_mode & MBI_APPEND) { 312136739Srwatson acc_mode &= ~MBI_APPEND; 313136739Srwatson acc_mode |= MBI_WRITE; 314108376Srwatson } 315108376Srwatson 316101099Srwatson error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 317101099Srwatson object_gid, acc_mode); 318134131Strhodes if (error == EJUSTRETURN) 319134131Strhodes break; 320101099Srwatson if (error) 321101099Srwatson return (error); 322101099Srwatson } 323101099Srwatson 324101099Srwatson return (0); 325101099Srwatson} 326101099Srwatson 327101099Srwatsonstatic int 328112575Srwatsonmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 329112575Srwatson struct label *label) 330112575Srwatson{ 331112575Srwatson struct vattr vap; 332112575Srwatson int error; 333112575Srwatson 334112575Srwatson if (!mac_bsdextended_enabled) 335112575Srwatson return (0); 336112575Srwatson 337112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 338112575Srwatson if (error) 339112575Srwatson return (error); 340136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 341136739Srwatson MBI_WRITE)); 342112575Srwatson} 343112575Srwatson 344112575Srwatsonstatic int 345101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 346106212Srwatson struct label *label, int acc_mode) 347101099Srwatson{ 348101099Srwatson struct vattr vap; 349101099Srwatson int error; 350101099Srwatson 351101099Srwatson if (!mac_bsdextended_enabled) 352101099Srwatson return (0); 353101099Srwatson 354101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 355101099Srwatson if (error) 356101099Srwatson return (error); 357106212Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 358101099Srwatson} 359101099Srwatson 360101099Srwatsonstatic int 361101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 362101099Srwatson struct label *dlabel) 363101099Srwatson{ 364101099Srwatson struct vattr vap; 365101099Srwatson int error; 366101099Srwatson 367101099Srwatson if (!mac_bsdextended_enabled) 368101099Srwatson return (0); 369101099Srwatson 370101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 371101099Srwatson if (error) 372101099Srwatson return (error); 373136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 374136739Srwatson MBI_EXEC)); 375101099Srwatson} 376101099Srwatson 377101099Srwatsonstatic int 378101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 379101099Srwatson struct label *dlabel) 380101099Srwatson{ 381101099Srwatson struct vattr vap; 382101099Srwatson int error; 383101099Srwatson 384101099Srwatson if (!mac_bsdextended_enabled) 385101099Srwatson return (0); 386101099Srwatson 387101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 388101099Srwatson if (error) 389101099Srwatson return (error); 390136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 391136739Srwatson MBI_EXEC)); 392101099Srwatson} 393101099Srwatson 394101099Srwatsonstatic int 395101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 396101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 397101099Srwatson{ 398101099Srwatson struct vattr dvap; 399101099Srwatson int error; 400101099Srwatson 401101099Srwatson if (!mac_bsdextended_enabled) 402101099Srwatson return (0); 403101099Srwatson 404101099Srwatson error = VOP_GETATTR(dvp, &dvap, cred, curthread); 405101099Srwatson if (error) 406101099Srwatson return (error); 407136739Srwatson return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, 408136739Srwatson MBI_WRITE)); 409101099Srwatson} 410101099Srwatson 411101099Srwatsonstatic int 412101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 413101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 414101099Srwatson struct componentname *cnp) 415101099Srwatson{ 416101099Srwatson struct vattr vap; 417101099Srwatson int error; 418101099Srwatson 419101099Srwatson if (!mac_bsdextended_enabled) 420101099Srwatson return (0); 421101099Srwatson 422101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 423101099Srwatson if (error) 424101099Srwatson return (error); 425136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 426136739Srwatson MBI_WRITE); 427101099Srwatson if (error) 428101099Srwatson return (error); 429101099Srwatson 430101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 431101099Srwatson if (error) 432101099Srwatson return (error); 433136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 434136739Srwatson MBI_WRITE)); 435101099Srwatson} 436101099Srwatson 437101099Srwatsonstatic int 438101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 439101099Srwatson struct label *label, acl_type_t type) 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); 448117247Srwatson if (error) 449101099Srwatson return (error); 450136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 451136739Srwatson MBI_ADMIN)); 452101099Srwatson} 453101099Srwatson 454101099Srwatsonstatic int 455119202Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 456119202Srwatson struct label *label, int attrnamespace, const char *name) 457119202Srwatson{ 458119202Srwatson struct vattr vap; 459119202Srwatson int error; 460119202Srwatson 461119202Srwatson if (!mac_bsdextended_enabled) 462119202Srwatson return (0); 463119202Srwatson 464119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 465119202Srwatson if (error) 466119202Srwatson return (error); 467136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 468136739Srwatson MBI_WRITE)); 469119202Srwatson} 470119202Srwatson 471119202Srwatsonstatic int 472101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 473106648Srwatson struct label *label, struct image_params *imgp, 474106648Srwatson struct label *execlabel) 475101099Srwatson{ 476101099Srwatson struct vattr vap; 477101099Srwatson int error; 478101099Srwatson 479101099Srwatson if (!mac_bsdextended_enabled) 480101099Srwatson return (0); 481101099Srwatson 482101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 483101099Srwatson if (error) 484101099Srwatson return (error); 485101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 486136739Srwatson MBI_READ|MBI_EXEC)); 487101099Srwatson} 488101099Srwatson 489101099Srwatsonstatic int 490101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 491101099Srwatson struct label *label, acl_type_t type) 492101099Srwatson{ 493101099Srwatson struct vattr vap; 494101099Srwatson int error; 495101099Srwatson 496101099Srwatson if (!mac_bsdextended_enabled) 497101099Srwatson return (0); 498101099Srwatson 499101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 500101099Srwatson if (error) 501101099Srwatson return (error); 502136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 503136739Srwatson MBI_STAT)); 504101099Srwatson} 505101099Srwatson 506101099Srwatsonstatic int 507101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 508101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 509101099Srwatson{ 510101099Srwatson struct vattr vap; 511101099Srwatson int error; 512101099Srwatson 513101099Srwatson if (!mac_bsdextended_enabled) 514101099Srwatson return (0); 515101099Srwatson 516101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 517101099Srwatson if (error) 518101099Srwatson return (error); 519136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 520136739Srwatson MBI_READ)); 521101099Srwatson} 522101099Srwatson 523101099Srwatsonstatic int 524104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 525104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 526104530Srwatson struct componentname *cnp) 527104530Srwatson{ 528104530Srwatson struct vattr vap; 529104530Srwatson int error; 530104530Srwatson 531104530Srwatson if (!mac_bsdextended_enabled) 532104530Srwatson return (0); 533104530Srwatson 534104530Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 535104530Srwatson if (error) 536104530Srwatson return (error); 537136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 538136739Srwatson MBI_WRITE); 539106214Srwatson if (error) 540106214Srwatson return (error); 541104530Srwatson 542104530Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 543104530Srwatson if (error) 544104530Srwatson return (error); 545136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 546136739Srwatson MBI_WRITE); 547104530Srwatson if (error) 548104530Srwatson return (error); 549104530Srwatson return (0); 550104530Srwatson} 551104530Srwatson 552104530Srwatsonstatic int 553119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 554119202Srwatson struct label *label, int attrnamespace) 555119202Srwatson{ 556119202Srwatson struct vattr vap; 557119202Srwatson int error; 558119202Srwatson 559119202Srwatson if (!mac_bsdextended_enabled) 560119202Srwatson return (0); 561119202Srwatson 562119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 563119202Srwatson if (error) 564119202Srwatson return (error); 565136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 566136739Srwatson MBI_READ)); 567119202Srwatson} 568119202Srwatson 569119202Srwatsonstatic int 570101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 571101099Srwatson struct label *dlabel, struct componentname *cnp) 572101099Srwatson{ 573101099Srwatson struct vattr vap; 574101099Srwatson int error; 575117247Srwatson 576101099Srwatson if (!mac_bsdextended_enabled) 577101099Srwatson return (0); 578117247Srwatson 579101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 580101099Srwatson if (error) 581101099Srwatson return (error); 582136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 583136739Srwatson MBI_EXEC)); 584101099Srwatson} 585101099Srwatson 586101099Srwatsonstatic int 587101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 588106212Srwatson struct label *filelabel, int acc_mode) 589101099Srwatson{ 590101099Srwatson struct vattr vap; 591101099Srwatson int error; 592101099Srwatson 593101099Srwatson if (!mac_bsdextended_enabled) 594101099Srwatson return (0); 595101099Srwatson 596101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 597101099Srwatson if (error) 598101099Srwatson return (error); 599101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 600101099Srwatson} 601101099Srwatson 602101099Srwatsonstatic int 603101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 604101099Srwatson struct label *dlabel) 605101099Srwatson{ 606101099Srwatson struct vattr vap; 607101099Srwatson int error; 608101099Srwatson 609101099Srwatson if (!mac_bsdextended_enabled) 610101099Srwatson return (0); 611101099Srwatson 612101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 613101099Srwatson if (error) 614101099Srwatson return (error); 615136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 616136739Srwatson MBI_READ)); 617101099Srwatson} 618101099Srwatson 619101099Srwatsonstatic int 620101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 621101099Srwatson struct label *label) 622101099Srwatson{ 623101099Srwatson struct vattr vap; 624101099Srwatson int error; 625101099Srwatson 626101099Srwatson if (!mac_bsdextended_enabled) 627101099Srwatson return (0); 628101099Srwatson 629101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 630101099Srwatson if (error) 631101099Srwatson return (error); 632136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 633136739Srwatson MBI_READ)); 634101099Srwatson} 635101099Srwatson 636101099Srwatsonstatic int 637101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 638101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 639101099Srwatson struct componentname *cnp) 640101099Srwatson{ 641101099Srwatson struct vattr vap; 642101099Srwatson int error; 643101099Srwatson 644101099Srwatson if (!mac_bsdextended_enabled) 645101099Srwatson return (0); 646101099Srwatson 647101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 648101099Srwatson if (error) 649101099Srwatson return (error); 650136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 651136739Srwatson MBI_WRITE); 652101099Srwatson if (error) 653101099Srwatson return (error); 654101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 655101099Srwatson if (error) 656101099Srwatson return (error); 657136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 658136739Srwatson MBI_WRITE); 659101099Srwatson 660101099Srwatson return (error); 661101099Srwatson} 662101099Srwatson 663101099Srwatsonstatic int 664101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 665101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 666101099Srwatson struct componentname *cnp) 667101099Srwatson{ 668101099Srwatson struct vattr vap; 669101099Srwatson int error; 670101099Srwatson 671101099Srwatson if (!mac_bsdextended_enabled) 672101099Srwatson return (0); 673101099Srwatson 674101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 675101099Srwatson if (error) 676101099Srwatson return (error); 677136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 678136739Srwatson MBI_WRITE); 679101099Srwatson if (error) 680101099Srwatson return (error); 681101099Srwatson 682101099Srwatson if (vp != NULL) { 683101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 684101099Srwatson if (error) 685101099Srwatson return (error); 686101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 687136739Srwatson MBI_WRITE); 688101099Srwatson } 689101099Srwatson 690101099Srwatson return (error); 691101099Srwatson} 692101099Srwatson 693101099Srwatsonstatic int 694101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 695101099Srwatson struct label *label) 696101099Srwatson{ 697101099Srwatson struct vattr vap; 698101099Srwatson int error; 699101099Srwatson 700101099Srwatson if (!mac_bsdextended_enabled) 701101099Srwatson return (0); 702101099Srwatson 703101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 704101099Srwatson if (error) 705101099Srwatson return (error); 706136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 707136739Srwatson MBI_ADMIN)); 708101099Srwatson} 709101099Srwatson 710101099Srwatsonstatic int 711101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 712101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 713101099Srwatson{ 714101099Srwatson struct vattr vap; 715101099Srwatson int error; 716101099Srwatson 717101099Srwatson if (!mac_bsdextended_enabled) 718101099Srwatson return (0); 719101099Srwatson 720101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 721101099Srwatson if (error) 722101099Srwatson return (error); 723136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 724136739Srwatson MBI_ADMIN)); 725101099Srwatson} 726101099Srwatson 727101099Srwatsonstatic int 728101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 729101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 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); 740136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 741136739Srwatson MBI_WRITE)); 742101099Srwatson} 743101099Srwatson 744101099Srwatsonstatic int 745101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 746101099Srwatson struct label *label, u_long flags) 747101099Srwatson{ 748101099Srwatson struct vattr vap; 749101099Srwatson int error; 750101099Srwatson 751101099Srwatson if (!mac_bsdextended_enabled) 752101099Srwatson return (0); 753101099Srwatson 754101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 755101099Srwatson if (error) 756101099Srwatson return (error); 757136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 758136739Srwatson MBI_ADMIN)); 759101099Srwatson} 760101099Srwatson 761101099Srwatsonstatic int 762101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 763101099Srwatson struct label *label, mode_t mode) 764101099Srwatson{ 765101099Srwatson struct vattr vap; 766101099Srwatson int error; 767101099Srwatson 768101099Srwatson if (!mac_bsdextended_enabled) 769101099Srwatson return (0); 770101099Srwatson 771101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 772101099Srwatson if (error) 773101099Srwatson return (error); 774136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 775136739Srwatson MBI_ADMIN)); 776101099Srwatson} 777101099Srwatson 778101099Srwatsonstatic int 779101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 780101099Srwatson struct label *label, uid_t uid, gid_t gid) 781101099Srwatson{ 782101099Srwatson struct vattr vap; 783101099Srwatson int error; 784101099Srwatson 785101099Srwatson if (!mac_bsdextended_enabled) 786101099Srwatson return (0); 787101099Srwatson 788101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 789101099Srwatson if (error) 790101099Srwatson return (error); 791136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 792136739Srwatson MBI_ADMIN)); 793101099Srwatson} 794101099Srwatson 795101099Srwatsonstatic int 796101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 797101099Srwatson struct label *label, struct timespec atime, struct timespec utime) 798101099Srwatson{ 799101099Srwatson struct vattr vap; 800101099Srwatson int error; 801101099Srwatson 802101099Srwatson if (!mac_bsdextended_enabled) 803101099Srwatson return (0); 804101099Srwatson 805101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 806101099Srwatson if (error) 807101099Srwatson return (error); 808136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 809136739Srwatson MBI_ADMIN)); 810101099Srwatson} 811101099Srwatson 812101099Srwatsonstatic int 813102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 814102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 815101099Srwatson{ 816101099Srwatson struct vattr vap; 817101099Srwatson int error; 818101099Srwatson 819101099Srwatson if (!mac_bsdextended_enabled) 820101099Srwatson return (0); 821101099Srwatson 822102129Srwatson error = VOP_GETATTR(vp, &vap, active_cred, curthread); 823101099Srwatson if (error) 824101099Srwatson return (error); 825102129Srwatson return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 826136739Srwatson MBI_STAT)); 827101099Srwatson} 828101099Srwatson 829106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 830101099Srwatson{ 831106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 832106217Srwatson .mpo_init = mac_bsdextended_init, 833112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 834106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 835106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 836106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 837106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 838106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 839106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 840119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 841106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 842106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 843106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 844106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 845119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 846106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 847106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 848106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 849106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 850106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 851106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 852106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 853106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 854106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 855106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 856106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 857106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 858106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 859106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 860101099Srwatson}; 861101099Srwatson 862112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 863101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 864