ugidfw_system.c revision 145412
1101099Srwatson/*- 2145412Strhodes * Copyright (c) 2005 Tom Rhodes 3126097Srwatson * Copyright (c) 1999-2002 Robert N. M. Watson 4145412Strhodes * Copyright (c) 2001-2005 Networks Associates Technology, Inc. 5101099Srwatson * All rights reserved. 6101099Srwatson * 7101099Srwatson * This software was developed by Robert Watson for the TrustedBSD Project. 8145412Strhodes * It was later enhanced by Tom Rhodes for the TrustedBSD Project. 9101099Srwatson * 10106393Srwatson * This software was developed for the FreeBSD Project in part by Network 11106393Srwatson * Associates Laboratories, the Security Research Division of Network 12106393Srwatson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 13106393Srwatson * as part of the DARPA CHATS research program. 14101099Srwatson * 15101099Srwatson * Redistribution and use in source and binary forms, with or without 16101099Srwatson * modification, are permitted provided that the following conditions 17101099Srwatson * are met: 18101099Srwatson * 1. Redistributions of source code must retain the above copyright 19101099Srwatson * notice, this list of conditions and the following disclaimer. 20101099Srwatson * 2. Redistributions in binary form must reproduce the above copyright 21101099Srwatson * notice, this list of conditions and the following disclaimer in the 22101099Srwatson * documentation and/or other materials provided with the distribution. 23101099Srwatson * 24101099Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25101099Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26101099Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27101099Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28101099Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29101099Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30101099Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31101099Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32101099Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33101099Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34101099Srwatson * SUCH DAMAGE. 35101099Srwatson * 36101099Srwatson * $FreeBSD: head/sys/security/mac_bsdextended/mac_bsdextended.c 145412 2005-04-22 18:49:30Z trhodes $ 37101099Srwatson */ 38136774Srwatson 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 45101099Srwatson#include <sys/types.h> 46101099Srwatson#include <sys/param.h> 47101099Srwatson#include <sys/acl.h> 48101099Srwatson#include <sys/conf.h> 49101099Srwatson#include <sys/kernel.h> 50145412Strhodes#include <sys/lock.h> 51101099Srwatson#include <sys/mac.h> 52101099Srwatson#include <sys/malloc.h> 53101099Srwatson#include <sys/mount.h> 54145412Strhodes#include <sys/mutex.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> 64134132Strhodes#include <sys/syslog.h> 65101099Srwatson 66101099Srwatson#include <net/bpfdesc.h> 67101099Srwatson#include <net/if.h> 68101099Srwatson#include <net/if_types.h> 69101099Srwatson#include <net/if_var.h> 70101099Srwatson 71101099Srwatson#include <vm/vm.h> 72101099Srwatson 73101099Srwatson#include <sys/mac_policy.h> 74101099Srwatson 75101099Srwatson#include <security/mac_bsdextended/mac_bsdextended.h> 76101099Srwatson 77145412Strhodesstatic struct mtx mac_bsdextended_mtx; 78145412Strhodes 79101099SrwatsonSYSCTL_DECL(_security_mac); 80101099Srwatson 81101099SrwatsonSYSCTL_NODE(_security_mac, OID_AUTO, bsdextended, CTLFLAG_RW, 0, 82101099Srwatson "TrustedBSD extended BSD MAC policy controls"); 83101099Srwatson 84101099Srwatsonstatic int mac_bsdextended_enabled = 1; 85101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, enabled, CTLFLAG_RW, 86101099Srwatson &mac_bsdextended_enabled, 0, "Enforce extended BSD policy"); 87101099SrwatsonTUNABLE_INT("security.mac.bsdextended.enabled", &mac_bsdextended_enabled); 88101099Srwatson 89101099SrwatsonMALLOC_DEFINE(M_MACBSDEXTENDED, "mac_bsdextended", "BSD Extended MAC rule"); 90101099Srwatson 91101099Srwatson#define MAC_BSDEXTENDED_MAXRULES 250 92101099Srwatsonstatic struct mac_bsdextended_rule *rules[MAC_BSDEXTENDED_MAXRULES]; 93101099Srwatsonstatic int rule_count = 0; 94101099Srwatsonstatic int rule_slots = 0; 95101099Srwatson 96101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_count, CTLFLAG_RD, 97101099Srwatson &rule_count, 0, "Number of defined rules\n"); 98101099SrwatsonSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, rule_slots, CTLFLAG_RD, 99101099Srwatson &rule_slots, 0, "Number of used rule slots\n"); 100101099Srwatson 101134132Strhodes/* 102145412Strhodes * This is just used for logging purposes, eventually we would like 103134132Strhodes * to log much more then failed requests. 104134132Strhodes */ 105134132Strhodesstatic int mac_bsdextended_logging; 106134132StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, logging, CTLFLAG_RW, 107134132Strhodes &mac_bsdextended_logging, 0, "Log failed authorization requests"); 108134132Strhodes 109134132Strhodes/* 110134131Strhodes * This tunable is here for compatibility. It will allow the user 111134131Strhodes * to switch between the new mode (first rule matches) and the old 112134131Strhodes * functionality (all rules match). 113134131Strhodes */ 114101099Srwatsonstatic int 115134131Strhodesmac_bsdextended_firstmatch_enabled; 116134131StrhodesSYSCTL_INT(_security_mac_bsdextended, OID_AUTO, firstmatch_enabled, 117135039Strhodes CTLFLAG_RW, &mac_bsdextended_firstmatch_enabled, 1, 118134131Strhodes "Disable/enable match first rule functionality"); 119134131Strhodes 120134131Strhodesstatic int 121101099Srwatsonmac_bsdextended_rule_valid(struct mac_bsdextended_rule *rule) 122101099Srwatson{ 123101099Srwatson 124101099Srwatson if ((rule->mbr_subject.mbi_flags | MBI_BITS) != MBI_BITS) 125101099Srwatson return (EINVAL); 126101099Srwatson 127101099Srwatson if ((rule->mbr_object.mbi_flags | MBI_BITS) != MBI_BITS) 128101099Srwatson return (EINVAL); 129101099Srwatson 130136739Srwatson if ((rule->mbr_mode | MBI_ALLPERM) != MBI_ALLPERM) 131101099Srwatson return (EINVAL); 132101099Srwatson 133101099Srwatson return (0); 134101099Srwatson} 135101099Srwatson 136101099Srwatsonstatic int 137101099Srwatsonsysctl_rule(SYSCTL_HANDLER_ARGS) 138101099Srwatson{ 139101099Srwatson struct mac_bsdextended_rule temprule, *ruleptr; 140101099Srwatson u_int namelen; 141101099Srwatson int error, index, *name; 142101099Srwatson 143145412Strhodes error = 0; 144101099Srwatson name = (int *)arg1; 145101099Srwatson namelen = arg2; 146101099Srwatson 147101099Srwatson /* printf("bsdextended sysctl handler (namelen %d)\n", namelen); */ 148101099Srwatson 149101099Srwatson if (namelen != 1) 150101099Srwatson return (EINVAL); 151101099Srwatson 152101099Srwatson index = name[0]; 153145412Strhodes if (index > MAC_BSDEXTENDED_MAXRULES) 154101099Srwatson return (ENOENT); 155101099Srwatson 156145412Strhodes ruleptr = NULL; 157145412Strhodes if (req->newptr && req->newlen != 0) { 158145412Strhodes error = SYSCTL_IN(req, &temprule, sizeof(temprule)); 159101099Srwatson if (error) 160101099Srwatson return (error); 161145412Strhodes MALLOC(ruleptr, struct mac_bsdextended_rule *, 162145412Strhodes sizeof(*ruleptr), M_MACBSDEXTENDED, M_WAITOK | M_ZERO); 163101099Srwatson } 164101099Srwatson 165145412Strhodes mtx_lock(&mac_bsdextended_mtx); 166145412Strhodes 167145412Strhodes if (req->oldptr) { 168145412Strhodes if (index < 0 || index > rule_slots + 1) { 169145412Strhodes error = ENOENT; 170145412Strhodes goto out; 171101099Srwatson } 172145412Strhodes if (rules[index] == NULL) { 173145412Strhodes error = ENOENT; 174145412Strhodes goto out; 175145412Strhodes } 176145412Strhodes temprule = *rules[index]; 177145412Strhodes } 178101099Srwatson 179145412Strhodes if (req->newptr && req->newlen == 0) { 180145412Strhodes /* printf("deletion\n"); */ 181145412Strhodes KASSERT(ruleptr == NULL, ("sysctl_rule: ruleptr != NULL")); 182145412Strhodes ruleptr = rules[index]; 183145412Strhodes if (ruleptr == NULL) { 184145412Strhodes error = ENOENT; 185145412Strhodes goto out; 186145412Strhodes } 187145412Strhodes rule_count--; 188145412Strhodes rules[index] = NULL; 189145412Strhodes } else if (req->newptr) { 190101099Srwatson error = mac_bsdextended_rule_valid(&temprule); 191101099Srwatson if (error) 192145412Strhodes goto out; 193101099Srwatson 194101099Srwatson if (rules[index] == NULL) { 195101099Srwatson /* printf("addition\n"); */ 196101099Srwatson *ruleptr = temprule; 197101099Srwatson rules[index] = ruleptr; 198145412Strhodes ruleptr = NULL; 199145412Strhodes if (index + 1 > rule_slots) 200145412Strhodes rule_slots = index + 1; 201101099Srwatson rule_count++; 202101099Srwatson } else { 203101099Srwatson /* printf("replacement\n"); */ 204101099Srwatson *rules[index] = temprule; 205101099Srwatson } 206101099Srwatson } 207101099Srwatson 208145412Strhodesout: 209145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 210145412Strhodes if (ruleptr != NULL) 211145412Strhodes FREE(ruleptr, M_MACBSDEXTENDED); 212145412Strhodes if (req->oldptr && error == 0) { 213145412Strhodes error = SYSCTL_OUT(req, &temprule, sizeof(temprule)); 214145412Strhodes if (error) 215145412Strhodes return (error); 216145412Strhodes } 217145412Strhodes 218101099Srwatson return (0); 219101099Srwatson} 220101099Srwatson 221101099SrwatsonSYSCTL_NODE(_security_mac_bsdextended, OID_AUTO, rules, 222101099Srwatson CTLFLAG_RW, sysctl_rule, "BSD extended MAC rules"); 223101099Srwatson 224101099Srwatsonstatic void 225101099Srwatsonmac_bsdextended_init(struct mac_policy_conf *mpc) 226101099Srwatson{ 227101099Srwatson 228101099Srwatson /* Initialize ruleset lock. */ 229145412Strhodes mtx_init(&mac_bsdextended_mtx, "mac_bsdextended lock", NULL, MTX_DEF); 230145412Strhodes 231101099Srwatson /* Register dynamic sysctl's for rules. */ 232101099Srwatson} 233101099Srwatson 234101099Srwatsonstatic void 235101099Srwatsonmac_bsdextended_destroy(struct mac_policy_conf *mpc) 236101099Srwatson{ 237101099Srwatson 238145412Strhodes /* Destroy ruleset lock. */ 239145412Strhodes mtx_destroy(&mac_bsdextended_mtx); 240145412Strhodes 241101099Srwatson /* Tear down sysctls. */ 242101099Srwatson} 243101099Srwatson 244101099Srwatsonstatic int 245101099Srwatsonmac_bsdextended_rulecheck(struct mac_bsdextended_rule *rule, 246106212Srwatson struct ucred *cred, uid_t object_uid, gid_t object_gid, int acc_mode) 247101099Srwatson{ 248101099Srwatson int match; 249101099Srwatson 250101099Srwatson /* 251101099Srwatson * Is there a subject match? 252101099Srwatson */ 253145412Strhodes mtx_assert(&mac_bsdextended_mtx, MA_OWNED); 254101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_UID_DEFINED) { 255101099Srwatson match = (rule->mbr_subject.mbi_uid == cred->cr_uid || 256101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_ruid || 257101099Srwatson rule->mbr_subject.mbi_uid == cred->cr_svuid); 258101099Srwatson 259101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 260101099Srwatson match = !match; 261101099Srwatson 262101099Srwatson if (!match) 263101099Srwatson return (0); 264101099Srwatson } 265101099Srwatson 266101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_GID_DEFINED) { 267101099Srwatson match = (groupmember(rule->mbr_subject.mbi_gid, cred) || 268101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_rgid || 269101099Srwatson rule->mbr_subject.mbi_gid == cred->cr_svgid); 270101099Srwatson 271101099Srwatson if (rule->mbr_subject.mbi_flags & MBI_NEGATED) 272101099Srwatson match = !match; 273101099Srwatson 274101099Srwatson if (!match) 275101099Srwatson return (0); 276101099Srwatson } 277101099Srwatson 278101099Srwatson /* 279101099Srwatson * Is there an object match? 280101099Srwatson */ 281101099Srwatson if (rule->mbr_object.mbi_flags & MBI_UID_DEFINED) { 282101099Srwatson match = (rule->mbr_object.mbi_uid == object_uid); 283101099Srwatson 284101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 285101099Srwatson match = !match; 286101099Srwatson 287101099Srwatson if (!match) 288101099Srwatson return (0); 289101099Srwatson } 290101099Srwatson 291101099Srwatson if (rule->mbr_object.mbi_flags & MBI_GID_DEFINED) { 292101099Srwatson match = (rule->mbr_object.mbi_gid == object_gid); 293101099Srwatson 294101099Srwatson if (rule->mbr_object.mbi_flags & MBI_NEGATED) 295101099Srwatson match = !match; 296101099Srwatson 297101099Srwatson if (!match) 298101099Srwatson return (0); 299101099Srwatson } 300101099Srwatson 301101099Srwatson /* 302101099Srwatson * Is the access permitted? 303101099Srwatson */ 304101099Srwatson if ((rule->mbr_mode & acc_mode) != acc_mode) { 305134132Strhodes if (mac_bsdextended_logging) 306134132Strhodes log(LOG_AUTHPRIV, "mac_bsdextended: %d:%d request %d" 307134132Strhodes " on %d:%d failed. \n", cred->cr_ruid, 308134132Strhodes cred->cr_rgid, acc_mode, object_uid, object_gid); 309134132Strhodes return (EACCES); /* Matching rule denies access */ 310101099Srwatson } 311145412Strhodes 312134131Strhodes /* 313145412Strhodes * If the rule matched, permits access, and first match is enabled, 314145412Strhodes * return success. 315134131Strhodes */ 316134131Strhodes if (mac_bsdextended_firstmatch_enabled) 317134131Strhodes return (EJUSTRETURN); 318134131Strhodes else 319134131Strhodes return(0); 320101099Srwatson} 321101099Srwatson 322101099Srwatsonstatic int 323101099Srwatsonmac_bsdextended_check(struct ucred *cred, uid_t object_uid, gid_t object_gid, 324106212Srwatson int acc_mode) 325101099Srwatson{ 326101099Srwatson int error, i; 327101099Srwatson 328132563Srwatson if (suser_cred(cred, 0) == 0) 329132563Srwatson return (0); 330132563Srwatson 331145412Strhodes mtx_lock(&mac_bsdextended_mtx); 332101099Srwatson for (i = 0; i < rule_slots; i++) { 333101099Srwatson if (rules[i] == NULL) 334101099Srwatson continue; 335101099Srwatson 336108376Srwatson /* 337145412Strhodes * Since we do not separately handle append, map append to 338108376Srwatson * write. 339108376Srwatson */ 340136739Srwatson if (acc_mode & MBI_APPEND) { 341136739Srwatson acc_mode &= ~MBI_APPEND; 342136739Srwatson acc_mode |= MBI_WRITE; 343108376Srwatson } 344108376Srwatson 345101099Srwatson error = mac_bsdextended_rulecheck(rules[i], cred, object_uid, 346101099Srwatson object_gid, acc_mode); 347134131Strhodes if (error == EJUSTRETURN) 348134131Strhodes break; 349145412Strhodes if (error) { 350145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 351101099Srwatson return (error); 352145412Strhodes } 353101099Srwatson } 354145412Strhodes mtx_unlock(&mac_bsdextended_mtx); 355101099Srwatson return (0); 356101099Srwatson} 357101099Srwatson 358101099Srwatsonstatic int 359112575Srwatsonmac_bsdextended_check_system_swapon(struct ucred *cred, struct vnode *vp, 360112575Srwatson struct label *label) 361112575Srwatson{ 362112575Srwatson struct vattr vap; 363112575Srwatson int error; 364112575Srwatson 365112575Srwatson if (!mac_bsdextended_enabled) 366112575Srwatson return (0); 367112575Srwatson 368112575Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 369112575Srwatson if (error) 370112575Srwatson return (error); 371136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 372136739Srwatson MBI_WRITE)); 373112575Srwatson} 374112575Srwatson 375112575Srwatsonstatic int 376101099Srwatsonmac_bsdextended_check_vnode_access(struct ucred *cred, struct vnode *vp, 377106212Srwatson struct label *label, int acc_mode) 378101099Srwatson{ 379101099Srwatson struct vattr vap; 380101099Srwatson int error; 381101099Srwatson 382101099Srwatson if (!mac_bsdextended_enabled) 383101099Srwatson return (0); 384101099Srwatson 385101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 386101099Srwatson if (error) 387101099Srwatson return (error); 388106212Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 389101099Srwatson} 390101099Srwatson 391101099Srwatsonstatic int 392101099Srwatsonmac_bsdextended_check_vnode_chdir(struct ucred *cred, struct vnode *dvp, 393101099Srwatson struct label *dlabel) 394101099Srwatson{ 395101099Srwatson struct vattr vap; 396101099Srwatson int error; 397101099Srwatson 398101099Srwatson if (!mac_bsdextended_enabled) 399101099Srwatson return (0); 400101099Srwatson 401101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 402101099Srwatson if (error) 403101099Srwatson return (error); 404136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 405136739Srwatson MBI_EXEC)); 406101099Srwatson} 407101099Srwatson 408101099Srwatsonstatic int 409101099Srwatsonmac_bsdextended_check_vnode_chroot(struct ucred *cred, struct vnode *dvp, 410101099Srwatson struct label *dlabel) 411101099Srwatson{ 412101099Srwatson struct vattr vap; 413101099Srwatson int error; 414101099Srwatson 415101099Srwatson if (!mac_bsdextended_enabled) 416101099Srwatson return (0); 417101099Srwatson 418101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 419101099Srwatson if (error) 420101099Srwatson return (error); 421136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 422136739Srwatson MBI_EXEC)); 423101099Srwatson} 424101099Srwatson 425101099Srwatsonstatic int 426101099Srwatsonmac_bsdextended_check_create_vnode(struct ucred *cred, struct vnode *dvp, 427101099Srwatson struct label *dlabel, struct componentname *cnp, struct vattr *vap) 428101099Srwatson{ 429101099Srwatson struct vattr dvap; 430101099Srwatson int error; 431101099Srwatson 432101099Srwatson if (!mac_bsdextended_enabled) 433101099Srwatson return (0); 434101099Srwatson 435101099Srwatson error = VOP_GETATTR(dvp, &dvap, cred, curthread); 436101099Srwatson if (error) 437101099Srwatson return (error); 438136739Srwatson return (mac_bsdextended_check(cred, dvap.va_uid, dvap.va_gid, 439136739Srwatson MBI_WRITE)); 440101099Srwatson} 441101099Srwatson 442101099Srwatsonstatic int 443101099Srwatsonmac_bsdextended_check_vnode_delete(struct ucred *cred, struct vnode *dvp, 444101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 445101099Srwatson struct componentname *cnp) 446101099Srwatson{ 447101099Srwatson struct vattr vap; 448101099Srwatson int error; 449101099Srwatson 450101099Srwatson if (!mac_bsdextended_enabled) 451101099Srwatson return (0); 452101099Srwatson 453101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 454101099Srwatson if (error) 455101099Srwatson return (error); 456136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 457136739Srwatson MBI_WRITE); 458101099Srwatson if (error) 459101099Srwatson return (error); 460101099Srwatson 461101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 462101099Srwatson if (error) 463101099Srwatson return (error); 464136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 465136739Srwatson MBI_WRITE)); 466101099Srwatson} 467101099Srwatson 468101099Srwatsonstatic int 469101099Srwatsonmac_bsdextended_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp, 470101099Srwatson struct label *label, acl_type_t type) 471101099Srwatson{ 472101099Srwatson struct vattr vap; 473101099Srwatson int error; 474101099Srwatson 475101099Srwatson if (!mac_bsdextended_enabled) 476101099Srwatson return (0); 477101099Srwatson 478101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 479117247Srwatson if (error) 480101099Srwatson return (error); 481136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 482136739Srwatson MBI_ADMIN)); 483101099Srwatson} 484101099Srwatson 485101099Srwatsonstatic int 486119202Srwatsonmac_bsdextended_check_vnode_deleteextattr(struct ucred *cred, struct vnode *vp, 487119202Srwatson struct label *label, int attrnamespace, const char *name) 488119202Srwatson{ 489119202Srwatson struct vattr vap; 490119202Srwatson int error; 491119202Srwatson 492119202Srwatson if (!mac_bsdextended_enabled) 493119202Srwatson return (0); 494119202Srwatson 495119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 496119202Srwatson if (error) 497119202Srwatson return (error); 498136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 499136739Srwatson MBI_WRITE)); 500119202Srwatson} 501119202Srwatson 502119202Srwatsonstatic int 503101099Srwatsonmac_bsdextended_check_vnode_exec(struct ucred *cred, struct vnode *vp, 504106648Srwatson struct label *label, struct image_params *imgp, 505106648Srwatson struct label *execlabel) 506101099Srwatson{ 507101099Srwatson struct vattr vap; 508101099Srwatson int error; 509101099Srwatson 510101099Srwatson if (!mac_bsdextended_enabled) 511101099Srwatson return (0); 512101099Srwatson 513101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 514101099Srwatson if (error) 515101099Srwatson return (error); 516101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 517136739Srwatson MBI_READ|MBI_EXEC)); 518101099Srwatson} 519101099Srwatson 520101099Srwatsonstatic int 521101099Srwatsonmac_bsdextended_check_vnode_getacl(struct ucred *cred, struct vnode *vp, 522101099Srwatson struct label *label, acl_type_t type) 523101099Srwatson{ 524101099Srwatson struct vattr vap; 525101099Srwatson int error; 526101099Srwatson 527101099Srwatson if (!mac_bsdextended_enabled) 528101099Srwatson return (0); 529101099Srwatson 530101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 531101099Srwatson if (error) 532101099Srwatson return (error); 533136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 534136739Srwatson MBI_STAT)); 535101099Srwatson} 536101099Srwatson 537101099Srwatsonstatic int 538101099Srwatsonmac_bsdextended_check_vnode_getextattr(struct ucred *cred, struct vnode *vp, 539101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 540101099Srwatson{ 541101099Srwatson struct vattr vap; 542101099Srwatson int error; 543101099Srwatson 544101099Srwatson if (!mac_bsdextended_enabled) 545101099Srwatson return (0); 546101099Srwatson 547101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 548101099Srwatson if (error) 549101099Srwatson return (error); 550136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 551136739Srwatson MBI_READ)); 552101099Srwatson} 553101099Srwatson 554101099Srwatsonstatic int 555104530Srwatsonmac_bsdextended_check_vnode_link(struct ucred *cred, struct vnode *dvp, 556104530Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 557104530Srwatson struct componentname *cnp) 558104530Srwatson{ 559104530Srwatson struct vattr vap; 560104530Srwatson int error; 561104530Srwatson 562104530Srwatson if (!mac_bsdextended_enabled) 563104530Srwatson return (0); 564104530Srwatson 565104530Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 566104530Srwatson if (error) 567104530Srwatson return (error); 568136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 569136739Srwatson MBI_WRITE); 570106214Srwatson if (error) 571106214Srwatson return (error); 572104530Srwatson 573104530Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 574104530Srwatson if (error) 575104530Srwatson return (error); 576136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 577136739Srwatson MBI_WRITE); 578104530Srwatson if (error) 579104530Srwatson return (error); 580104530Srwatson return (0); 581104530Srwatson} 582104530Srwatson 583104530Srwatsonstatic int 584119202Srwatsonmac_bsdextended_check_vnode_listextattr(struct ucred *cred, struct vnode *vp, 585119202Srwatson struct label *label, int attrnamespace) 586119202Srwatson{ 587119202Srwatson struct vattr vap; 588119202Srwatson int error; 589119202Srwatson 590119202Srwatson if (!mac_bsdextended_enabled) 591119202Srwatson return (0); 592119202Srwatson 593119202Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 594119202Srwatson if (error) 595119202Srwatson return (error); 596136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 597136739Srwatson MBI_READ)); 598119202Srwatson} 599119202Srwatson 600119202Srwatsonstatic int 601101099Srwatsonmac_bsdextended_check_vnode_lookup(struct ucred *cred, struct vnode *dvp, 602101099Srwatson struct label *dlabel, struct componentname *cnp) 603101099Srwatson{ 604101099Srwatson struct vattr vap; 605101099Srwatson int error; 606117247Srwatson 607101099Srwatson if (!mac_bsdextended_enabled) 608101099Srwatson return (0); 609117247Srwatson 610101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 611101099Srwatson if (error) 612101099Srwatson return (error); 613136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 614136739Srwatson MBI_EXEC)); 615101099Srwatson} 616101099Srwatson 617101099Srwatsonstatic int 618101099Srwatsonmac_bsdextended_check_vnode_open(struct ucred *cred, struct vnode *vp, 619106212Srwatson struct label *filelabel, int acc_mode) 620101099Srwatson{ 621101099Srwatson struct vattr vap; 622101099Srwatson int error; 623101099Srwatson 624101099Srwatson if (!mac_bsdextended_enabled) 625101099Srwatson return (0); 626101099Srwatson 627101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 628101099Srwatson if (error) 629101099Srwatson return (error); 630101099Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, acc_mode)); 631101099Srwatson} 632101099Srwatson 633101099Srwatsonstatic int 634101099Srwatsonmac_bsdextended_check_vnode_readdir(struct ucred *cred, struct vnode *dvp, 635101099Srwatson struct label *dlabel) 636101099Srwatson{ 637101099Srwatson struct vattr vap; 638101099Srwatson int error; 639101099Srwatson 640101099Srwatson if (!mac_bsdextended_enabled) 641101099Srwatson return (0); 642101099Srwatson 643101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 644101099Srwatson if (error) 645101099Srwatson return (error); 646136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 647136739Srwatson MBI_READ)); 648101099Srwatson} 649101099Srwatson 650101099Srwatsonstatic int 651101099Srwatsonmac_bsdextended_check_vnode_readdlink(struct ucred *cred, struct vnode *vp, 652101099Srwatson struct label *label) 653101099Srwatson{ 654101099Srwatson struct vattr vap; 655101099Srwatson int error; 656101099Srwatson 657101099Srwatson if (!mac_bsdextended_enabled) 658101099Srwatson return (0); 659101099Srwatson 660101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 661101099Srwatson if (error) 662101099Srwatson return (error); 663136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 664136739Srwatson MBI_READ)); 665101099Srwatson} 666101099Srwatson 667101099Srwatsonstatic int 668101099Srwatsonmac_bsdextended_check_vnode_rename_from(struct ucred *cred, struct vnode *dvp, 669101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, 670101099Srwatson struct componentname *cnp) 671101099Srwatson{ 672101099Srwatson struct vattr vap; 673101099Srwatson int error; 674101099Srwatson 675101099Srwatson if (!mac_bsdextended_enabled) 676101099Srwatson return (0); 677101099Srwatson 678101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 679101099Srwatson if (error) 680101099Srwatson return (error); 681136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 682136739Srwatson MBI_WRITE); 683101099Srwatson if (error) 684101099Srwatson return (error); 685101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 686101099Srwatson if (error) 687101099Srwatson return (error); 688136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 689136739Srwatson MBI_WRITE); 690101099Srwatson 691101099Srwatson return (error); 692101099Srwatson} 693101099Srwatson 694101099Srwatsonstatic int 695101099Srwatsonmac_bsdextended_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp, 696101099Srwatson struct label *dlabel, struct vnode *vp, struct label *label, int samedir, 697101099Srwatson struct componentname *cnp) 698101099Srwatson{ 699101099Srwatson struct vattr vap; 700101099Srwatson int error; 701101099Srwatson 702101099Srwatson if (!mac_bsdextended_enabled) 703101099Srwatson return (0); 704101099Srwatson 705101099Srwatson error = VOP_GETATTR(dvp, &vap, cred, curthread); 706101099Srwatson if (error) 707101099Srwatson return (error); 708136739Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 709136739Srwatson MBI_WRITE); 710101099Srwatson if (error) 711101099Srwatson return (error); 712101099Srwatson 713101099Srwatson if (vp != NULL) { 714101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 715101099Srwatson if (error) 716101099Srwatson return (error); 717101099Srwatson error = mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 718136739Srwatson MBI_WRITE); 719101099Srwatson } 720101099Srwatson 721101099Srwatson return (error); 722101099Srwatson} 723101099Srwatson 724101099Srwatsonstatic int 725101099Srwatsonmac_bsdextended_check_vnode_revoke(struct ucred *cred, struct vnode *vp, 726101099Srwatson struct label *label) 727101099Srwatson{ 728101099Srwatson struct vattr vap; 729101099Srwatson int error; 730101099Srwatson 731101099Srwatson if (!mac_bsdextended_enabled) 732101099Srwatson return (0); 733101099Srwatson 734101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 735101099Srwatson if (error) 736101099Srwatson return (error); 737136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 738136739Srwatson MBI_ADMIN)); 739101099Srwatson} 740101099Srwatson 741101099Srwatsonstatic int 742101099Srwatsonmac_bsdextended_check_setacl_vnode(struct ucred *cred, struct vnode *vp, 743101099Srwatson struct label *label, acl_type_t type, struct acl *acl) 744101099Srwatson{ 745101099Srwatson struct vattr vap; 746101099Srwatson int error; 747101099Srwatson 748101099Srwatson if (!mac_bsdextended_enabled) 749101099Srwatson return (0); 750101099Srwatson 751101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 752101099Srwatson if (error) 753101099Srwatson return (error); 754136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 755136739Srwatson MBI_ADMIN)); 756101099Srwatson} 757101099Srwatson 758101099Srwatsonstatic int 759101099Srwatsonmac_bsdextended_check_vnode_setextattr(struct ucred *cred, struct vnode *vp, 760101099Srwatson struct label *label, int attrnamespace, const char *name, struct uio *uio) 761101099Srwatson{ 762101099Srwatson struct vattr vap; 763101099Srwatson int error; 764101099Srwatson 765101099Srwatson if (!mac_bsdextended_enabled) 766101099Srwatson return (0); 767101099Srwatson 768101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 769101099Srwatson if (error) 770101099Srwatson return (error); 771136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 772136739Srwatson MBI_WRITE)); 773101099Srwatson} 774101099Srwatson 775101099Srwatsonstatic int 776101099Srwatsonmac_bsdextended_check_vnode_setflags(struct ucred *cred, struct vnode *vp, 777101099Srwatson struct label *label, u_long flags) 778101099Srwatson{ 779101099Srwatson struct vattr vap; 780101099Srwatson int error; 781101099Srwatson 782101099Srwatson if (!mac_bsdextended_enabled) 783101099Srwatson return (0); 784101099Srwatson 785101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 786101099Srwatson if (error) 787101099Srwatson return (error); 788136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 789136739Srwatson MBI_ADMIN)); 790101099Srwatson} 791101099Srwatson 792101099Srwatsonstatic int 793101099Srwatsonmac_bsdextended_check_vnode_setmode(struct ucred *cred, struct vnode *vp, 794101099Srwatson struct label *label, mode_t mode) 795101099Srwatson{ 796101099Srwatson struct vattr vap; 797101099Srwatson int error; 798101099Srwatson 799101099Srwatson if (!mac_bsdextended_enabled) 800101099Srwatson return (0); 801101099Srwatson 802101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 803101099Srwatson if (error) 804101099Srwatson return (error); 805136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 806136739Srwatson MBI_ADMIN)); 807101099Srwatson} 808101099Srwatson 809101099Srwatsonstatic int 810101099Srwatsonmac_bsdextended_check_vnode_setowner(struct ucred *cred, struct vnode *vp, 811101099Srwatson struct label *label, uid_t uid, gid_t gid) 812101099Srwatson{ 813101099Srwatson struct vattr vap; 814101099Srwatson int error; 815101099Srwatson 816101099Srwatson if (!mac_bsdextended_enabled) 817101099Srwatson return (0); 818101099Srwatson 819101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 820101099Srwatson if (error) 821101099Srwatson return (error); 822136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 823136739Srwatson MBI_ADMIN)); 824101099Srwatson} 825101099Srwatson 826101099Srwatsonstatic int 827101099Srwatsonmac_bsdextended_check_vnode_setutimes(struct ucred *cred, struct vnode *vp, 828101099Srwatson struct label *label, struct timespec atime, struct timespec utime) 829101099Srwatson{ 830101099Srwatson struct vattr vap; 831101099Srwatson int error; 832101099Srwatson 833101099Srwatson if (!mac_bsdextended_enabled) 834101099Srwatson return (0); 835101099Srwatson 836101099Srwatson error = VOP_GETATTR(vp, &vap, cred, curthread); 837101099Srwatson if (error) 838101099Srwatson return (error); 839136739Srwatson return (mac_bsdextended_check(cred, vap.va_uid, vap.va_gid, 840136739Srwatson MBI_ADMIN)); 841101099Srwatson} 842101099Srwatson 843101099Srwatsonstatic int 844102129Srwatsonmac_bsdextended_check_vnode_stat(struct ucred *active_cred, 845102129Srwatson struct ucred *file_cred, struct vnode *vp, struct label *label) 846101099Srwatson{ 847101099Srwatson struct vattr vap; 848101099Srwatson int error; 849101099Srwatson 850101099Srwatson if (!mac_bsdextended_enabled) 851101099Srwatson return (0); 852101099Srwatson 853102129Srwatson error = VOP_GETATTR(vp, &vap, active_cred, curthread); 854101099Srwatson if (error) 855101099Srwatson return (error); 856102129Srwatson return (mac_bsdextended_check(active_cred, vap.va_uid, vap.va_gid, 857136739Srwatson MBI_STAT)); 858101099Srwatson} 859101099Srwatson 860106217Srwatsonstatic struct mac_policy_ops mac_bsdextended_ops = 861101099Srwatson{ 862106217Srwatson .mpo_destroy = mac_bsdextended_destroy, 863106217Srwatson .mpo_init = mac_bsdextended_init, 864112575Srwatson .mpo_check_system_swapon = mac_bsdextended_check_system_swapon, 865106217Srwatson .mpo_check_vnode_access = mac_bsdextended_check_vnode_access, 866106217Srwatson .mpo_check_vnode_chdir = mac_bsdextended_check_vnode_chdir, 867106217Srwatson .mpo_check_vnode_chroot = mac_bsdextended_check_vnode_chroot, 868106217Srwatson .mpo_check_vnode_create = mac_bsdextended_check_create_vnode, 869106217Srwatson .mpo_check_vnode_delete = mac_bsdextended_check_vnode_delete, 870106217Srwatson .mpo_check_vnode_deleteacl = mac_bsdextended_check_vnode_deleteacl, 871119202Srwatson .mpo_check_vnode_deleteextattr = mac_bsdextended_check_vnode_deleteextattr, 872106217Srwatson .mpo_check_vnode_exec = mac_bsdextended_check_vnode_exec, 873106217Srwatson .mpo_check_vnode_getacl = mac_bsdextended_check_vnode_getacl, 874106217Srwatson .mpo_check_vnode_getextattr = mac_bsdextended_check_vnode_getextattr, 875106217Srwatson .mpo_check_vnode_link = mac_bsdextended_check_vnode_link, 876119202Srwatson .mpo_check_vnode_listextattr = mac_bsdextended_check_vnode_listextattr, 877106217Srwatson .mpo_check_vnode_lookup = mac_bsdextended_check_vnode_lookup, 878106217Srwatson .mpo_check_vnode_open = mac_bsdextended_check_vnode_open, 879106217Srwatson .mpo_check_vnode_readdir = mac_bsdextended_check_vnode_readdir, 880106217Srwatson .mpo_check_vnode_readlink = mac_bsdextended_check_vnode_readdlink, 881106217Srwatson .mpo_check_vnode_rename_from = mac_bsdextended_check_vnode_rename_from, 882106217Srwatson .mpo_check_vnode_rename_to = mac_bsdextended_check_vnode_rename_to, 883106217Srwatson .mpo_check_vnode_revoke = mac_bsdextended_check_vnode_revoke, 884106217Srwatson .mpo_check_vnode_setacl = mac_bsdextended_check_setacl_vnode, 885106217Srwatson .mpo_check_vnode_setextattr = mac_bsdextended_check_vnode_setextattr, 886106217Srwatson .mpo_check_vnode_setflags = mac_bsdextended_check_vnode_setflags, 887106217Srwatson .mpo_check_vnode_setmode = mac_bsdextended_check_vnode_setmode, 888106217Srwatson .mpo_check_vnode_setowner = mac_bsdextended_check_vnode_setowner, 889106217Srwatson .mpo_check_vnode_setutimes = mac_bsdextended_check_vnode_setutimes, 890106217Srwatson .mpo_check_vnode_stat = mac_bsdextended_check_vnode_stat, 891101099Srwatson}; 892101099Srwatson 893112717SrwatsonMAC_POLICY_SET(&mac_bsdextended_ops, mac_bsdextended, 894101099Srwatson "TrustedBSD MAC/BSD Extended", MPC_LOADTIME_FLAG_UNLOADOK, NULL); 895