1*789Sahrens /* 2*789Sahrens * CDDL HEADER START 3*789Sahrens * 4*789Sahrens * The contents of this file are subject to the terms of the 5*789Sahrens * Common Development and Distribution License, Version 1.0 only 6*789Sahrens * (the "License"). You may not use this file except in compliance 7*789Sahrens * with the License. 8*789Sahrens * 9*789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*789Sahrens * or http://www.opensolaris.org/os/licensing. 11*789Sahrens * See the License for the specific language governing permissions 12*789Sahrens * and limitations under the License. 13*789Sahrens * 14*789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15*789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*789Sahrens * If applicable, add the following below this CDDL HEADER, with the 17*789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18*789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19*789Sahrens * 20*789Sahrens * CDDL HEADER END 21*789Sahrens */ 22*789Sahrens /* 23*789Sahrens * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*789Sahrens * Use is subject to license terms. 25*789Sahrens */ 26*789Sahrens 27*789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28*789Sahrens 29*789Sahrens #include <sys/types.h> 30*789Sahrens #include <sys/param.h> 31*789Sahrens #include <sys/time.h> 32*789Sahrens #include <sys/systm.h> 33*789Sahrens #include <sys/sysmacros.h> 34*789Sahrens #include <sys/resource.h> 35*789Sahrens #include <sys/vfs.h> 36*789Sahrens #include <sys/vnode.h> 37*789Sahrens #include <sys/file.h> 38*789Sahrens #include <sys/stat.h> 39*789Sahrens #include <sys/kmem.h> 40*789Sahrens #include <sys/cmn_err.h> 41*789Sahrens #include <sys/errno.h> 42*789Sahrens #include <sys/unistd.h> 43*789Sahrens #include <sys/fs/zfs.h> 44*789Sahrens #include <sys/mode.h> 45*789Sahrens #include <sys/policy.h> 46*789Sahrens #include <sys/zfs_znode.h> 47*789Sahrens #include <sys/zfs_acl.h> 48*789Sahrens #include <sys/zfs_dir.h> 49*789Sahrens #include <sys/zfs_vfsops.h> 50*789Sahrens #include <sys/dmu.h> 51*789Sahrens #include <sys/zap.h> 52*789Sahrens #include <util/qsort.h> 53*789Sahrens #include "fs/fs_subr.h" 54*789Sahrens #include <acl/acl_common.h> 55*789Sahrens 56*789Sahrens #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE 57*789Sahrens #define DENY ACE_ACCESS_DENIED_ACE_TYPE 58*789Sahrens 59*789Sahrens #define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) 60*789Sahrens #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \ 61*789Sahrens ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE) 62*789Sahrens #define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \ 63*789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 64*789Sahrens #define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \ 65*789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 66*789Sahrens #define WRITE_MASK (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS| \ 67*789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|ACE_WRITE_OWNER) 68*789Sahrens 69*789Sahrens #define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 70*789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 71*789Sahrens 72*789Sahrens #define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 73*789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 74*789Sahrens 75*789Sahrens #define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \ 76*789Sahrens ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE) 77*789Sahrens 78*789Sahrens #define SECURE_NO_INHERIT (ACE_WRITE_ACL|ACE_WRITE_OWNER) 79*789Sahrens 80*789Sahrens #define OGE_PAD 6 /* traditional owner/group/everyone ACES */ 81*789Sahrens 82*789Sahrens static int zfs_ace_can_use(znode_t *zp, ace_t *); 83*789Sahrens 84*789Sahrens static zfs_acl_t * 85*789Sahrens zfs_acl_alloc(int slots) 86*789Sahrens { 87*789Sahrens zfs_acl_t *aclp; 88*789Sahrens 89*789Sahrens aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP); 90*789Sahrens if (slots != 0) { 91*789Sahrens aclp->z_acl = kmem_alloc(ZFS_ACL_SIZE(slots), KM_SLEEP); 92*789Sahrens aclp->z_acl_count = 0; 93*789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 94*789Sahrens } else { 95*789Sahrens aclp->z_state = 0; 96*789Sahrens } 97*789Sahrens aclp->z_slots = slots; 98*789Sahrens return (aclp); 99*789Sahrens } 100*789Sahrens 101*789Sahrens void 102*789Sahrens zfs_acl_free(zfs_acl_t *aclp) 103*789Sahrens { 104*789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) { 105*789Sahrens kmem_free(aclp->z_acl, ZFS_ACL_SIZE(aclp->z_slots)); 106*789Sahrens } 107*789Sahrens kmem_free(aclp, sizeof (zfs_acl_t)); 108*789Sahrens } 109*789Sahrens 110*789Sahrens static uint32_t 111*789Sahrens zfs_v4_to_unix(uint32_t access_mask) 112*789Sahrens { 113*789Sahrens uint32_t new_mask = 0; 114*789Sahrens 115*789Sahrens if (access_mask & (ACE_READ_DATA | ACE_LIST_DIRECTORY)) 116*789Sahrens new_mask |= S_IROTH; 117*789Sahrens if (access_mask & (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_ADD_FILE)) 118*789Sahrens new_mask |= S_IWOTH; 119*789Sahrens if (access_mask & (ACE_EXECUTE|ACE_READ_NAMED_ATTRS)) 120*789Sahrens new_mask |= S_IXOTH; 121*789Sahrens 122*789Sahrens return (new_mask); 123*789Sahrens } 124*789Sahrens 125*789Sahrens /* 126*789Sahrens * Convert unix access mask to v4 access mask 127*789Sahrens */ 128*789Sahrens static uint32_t 129*789Sahrens zfs_unix_to_v4(uint32_t access_mask) 130*789Sahrens { 131*789Sahrens uint32_t new_mask = 0; 132*789Sahrens 133*789Sahrens if (access_mask & 01) 134*789Sahrens new_mask |= (ACE_EXECUTE); 135*789Sahrens if (access_mask & 02) { 136*789Sahrens new_mask |= (ACE_WRITE_DATA); 137*789Sahrens } if (access_mask & 04) { 138*789Sahrens new_mask |= ACE_READ_DATA; 139*789Sahrens } 140*789Sahrens return (new_mask); 141*789Sahrens } 142*789Sahrens 143*789Sahrens static void 144*789Sahrens zfs_set_ace(ace_t *zacep, uint32_t access_mask, int access_type, 145*789Sahrens uid_t uid, int entry_type) 146*789Sahrens { 147*789Sahrens zacep->a_access_mask = access_mask; 148*789Sahrens zacep->a_type = access_type; 149*789Sahrens zacep->a_who = uid; 150*789Sahrens zacep->a_flags = entry_type; 151*789Sahrens } 152*789Sahrens 153*789Sahrens static uint64_t 154*789Sahrens zfs_mode_compute(znode_t *zp, zfs_acl_t *aclp) 155*789Sahrens { 156*789Sahrens int i; 157*789Sahrens int entry_type; 158*789Sahrens mode_t mode = (zp->z_phys->zp_mode & 159*789Sahrens (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)); 160*789Sahrens mode_t seen = 0; 161*789Sahrens ace_t *acep; 162*789Sahrens 163*789Sahrens for (i = 0, acep = aclp->z_acl; 164*789Sahrens i != aclp->z_acl_count; i++, acep++) { 165*789Sahrens entry_type = (acep->a_flags & 0xf040); 166*789Sahrens if (entry_type == ACE_OWNER) { 167*789Sahrens if ((acep->a_access_mask & ACE_READ_DATA) && 168*789Sahrens (!(seen & S_IRUSR))) { 169*789Sahrens seen |= S_IRUSR; 170*789Sahrens if (acep->a_type == ALLOW) { 171*789Sahrens mode |= S_IRUSR; 172*789Sahrens } 173*789Sahrens } 174*789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA) && 175*789Sahrens (!(seen & S_IWUSR))) { 176*789Sahrens seen |= S_IWUSR; 177*789Sahrens if (acep->a_type == ALLOW) { 178*789Sahrens mode |= S_IWUSR; 179*789Sahrens } 180*789Sahrens } 181*789Sahrens if ((acep->a_access_mask & ACE_EXECUTE) && 182*789Sahrens (!(seen & S_IXUSR))) { 183*789Sahrens seen |= S_IXUSR; 184*789Sahrens if (acep->a_type == ALLOW) { 185*789Sahrens mode |= S_IXUSR; 186*789Sahrens } 187*789Sahrens } 188*789Sahrens } else if (entry_type == OWNING_GROUP) { 189*789Sahrens if ((acep->a_access_mask & ACE_READ_DATA) && 190*789Sahrens (!(seen & S_IRGRP))) { 191*789Sahrens seen |= S_IRGRP; 192*789Sahrens if (acep->a_type == ALLOW) { 193*789Sahrens mode |= S_IRGRP; 194*789Sahrens } 195*789Sahrens } 196*789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA) && 197*789Sahrens (!(seen & S_IWGRP))) { 198*789Sahrens seen |= S_IWGRP; 199*789Sahrens if (acep->a_type == ALLOW) { 200*789Sahrens mode |= S_IWGRP; 201*789Sahrens } 202*789Sahrens } 203*789Sahrens if ((acep->a_access_mask & ACE_EXECUTE) && 204*789Sahrens (!(seen & S_IXGRP))) { 205*789Sahrens seen |= S_IXGRP; 206*789Sahrens if (acep->a_type == ALLOW) { 207*789Sahrens mode |= S_IXGRP; 208*789Sahrens } 209*789Sahrens } 210*789Sahrens } else if (entry_type == ACE_EVERYONE) { 211*789Sahrens if ((acep->a_access_mask & ACE_READ_DATA)) { 212*789Sahrens if (!(seen & S_IRUSR)) { 213*789Sahrens seen |= S_IRUSR; 214*789Sahrens if (acep->a_type == ALLOW) { 215*789Sahrens mode |= S_IRUSR; 216*789Sahrens } 217*789Sahrens } 218*789Sahrens if (!(seen & S_IRGRP)) { 219*789Sahrens seen |= S_IRGRP; 220*789Sahrens if (acep->a_type == ALLOW) { 221*789Sahrens mode |= S_IRGRP; 222*789Sahrens } 223*789Sahrens } 224*789Sahrens if (!(seen & S_IROTH)) { 225*789Sahrens seen |= S_IROTH; 226*789Sahrens if (acep->a_type == ALLOW) { 227*789Sahrens mode |= S_IROTH; 228*789Sahrens } 229*789Sahrens } 230*789Sahrens } 231*789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA)) { 232*789Sahrens if (!(seen & S_IWUSR)) { 233*789Sahrens seen |= S_IWUSR; 234*789Sahrens if (acep->a_type == ALLOW) { 235*789Sahrens mode |= S_IWUSR; 236*789Sahrens } 237*789Sahrens } 238*789Sahrens if (!(seen & S_IWGRP)) { 239*789Sahrens seen |= S_IWGRP; 240*789Sahrens if (acep->a_type == ALLOW) { 241*789Sahrens mode |= S_IWGRP; 242*789Sahrens } 243*789Sahrens } 244*789Sahrens if (!(seen & S_IWOTH)) { 245*789Sahrens seen |= S_IWOTH; 246*789Sahrens if (acep->a_type == ALLOW) { 247*789Sahrens mode |= S_IWOTH; 248*789Sahrens } 249*789Sahrens } 250*789Sahrens } 251*789Sahrens if ((acep->a_access_mask & ACE_EXECUTE)) { 252*789Sahrens if (!(seen & S_IXUSR)) { 253*789Sahrens seen |= S_IXUSR; 254*789Sahrens if (acep->a_type == ALLOW) { 255*789Sahrens mode |= S_IXUSR; 256*789Sahrens } 257*789Sahrens } 258*789Sahrens if (!(seen & S_IXGRP)) { 259*789Sahrens seen |= S_IXGRP; 260*789Sahrens if (acep->a_type == ALLOW) { 261*789Sahrens mode |= S_IXGRP; 262*789Sahrens } 263*789Sahrens } 264*789Sahrens if (!(seen & S_IXOTH)) { 265*789Sahrens seen |= S_IXOTH; 266*789Sahrens if (acep->a_type == ALLOW) { 267*789Sahrens mode |= S_IXOTH; 268*789Sahrens } 269*789Sahrens } 270*789Sahrens } 271*789Sahrens } 272*789Sahrens } 273*789Sahrens return (mode); 274*789Sahrens } 275*789Sahrens 276*789Sahrens static zfs_acl_t * 277*789Sahrens zfs_acl_node_read_internal(znode_t *zp) 278*789Sahrens { 279*789Sahrens zfs_acl_t *aclp; 280*789Sahrens 281*789Sahrens aclp = zfs_acl_alloc(0); 282*789Sahrens aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 283*789Sahrens aclp->z_acl = &zp->z_phys->zp_acl.z_ace_data[0]; 284*789Sahrens 285*789Sahrens return (aclp); 286*789Sahrens } 287*789Sahrens 288*789Sahrens /* 289*789Sahrens * Read an external acl object. 290*789Sahrens */ 291*789Sahrens zfs_acl_t * 292*789Sahrens zfs_acl_node_read(znode_t *zp) 293*789Sahrens { 294*789Sahrens uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj; 295*789Sahrens zfs_acl_t *aclp; 296*789Sahrens 297*789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 298*789Sahrens 299*789Sahrens if (zp->z_phys->zp_acl.z_acl_extern_obj == 0) 300*789Sahrens return (zfs_acl_node_read_internal(zp)); 301*789Sahrens 302*789Sahrens aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_count); 303*789Sahrens 304*789Sahrens dmu_read(zp->z_zfsvfs->z_os, extacl, 0, 305*789Sahrens ZFS_ACL_SIZE(zp->z_phys->zp_acl.z_acl_count), aclp->z_acl); 306*789Sahrens 307*789Sahrens aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 308*789Sahrens 309*789Sahrens return (aclp); 310*789Sahrens } 311*789Sahrens 312*789Sahrens static boolean_t 313*789Sahrens zfs_acl_valid(znode_t *zp, ace_t *uace, int aclcnt, int *inherit) 314*789Sahrens { 315*789Sahrens ace_t *acep; 316*789Sahrens int i; 317*789Sahrens 318*789Sahrens *inherit = 0; 319*789Sahrens 320*789Sahrens if (aclcnt > MAX_ACL_ENTRIES || aclcnt <= 0) { 321*789Sahrens return (B_FALSE); 322*789Sahrens } 323*789Sahrens 324*789Sahrens for (i = 0, acep = uace; i != aclcnt; i++, acep++) { 325*789Sahrens 326*789Sahrens /* 327*789Sahrens * first check type of entry 328*789Sahrens */ 329*789Sahrens 330*789Sahrens switch (acep->a_flags & 0xf040) { 331*789Sahrens case ACE_OWNER: 332*789Sahrens acep->a_who = -1; 333*789Sahrens break; 334*789Sahrens case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 335*789Sahrens case ACE_IDENTIFIER_GROUP: 336*789Sahrens if (acep->a_flags & ACE_GROUP) { 337*789Sahrens acep->a_who = -1; 338*789Sahrens } 339*789Sahrens break; 340*789Sahrens case ACE_EVERYONE: 341*789Sahrens acep->a_who = -1; 342*789Sahrens break; 343*789Sahrens } 344*789Sahrens 345*789Sahrens /* 346*789Sahrens * next check inheritance level flags 347*789Sahrens */ 348*789Sahrens 349*789Sahrens if (acep->a_type != ALLOW && acep->a_type != DENY) 350*789Sahrens return (B_FALSE); 351*789Sahrens 352*789Sahrens /* 353*789Sahrens * Only directories should have inheritance flags. 354*789Sahrens */ 355*789Sahrens if (ZTOV(zp)->v_type != VDIR && (acep->a_flags & 356*789Sahrens (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE| 357*789Sahrens ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) { 358*789Sahrens return (B_FALSE); 359*789Sahrens } 360*789Sahrens 361*789Sahrens if (acep->a_flags & 362*789Sahrens (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)) 363*789Sahrens *inherit = 1; 364*789Sahrens 365*789Sahrens if (acep->a_flags & 366*789Sahrens (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) { 367*789Sahrens if ((acep->a_flags & (ACE_FILE_INHERIT_ACE| 368*789Sahrens ACE_DIRECTORY_INHERIT_ACE)) == 0) { 369*789Sahrens return (B_FALSE); 370*789Sahrens } 371*789Sahrens } 372*789Sahrens } 373*789Sahrens 374*789Sahrens return (B_TRUE); 375*789Sahrens } 376*789Sahrens /* 377*789Sahrens * common code for setting acl's. 378*789Sahrens * 379*789Sahrens * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl. 380*789Sahrens * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's 381*789Sahrens * already checked the acl and knows whether to inherit. 382*789Sahrens */ 383*789Sahrens int 384*789Sahrens zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, dmu_tx_t *tx, int *ihp) 385*789Sahrens { 386*789Sahrens int inherit = 0; 387*789Sahrens int error; 388*789Sahrens znode_phys_t *zphys = zp->z_phys; 389*789Sahrens zfs_znode_acl_t *zacl = &zphys->zp_acl; 390*789Sahrens uint32_t acl_phys_size = ZFS_ACL_SIZE(aclp->z_acl_count); 391*789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 392*789Sahrens uint64_t aoid = zphys->zp_acl.z_acl_extern_obj; 393*789Sahrens 394*789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 395*789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 396*789Sahrens 397*789Sahrens if (ihp) 398*789Sahrens inherit = *ihp; /* already determined by caller */ 399*789Sahrens else if (!zfs_acl_valid(zp, aclp->z_acl, 400*789Sahrens aclp->z_acl_count, &inherit)) { 401*789Sahrens return (EINVAL); 402*789Sahrens } 403*789Sahrens 404*789Sahrens dmu_buf_will_dirty(zp->z_dbuf, tx); 405*789Sahrens 406*789Sahrens /* 407*789Sahrens * Will ACL fit internally? 408*789Sahrens */ 409*789Sahrens if (aclp->z_acl_count > ACE_SLOT_CNT) { 410*789Sahrens if (aoid == 0) { 411*789Sahrens aoid = dmu_object_alloc(zfsvfs->z_os, 412*789Sahrens DMU_OT_ACL, acl_phys_size, DMU_OT_NONE, 0, tx); 413*789Sahrens } else { 414*789Sahrens (void) dmu_object_set_blocksize(zfsvfs->z_os, aoid, 415*789Sahrens acl_phys_size, 0, tx); 416*789Sahrens } 417*789Sahrens zphys->zp_acl.z_acl_extern_obj = aoid; 418*789Sahrens zphys->zp_acl.z_acl_count = aclp->z_acl_count; 419*789Sahrens dmu_write(zfsvfs->z_os, aoid, 0, 420*789Sahrens acl_phys_size, aclp->z_acl, tx); 421*789Sahrens } else { 422*789Sahrens /* 423*789Sahrens * Migrating back embedded? 424*789Sahrens */ 425*789Sahrens if (zphys->zp_acl.z_acl_extern_obj) { 426*789Sahrens error = dmu_object_free(zfsvfs->z_os, 427*789Sahrens zp->z_phys->zp_acl.z_acl_extern_obj, tx); 428*789Sahrens if (error) 429*789Sahrens return (error); 430*789Sahrens zphys->zp_acl.z_acl_extern_obj = 0; 431*789Sahrens } 432*789Sahrens bcopy(aclp->z_acl, zacl->z_ace_data, 433*789Sahrens aclp->z_acl_count * sizeof (ace_t)); 434*789Sahrens zacl->z_acl_count = aclp->z_acl_count; 435*789Sahrens } 436*789Sahrens if (inherit) 437*789Sahrens zp->z_phys->zp_flags |= ZFS_INHERIT_ACE; 438*789Sahrens else 439*789Sahrens zp->z_phys->zp_flags &= ~ZFS_INHERIT_ACE; 440*789Sahrens 441*789Sahrens zphys->zp_mode = zfs_mode_compute(zp, aclp); 442*789Sahrens zfs_time_stamper_locked(zp, STATE_CHANGED, tx); 443*789Sahrens 444*789Sahrens return (0); 445*789Sahrens } 446*789Sahrens 447*789Sahrens /* 448*789Sahrens * Create space for slots_needed ACEs to be append 449*789Sahrens * to aclp. 450*789Sahrens */ 451*789Sahrens static void 452*789Sahrens zfs_acl_append(zfs_acl_t *aclp, int slots_needed) 453*789Sahrens { 454*789Sahrens ace_t *newacep; 455*789Sahrens ace_t *oldaclp; 456*789Sahrens int slot_cnt; 457*789Sahrens int slots_left = aclp->z_slots - aclp->z_acl_count; 458*789Sahrens 459*789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 460*789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 461*789Sahrens if (slots_left < slots_needed || aclp->z_state != ACL_DATA_ALLOCED) { 462*789Sahrens slot_cnt = aclp->z_slots + 1 + (slots_needed - slots_left); 463*789Sahrens newacep = kmem_alloc(ZFS_ACL_SIZE(slot_cnt), KM_SLEEP); 464*789Sahrens bcopy(aclp->z_acl, newacep, 465*789Sahrens ZFS_ACL_SIZE(aclp->z_acl_count)); 466*789Sahrens oldaclp = aclp->z_acl; 467*789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 468*789Sahrens kmem_free(oldaclp, ZFS_ACL_SIZE(aclp->z_slots)); 469*789Sahrens aclp->z_acl = newacep; 470*789Sahrens aclp->z_slots = slot_cnt; 471*789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 472*789Sahrens } 473*789Sahrens } 474*789Sahrens 475*789Sahrens /* 476*789Sahrens * Remove "slot" ACE from aclp 477*789Sahrens */ 478*789Sahrens static void 479*789Sahrens zfs_ace_remove(zfs_acl_t *aclp, int slot) 480*789Sahrens { 481*789Sahrens if (aclp->z_acl_count > 1) { 482*789Sahrens (void) memmove(&aclp->z_acl[slot], 483*789Sahrens &aclp->z_acl[slot +1], sizeof (ace_t) * 484*789Sahrens (--aclp->z_acl_count - slot)); 485*789Sahrens } else 486*789Sahrens aclp->z_acl_count--; 487*789Sahrens } 488*789Sahrens 489*789Sahrens /* 490*789Sahrens * Update access mask for prepended ACE 491*789Sahrens * 492*789Sahrens * This applies the "groupmask" value for aclmode property. 493*789Sahrens */ 494*789Sahrens static void 495*789Sahrens zfs_acl_prepend_fixup(ace_t *acep, ace_t *origacep, mode_t mode, uid_t owner) 496*789Sahrens { 497*789Sahrens 498*789Sahrens int rmask, wmask, xmask; 499*789Sahrens int user_ace; 500*789Sahrens 501*789Sahrens user_ace = (!(acep->a_flags & 502*789Sahrens (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP))); 503*789Sahrens 504*789Sahrens if (user_ace && (acep->a_who == owner)) { 505*789Sahrens rmask = S_IRUSR; 506*789Sahrens wmask = S_IWUSR; 507*789Sahrens xmask = S_IXUSR; 508*789Sahrens } else { 509*789Sahrens rmask = S_IRGRP; 510*789Sahrens wmask = S_IWGRP; 511*789Sahrens xmask = S_IXGRP; 512*789Sahrens } 513*789Sahrens 514*789Sahrens if (origacep->a_access_mask & ACE_READ_DATA) { 515*789Sahrens if (mode & rmask) 516*789Sahrens acep->a_access_mask &= ~ACE_READ_DATA; 517*789Sahrens else 518*789Sahrens acep->a_access_mask |= ACE_READ_DATA; 519*789Sahrens } 520*789Sahrens 521*789Sahrens if (origacep->a_access_mask & ACE_WRITE_DATA) { 522*789Sahrens if (mode & wmask) 523*789Sahrens acep->a_access_mask &= ~ACE_WRITE_DATA; 524*789Sahrens else 525*789Sahrens acep->a_access_mask |= ACE_WRITE_DATA; 526*789Sahrens } 527*789Sahrens 528*789Sahrens if (origacep->a_access_mask & ACE_APPEND_DATA) { 529*789Sahrens if (mode & wmask) 530*789Sahrens acep->a_access_mask &= ~ACE_APPEND_DATA; 531*789Sahrens else 532*789Sahrens acep->a_access_mask |= ACE_APPEND_DATA; 533*789Sahrens } 534*789Sahrens 535*789Sahrens if (origacep->a_access_mask & ACE_EXECUTE) { 536*789Sahrens if (mode & xmask) 537*789Sahrens acep->a_access_mask &= ~ACE_EXECUTE; 538*789Sahrens else 539*789Sahrens acep->a_access_mask |= ACE_EXECUTE; 540*789Sahrens } 541*789Sahrens } 542*789Sahrens 543*789Sahrens /* 544*789Sahrens * Apply mode to canonical six ACEs. 545*789Sahrens */ 546*789Sahrens static void 547*789Sahrens zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode) 548*789Sahrens { 549*789Sahrens int cnt; 550*789Sahrens ace_t *acep; 551*789Sahrens 552*789Sahrens cnt = aclp->z_acl_count -1; 553*789Sahrens acep = aclp->z_acl; 554*789Sahrens 555*789Sahrens /* 556*789Sahrens * Fixup final ACEs to match the mode 557*789Sahrens */ 558*789Sahrens 559*789Sahrens ASSERT(cnt >= 5); 560*789Sahrens adjust_ace_pair(&acep[cnt - 1], mode); /* everyone@ */ 561*789Sahrens adjust_ace_pair(&acep[cnt - 3], (mode & 0070) >> 3); /* group@ */ 562*789Sahrens adjust_ace_pair(&acep[cnt - 5], (mode & 0700) >> 6); /* owner@ */ 563*789Sahrens } 564*789Sahrens 565*789Sahrens 566*789Sahrens static int 567*789Sahrens zfs_acl_ace_match(ace_t *acep, int allow_deny, int type, int mask) 568*789Sahrens { 569*789Sahrens return (acep->a_access_mask == mask && acep->a_type == allow_deny && 570*789Sahrens ((acep->a_flags & 0xf040) == type)); 571*789Sahrens } 572*789Sahrens 573*789Sahrens /* 574*789Sahrens * Can prepended ACE be reused? 575*789Sahrens */ 576*789Sahrens static int 577*789Sahrens zfs_reuse_deny(ace_t *acep, int i) 578*789Sahrens { 579*789Sahrens int okay_masks; 580*789Sahrens 581*789Sahrens if (i < 1) 582*789Sahrens return (B_FALSE); 583*789Sahrens 584*789Sahrens if (acep[i-1].a_type != DENY) 585*789Sahrens return (B_FALSE); 586*789Sahrens 587*789Sahrens if (acep[i-1].a_flags != (acep[i].a_flags & ACE_IDENTIFIER_GROUP)) 588*789Sahrens return (B_FALSE); 589*789Sahrens 590*789Sahrens okay_masks = (acep[i].a_access_mask & OKAY_MASK_BITS); 591*789Sahrens 592*789Sahrens if (acep[i-1].a_access_mask & ~okay_masks) 593*789Sahrens return (B_FALSE); 594*789Sahrens 595*789Sahrens return (B_TRUE); 596*789Sahrens } 597*789Sahrens 598*789Sahrens /* 599*789Sahrens * Create space to prepend an ACE 600*789Sahrens */ 601*789Sahrens static void 602*789Sahrens zfs_acl_prepend(zfs_acl_t *aclp, int i) 603*789Sahrens { 604*789Sahrens ace_t *oldaclp = NULL; 605*789Sahrens ace_t *to, *from; 606*789Sahrens int slots_left = aclp->z_slots - aclp->z_acl_count; 607*789Sahrens int oldslots; 608*789Sahrens int need_free = 0; 609*789Sahrens 610*789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 611*789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 612*789Sahrens 613*789Sahrens if (slots_left == 0 || aclp->z_state != ACL_DATA_ALLOCED) { 614*789Sahrens 615*789Sahrens to = kmem_alloc(ZFS_ACL_SIZE(aclp->z_acl_count + 616*789Sahrens OGE_PAD), KM_SLEEP); 617*789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 618*789Sahrens need_free++; 619*789Sahrens from = aclp->z_acl; 620*789Sahrens oldaclp = aclp->z_acl; 621*789Sahrens (void) memmove(to, from, 622*789Sahrens sizeof (ace_t) * aclp->z_acl_count); 623*789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 624*789Sahrens } else { 625*789Sahrens from = aclp->z_acl; 626*789Sahrens to = aclp->z_acl; 627*789Sahrens } 628*789Sahrens 629*789Sahrens 630*789Sahrens (void) memmove(&to[i + 1], &from[i], 631*789Sahrens sizeof (ace_t) * (aclp->z_acl_count - i)); 632*789Sahrens 633*789Sahrens if (oldaclp) { 634*789Sahrens aclp->z_acl = to; 635*789Sahrens oldslots = aclp->z_slots; 636*789Sahrens aclp->z_slots = aclp->z_acl_count + OGE_PAD; 637*789Sahrens if (need_free) 638*789Sahrens kmem_free(oldaclp, ZFS_ACL_SIZE(oldslots)); 639*789Sahrens } 640*789Sahrens 641*789Sahrens } 642*789Sahrens 643*789Sahrens /* 644*789Sahrens * Prepend deny ACE 645*789Sahrens */ 646*789Sahrens static void 647*789Sahrens zfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, int i, 648*789Sahrens mode_t mode) 649*789Sahrens { 650*789Sahrens ace_t *acep; 651*789Sahrens 652*789Sahrens zfs_acl_prepend(aclp, i); 653*789Sahrens 654*789Sahrens acep = aclp->z_acl; 655*789Sahrens zfs_set_ace(&acep[i], 0, DENY, acep[i + 1].a_who, 656*789Sahrens (acep[i + 1].a_flags & 0xf040)); 657*789Sahrens zfs_acl_prepend_fixup(&acep[i], &acep[i+1], mode, zp->z_phys->zp_uid); 658*789Sahrens aclp->z_acl_count++; 659*789Sahrens } 660*789Sahrens 661*789Sahrens /* 662*789Sahrens * Split an inherited ACE into inherit_only ACE 663*789Sahrens * and original ACE with inheritance flags stripped off. 664*789Sahrens */ 665*789Sahrens static void 666*789Sahrens zfs_acl_split_ace(zfs_acl_t *aclp, int i) 667*789Sahrens { 668*789Sahrens ace_t *acep = aclp->z_acl; 669*789Sahrens 670*789Sahrens zfs_acl_prepend(aclp, i); 671*789Sahrens acep = aclp->z_acl; 672*789Sahrens acep[i] = acep[i + 1]; 673*789Sahrens acep[i].a_flags |= ACE_INHERIT_ONLY_ACE; 674*789Sahrens acep[i + 1].a_flags &= ~ALL_INHERIT; 675*789Sahrens aclp->z_acl_count++; 676*789Sahrens } 677*789Sahrens 678*789Sahrens /* 679*789Sahrens * Are ACES started at index i, the canonical six ACES? 680*789Sahrens */ 681*789Sahrens static int 682*789Sahrens zfs_have_canonical_six(zfs_acl_t *aclp, int i) 683*789Sahrens { 684*789Sahrens ace_t *acep = aclp->z_acl; 685*789Sahrens 686*789Sahrens if ((zfs_acl_ace_match(&acep[i], 687*789Sahrens DENY, ACE_OWNER, 0) && 688*789Sahrens zfs_acl_ace_match(&acep[i + 1], ALLOW, ACE_OWNER, 689*789Sahrens OWNER_ALLOW_MASK) && zfs_acl_ace_match(&acep[i + 2], 690*789Sahrens DENY, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 3], 691*789Sahrens ALLOW, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 4], 692*789Sahrens DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) && 693*789Sahrens zfs_acl_ace_match(&acep[i + 5], ALLOW, ACE_EVERYONE, 694*789Sahrens EVERYONE_ALLOW_MASK))) { 695*789Sahrens return (1); 696*789Sahrens } else { 697*789Sahrens return (0); 698*789Sahrens } 699*789Sahrens } 700*789Sahrens 701*789Sahrens /* 702*789Sahrens * Apply step 1g, to group entries 703*789Sahrens * 704*789Sahrens * Need to deal with corner case where group may have 705*789Sahrens * greater permissions than owner. If so then limit 706*789Sahrens * group permissions, based on what extra permissions 707*789Sahrens * group has. 708*789Sahrens */ 709*789Sahrens static void 710*789Sahrens zfs_fixup_group_entries(ace_t *acep, mode_t mode) 711*789Sahrens { 712*789Sahrens mode_t extramode = (mode >> 3) & 07; 713*789Sahrens mode_t ownermode = (mode >> 6); 714*789Sahrens 715*789Sahrens if (acep[0].a_flags & ACE_IDENTIFIER_GROUP) { 716*789Sahrens 717*789Sahrens extramode &= ~ownermode; 718*789Sahrens 719*789Sahrens if (extramode) { 720*789Sahrens if (extramode & 04) { 721*789Sahrens acep[0].a_access_mask &= ~ACE_READ_DATA; 722*789Sahrens acep[1].a_access_mask &= ~ACE_READ_DATA; 723*789Sahrens } 724*789Sahrens if (extramode & 02) { 725*789Sahrens acep[0].a_access_mask &= 726*789Sahrens ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 727*789Sahrens acep[1].a_access_mask &= 728*789Sahrens ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 729*789Sahrens } 730*789Sahrens if (extramode & 01) { 731*789Sahrens acep[0].a_access_mask &= ~ACE_EXECUTE; 732*789Sahrens acep[1].a_access_mask &= ~ACE_EXECUTE; 733*789Sahrens } 734*789Sahrens } 735*789Sahrens } 736*789Sahrens } 737*789Sahrens 738*789Sahrens /* 739*789Sahrens * Apply the chmod algorithm as described 740*789Sahrens * in PSARC/2002/240 741*789Sahrens */ 742*789Sahrens static int 743*789Sahrens zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp, 744*789Sahrens dmu_tx_t *tx) 745*789Sahrens { 746*789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 747*789Sahrens ace_t *acep; 748*789Sahrens int i; 749*789Sahrens int error; 750*789Sahrens int entry_type; 751*789Sahrens int reuse_deny; 752*789Sahrens int need_canonical_six = 1; 753*789Sahrens 754*789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 755*789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 756*789Sahrens 757*789Sahrens i = 0; 758*789Sahrens while (i < aclp->z_acl_count) { 759*789Sahrens acep = aclp->z_acl; 760*789Sahrens entry_type = (acep[i].a_flags & 0xf040); 761*789Sahrens 762*789Sahrens if ((acep[i].a_type != ALLOW && acep[i].a_type != DENY) || 763*789Sahrens (acep[i].a_flags & ACE_INHERIT_ONLY_ACE)) { 764*789Sahrens i++; 765*789Sahrens continue; 766*789Sahrens } 767*789Sahrens 768*789Sahrens 769*789Sahrens if (zfsvfs->z_acl_mode == DISCARD) { 770*789Sahrens zfs_ace_remove(aclp, i); 771*789Sahrens continue; 772*789Sahrens } 773*789Sahrens 774*789Sahrens /* 775*789Sahrens * Need to split ace into two? 776*789Sahrens */ 777*789Sahrens if ((acep[i].a_flags & (ACE_FILE_INHERIT_ACE| 778*789Sahrens ACE_DIRECTORY_INHERIT_ACE)) && 779*789Sahrens (!(acep[i].a_flags & ACE_INHERIT_ONLY_ACE))) { 780*789Sahrens zfs_acl_split_ace(aclp, i); 781*789Sahrens i++; 782*789Sahrens continue; 783*789Sahrens } 784*789Sahrens 785*789Sahrens if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE || 786*789Sahrens (entry_type == OWNING_GROUP)) { 787*789Sahrens acep[i].a_access_mask &= ~OGE_CLEAR; 788*789Sahrens i++; 789*789Sahrens continue; 790*789Sahrens 791*789Sahrens } else { 792*789Sahrens if (acep[i].a_type == ALLOW) { 793*789Sahrens 794*789Sahrens /* 795*789Sahrens * Check preceding ACE if any, to see 796*789Sahrens * if we need to prepend a DENY ACE. 797*789Sahrens * This is only applicable when the acl_mode 798*789Sahrens * property == groupmask. 799*789Sahrens */ 800*789Sahrens if (zfsvfs->z_acl_mode == GROUPMASK) { 801*789Sahrens 802*789Sahrens reuse_deny = zfs_reuse_deny(acep, i); 803*789Sahrens 804*789Sahrens if (reuse_deny == B_FALSE) { 805*789Sahrens zfs_acl_prepend_deny(zp, aclp, 806*789Sahrens i, mode); 807*789Sahrens i++; 808*789Sahrens acep = aclp->z_acl; 809*789Sahrens } else { 810*789Sahrens zfs_acl_prepend_fixup( 811*789Sahrens &acep[i - 1], 812*789Sahrens &acep[i], mode, 813*789Sahrens zp->z_phys->zp_uid); 814*789Sahrens } 815*789Sahrens zfs_fixup_group_entries(&acep[i - 1], 816*789Sahrens mode); 817*789Sahrens } 818*789Sahrens } 819*789Sahrens i++; 820*789Sahrens } 821*789Sahrens } 822*789Sahrens 823*789Sahrens /* 824*789Sahrens * Check out last six aces, if we have six. 825*789Sahrens */ 826*789Sahrens 827*789Sahrens if (aclp->z_acl_count >= 6) { 828*789Sahrens i = aclp->z_acl_count - 6; 829*789Sahrens 830*789Sahrens if (zfs_have_canonical_six(aclp, i)) { 831*789Sahrens need_canonical_six = 0; 832*789Sahrens } 833*789Sahrens } 834*789Sahrens 835*789Sahrens if (need_canonical_six) { 836*789Sahrens 837*789Sahrens zfs_acl_append(aclp, 6); 838*789Sahrens i = aclp->z_acl_count; 839*789Sahrens acep = aclp->z_acl; 840*789Sahrens zfs_set_ace(&acep[i++], 0, DENY, -1, ACE_OWNER); 841*789Sahrens zfs_set_ace(&acep[i++], OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER); 842*789Sahrens zfs_set_ace(&acep[i++], 0, DENY, -1, OWNING_GROUP); 843*789Sahrens zfs_set_ace(&acep[i++], 0, ALLOW, -1, OWNING_GROUP); 844*789Sahrens zfs_set_ace(&acep[i++], EVERYONE_DENY_MASK, 845*789Sahrens DENY, -1, ACE_EVERYONE); 846*789Sahrens zfs_set_ace(&acep[i++], EVERYONE_ALLOW_MASK, 847*789Sahrens ALLOW, -1, ACE_EVERYONE); 848*789Sahrens aclp->z_acl_count += 6; 849*789Sahrens } 850*789Sahrens 851*789Sahrens zfs_acl_fixup_canonical_six(aclp, mode); 852*789Sahrens 853*789Sahrens zp->z_phys->zp_mode = mode; 854*789Sahrens error = zfs_aclset_common(zp, aclp, tx, NULL); 855*789Sahrens return (error); 856*789Sahrens } 857*789Sahrens 858*789Sahrens 859*789Sahrens int 860*789Sahrens zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx) 861*789Sahrens { 862*789Sahrens zfs_acl_t *aclp; 863*789Sahrens int error; 864*789Sahrens 865*789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 866*789Sahrens mutex_enter(&zp->z_acl_lock); 867*789Sahrens aclp = zfs_acl_node_read(zp); 868*789Sahrens error = zfs_acl_chmod(zp, mode, aclp, tx); 869*789Sahrens mutex_exit(&zp->z_acl_lock); 870*789Sahrens zfs_acl_free(aclp); 871*789Sahrens return (error); 872*789Sahrens } 873*789Sahrens 874*789Sahrens /* 875*789Sahrens * strip off write_owner and write_acl 876*789Sahrens */ 877*789Sahrens static void 878*789Sahrens zfs_securemode_update(zfsvfs_t *zfsvfs, ace_t *acep) 879*789Sahrens { 880*789Sahrens if ((zfsvfs->z_acl_inherit == SECURE) && 881*789Sahrens acep->a_type == ALLOW) 882*789Sahrens acep->a_access_mask &= ~SECURE_NO_INHERIT; 883*789Sahrens } 884*789Sahrens 885*789Sahrens /* 886*789Sahrens * inherit inheritable ACEs from parent 887*789Sahrens */ 888*789Sahrens static zfs_acl_t * 889*789Sahrens zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp) 890*789Sahrens { 891*789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 892*789Sahrens ace_t *pacep; 893*789Sahrens ace_t *acep; 894*789Sahrens int ace_cnt = 0; 895*789Sahrens int pace_cnt; 896*789Sahrens int i, j; 897*789Sahrens zfs_acl_t *aclp = NULL; 898*789Sahrens 899*789Sahrens i = j = 0; 900*789Sahrens pace_cnt = paclp->z_acl_count; 901*789Sahrens pacep = paclp->z_acl; 902*789Sahrens if (zfsvfs->z_acl_inherit != DISCARD) { 903*789Sahrens for (i = 0; i != pace_cnt; i++) { 904*789Sahrens 905*789Sahrens if (zfsvfs->z_acl_inherit == NOALLOW && 906*789Sahrens pacep[i].a_type == ALLOW) 907*789Sahrens continue; 908*789Sahrens 909*789Sahrens if (zfs_ace_can_use(zp, &pacep[i])) { 910*789Sahrens ace_cnt++; 911*789Sahrens if (!(pacep[i].a_flags & 912*789Sahrens ACE_NO_PROPAGATE_INHERIT_ACE)) 913*789Sahrens ace_cnt++; 914*789Sahrens } 915*789Sahrens } 916*789Sahrens } 917*789Sahrens 918*789Sahrens aclp = zfs_acl_alloc(ace_cnt + OGE_PAD); 919*789Sahrens if (ace_cnt && zfsvfs->z_acl_inherit != DISCARD) { 920*789Sahrens acep = aclp->z_acl; 921*789Sahrens pacep = paclp->z_acl; 922*789Sahrens for (i = 0; i != pace_cnt; i++) { 923*789Sahrens 924*789Sahrens if (zfsvfs->z_acl_inherit == NOALLOW && 925*789Sahrens pacep[i].a_type == ALLOW) 926*789Sahrens continue; 927*789Sahrens 928*789Sahrens if (zfs_ace_can_use(zp, &pacep[i])) { 929*789Sahrens /* 930*789Sahrens * Now create entry for inherited ace 931*789Sahrens */ 932*789Sahrens acep[j] = pacep[i]; 933*789Sahrens 934*789Sahrens if (pacep[i].a_flags & 935*789Sahrens ACE_NO_PROPAGATE_INHERIT_ACE) { 936*789Sahrens acep[j].a_flags &= ~ALL_INHERIT; 937*789Sahrens j++; 938*789Sahrens continue; 939*789Sahrens } 940*789Sahrens 941*789Sahrens if (pacep[i].a_type != ALLOW && 942*789Sahrens pacep[i].a_type != DENY) { 943*789Sahrens zfs_securemode_update(zfsvfs, &acep[j]); 944*789Sahrens j++; 945*789Sahrens continue; 946*789Sahrens } 947*789Sahrens 948*789Sahrens if (ZTOV(zp)->v_type != VDIR) { 949*789Sahrens acep[j].a_flags &= ~ALL_INHERIT; 950*789Sahrens zfs_securemode_update(zfsvfs, &acep[j]); 951*789Sahrens j++; 952*789Sahrens continue; 953*789Sahrens } 954*789Sahrens 955*789Sahrens ASSERT(ZTOV(zp)->v_type == VDIR); 956*789Sahrens 957*789Sahrens /* 958*789Sahrens * If we are inheriting an ACE targeted for 959*789Sahrens * only files, then leave the inherit_only 960*789Sahrens * one for future propagation. 961*789Sahrens */ 962*789Sahrens if ((acep[j].a_flags & (ACE_FILE_INHERIT_ACE | 963*789Sahrens ACE_DIRECTORY_INHERIT_ACE)) != 964*789Sahrens ACE_FILE_INHERIT_ACE) 965*789Sahrens acep[j].a_flags &= 966*789Sahrens ~ACE_INHERIT_ONLY_ACE; 967*789Sahrens 968*789Sahrens zfs_securemode_update(zfsvfs, &acep[j]); 969*789Sahrens j++; 970*789Sahrens } 971*789Sahrens } 972*789Sahrens } 973*789Sahrens aclp->z_acl_count = j; 974*789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 975*789Sahrens 976*789Sahrens return (aclp); 977*789Sahrens } 978*789Sahrens 979*789Sahrens /* 980*789Sahrens * Create file system object initial permissions 981*789Sahrens * including inheritable ACEs. 982*789Sahrens */ 983*789Sahrens void 984*789Sahrens zfs_perm_init(znode_t *zp, znode_t *parent, int flag, 985*789Sahrens vattr_t *vap, dmu_tx_t *tx, cred_t *cr) 986*789Sahrens { 987*789Sahrens uint64_t mode; 988*789Sahrens uid_t uid; 989*789Sahrens gid_t gid; 990*789Sahrens int error; 991*789Sahrens int pull_down; 992*789Sahrens zfs_acl_t *aclp, *paclp; 993*789Sahrens 994*789Sahrens mode = MAKEIMODE(vap->va_type, vap->va_mode); 995*789Sahrens 996*789Sahrens /* 997*789Sahrens * Determine uid and gid. 998*789Sahrens */ 999*789Sahrens if ((flag & (IS_ROOT_NODE | IS_REPLAY)) || 1000*789Sahrens ((flag & IS_XATTR) && (vap->va_type == VDIR))) { 1001*789Sahrens uid = vap->va_uid; 1002*789Sahrens gid = vap->va_gid; 1003*789Sahrens } else { 1004*789Sahrens uid = crgetuid(cr); 1005*789Sahrens if ((vap->va_mask & AT_GID) && 1006*789Sahrens ((vap->va_gid == parent->z_phys->zp_gid) || 1007*789Sahrens groupmember(vap->va_gid, cr) || 1008*789Sahrens secpolicy_vnode_create_gid(cr))) 1009*789Sahrens gid = vap->va_gid; 1010*789Sahrens else 1011*789Sahrens gid = (parent->z_phys->zp_mode & S_ISGID) ? 1012*789Sahrens parent->z_phys->zp_gid : crgetgid(cr); 1013*789Sahrens } 1014*789Sahrens 1015*789Sahrens /* 1016*789Sahrens * If we're creating a directory, and the parent directory has the 1017*789Sahrens * set-GID bit set, set in on the new directory. 1018*789Sahrens * Otherwise, if the user is neither privileged nor a member of the 1019*789Sahrens * file's new group, clear the file's set-GID bit. 1020*789Sahrens */ 1021*789Sahrens 1022*789Sahrens if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR)) 1023*789Sahrens mode |= S_ISGID; 1024*789Sahrens else { 1025*789Sahrens if ((mode & S_ISGID) && 1026*789Sahrens secpolicy_vnode_setids_setgids(cr, gid) != 0) 1027*789Sahrens mode &= ~S_ISGID; 1028*789Sahrens } 1029*789Sahrens 1030*789Sahrens zp->z_phys->zp_uid = uid; 1031*789Sahrens zp->z_phys->zp_gid = gid; 1032*789Sahrens zp->z_phys->zp_mode = mode; 1033*789Sahrens 1034*789Sahrens mutex_enter(&parent->z_lock); 1035*789Sahrens pull_down = (parent->z_phys->zp_flags & ZFS_INHERIT_ACE); 1036*789Sahrens if (pull_down) { 1037*789Sahrens mutex_enter(&parent->z_acl_lock); 1038*789Sahrens paclp = zfs_acl_node_read(parent); 1039*789Sahrens mutex_exit(&parent->z_acl_lock); 1040*789Sahrens aclp = zfs_acl_inherit(zp, paclp); 1041*789Sahrens zfs_acl_free(paclp); 1042*789Sahrens } else { 1043*789Sahrens aclp = zfs_acl_alloc(6); 1044*789Sahrens } 1045*789Sahrens mutex_exit(&parent->z_lock); 1046*789Sahrens mutex_enter(&zp->z_lock); 1047*789Sahrens mutex_enter(&zp->z_acl_lock); 1048*789Sahrens error = zfs_acl_chmod(zp, mode, aclp, tx); 1049*789Sahrens mutex_exit(&zp->z_lock); 1050*789Sahrens mutex_exit(&zp->z_acl_lock); 1051*789Sahrens ASSERT3U(error, ==, 0); 1052*789Sahrens zfs_acl_free(aclp); 1053*789Sahrens } 1054*789Sahrens 1055*789Sahrens /* 1056*789Sahrens * Can use be used for inheritance 1057*789Sahrens */ 1058*789Sahrens static int 1059*789Sahrens zfs_ace_can_use(znode_t *zp, ace_t *acep) 1060*789Sahrens { 1061*789Sahrens int vtype = ZTOV(zp)->v_type; 1062*789Sahrens 1063*789Sahrens int iflags = (acep->a_flags & 0xf); 1064*789Sahrens 1065*789Sahrens if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) 1066*789Sahrens return (1); 1067*789Sahrens 1068*789Sahrens else if (iflags & ACE_FILE_INHERIT_ACE) 1069*789Sahrens return (1); 1070*789Sahrens 1071*789Sahrens return (0); 1072*789Sahrens } 1073*789Sahrens 1074*789Sahrens /* 1075*789Sahrens * Retrieve a files ACL 1076*789Sahrens */ 1077*789Sahrens int 1078*789Sahrens zfs_getacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr) 1079*789Sahrens { 1080*789Sahrens zfs_acl_t *aclp; 1081*789Sahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); 1082*789Sahrens int error; 1083*789Sahrens 1084*789Sahrens if (error = zfs_zaccess(zp, ACE_READ_ACL, cr)) { 1085*789Sahrens /* 1086*789Sahrens * If owner of file then allow reading of the 1087*789Sahrens * ACL. 1088*789Sahrens */ 1089*789Sahrens if (crgetuid(cr) != zp->z_phys->zp_uid) 1090*789Sahrens return (error); 1091*789Sahrens } 1092*789Sahrens 1093*789Sahrens if (mask == 0) 1094*789Sahrens return (ENOSYS); 1095*789Sahrens 1096*789Sahrens mutex_enter(&zp->z_acl_lock); 1097*789Sahrens 1098*789Sahrens aclp = zfs_acl_node_read(zp); 1099*789Sahrens 1100*789Sahrens if (mask & VSA_ACECNT) { 1101*789Sahrens vsecp->vsa_aclcnt = aclp->z_acl_count; 1102*789Sahrens } 1103*789Sahrens 1104*789Sahrens if (mask & VSA_ACE) { 1105*789Sahrens vsecp->vsa_aclentp = kmem_alloc(aclp->z_acl_count * 1106*789Sahrens sizeof (ace_t), KM_SLEEP); 1107*789Sahrens bcopy(aclp->z_acl, vsecp->vsa_aclentp, 1108*789Sahrens aclp->z_acl_count * sizeof (ace_t)); 1109*789Sahrens } 1110*789Sahrens 1111*789Sahrens mutex_exit(&zp->z_acl_lock); 1112*789Sahrens 1113*789Sahrens zfs_acl_free(aclp); 1114*789Sahrens 1115*789Sahrens return (0); 1116*789Sahrens } 1117*789Sahrens 1118*789Sahrens /* 1119*789Sahrens * Set a files ACL 1120*789Sahrens */ 1121*789Sahrens int 1122*789Sahrens zfs_setacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr) 1123*789Sahrens { 1124*789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1125*789Sahrens zilog_t *zilog = zfsvfs->z_log; 1126*789Sahrens ace_t *acep = vsecp->vsa_aclentp; 1127*789Sahrens int aclcnt = vsecp->vsa_aclcnt; 1128*789Sahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); 1129*789Sahrens dmu_tx_t *tx; 1130*789Sahrens int error; 1131*789Sahrens int inherit; 1132*789Sahrens zfs_acl_t *aclp; 1133*789Sahrens uint64_t seq = 0; 1134*789Sahrens 1135*789Sahrens if (mask == 0) 1136*789Sahrens return (EINVAL); 1137*789Sahrens 1138*789Sahrens if (!zfs_acl_valid(zp, acep, aclcnt, &inherit)) 1139*789Sahrens return (EINVAL); 1140*789Sahrens top: 1141*789Sahrens error = zfs_zaccess_v4_perm(zp, ACE_WRITE_ACL, cr); 1142*789Sahrens if (error == EACCES || error == ACCESS_UNDETERMINED) { 1143*789Sahrens if ((error = secpolicy_vnode_setdac(cr, 1144*789Sahrens zp->z_phys->zp_uid)) != 0) { 1145*789Sahrens return (error); 1146*789Sahrens } 1147*789Sahrens } else if (error) { 1148*789Sahrens return (error == EROFS ? error : EPERM); 1149*789Sahrens } 1150*789Sahrens 1151*789Sahrens mutex_enter(&zp->z_lock); 1152*789Sahrens mutex_enter(&zp->z_acl_lock); 1153*789Sahrens 1154*789Sahrens tx = dmu_tx_create(zfsvfs->z_os); 1155*789Sahrens dmu_tx_hold_bonus(tx, zp->z_id); 1156*789Sahrens 1157*789Sahrens if (zp->z_phys->zp_acl.z_acl_extern_obj) { 1158*789Sahrens dmu_tx_hold_write(tx, zp->z_phys->zp_acl.z_acl_extern_obj, 1159*789Sahrens 0, ZFS_ACL_SIZE(aclcnt)); 1160*789Sahrens } else if (aclcnt > ACE_SLOT_CNT) { 1161*789Sahrens dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, ZFS_ACL_SIZE(aclcnt)); 1162*789Sahrens } 1163*789Sahrens 1164*789Sahrens error = dmu_tx_assign(tx, zfsvfs->z_assign); 1165*789Sahrens if (error) { 1166*789Sahrens dmu_tx_abort(tx); 1167*789Sahrens 1168*789Sahrens mutex_exit(&zp->z_acl_lock); 1169*789Sahrens mutex_exit(&zp->z_lock); 1170*789Sahrens 1171*789Sahrens if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { 1172*789Sahrens txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0); 1173*789Sahrens goto top; 1174*789Sahrens } 1175*789Sahrens return (error); 1176*789Sahrens } 1177*789Sahrens 1178*789Sahrens aclp = zfs_acl_alloc(aclcnt); 1179*789Sahrens bcopy(acep, aclp->z_acl, sizeof (ace_t) * aclcnt); 1180*789Sahrens aclp->z_acl_count = aclcnt; 1181*789Sahrens error = zfs_aclset_common(zp, aclp, tx, &inherit); 1182*789Sahrens ASSERT(error == 0); 1183*789Sahrens 1184*789Sahrens zfs_acl_free(aclp); 1185*789Sahrens seq = zfs_log_acl(zilog, tx, TX_ACL, zp, aclcnt, acep); 1186*789Sahrens dmu_tx_commit(tx); 1187*789Sahrens done: 1188*789Sahrens mutex_exit(&zp->z_acl_lock); 1189*789Sahrens mutex_exit(&zp->z_lock); 1190*789Sahrens 1191*789Sahrens zil_commit(zilog, seq, 0); 1192*789Sahrens 1193*789Sahrens return (error); 1194*789Sahrens } 1195*789Sahrens 1196*789Sahrens static int 1197*789Sahrens zfs_ace_access(ace_t *zacep, int mode_wanted, int *working_mode) 1198*789Sahrens { 1199*789Sahrens if ((*working_mode & mode_wanted) == mode_wanted) { 1200*789Sahrens return (0); 1201*789Sahrens } 1202*789Sahrens 1203*789Sahrens if (zacep->a_access_mask & mode_wanted) { 1204*789Sahrens if (zacep->a_type == ALLOW) { 1205*789Sahrens *working_mode |= (mode_wanted & zacep->a_access_mask); 1206*789Sahrens if ((*working_mode & mode_wanted) == mode_wanted) 1207*789Sahrens return (0); 1208*789Sahrens } else if (zacep->a_type == DENY) { 1209*789Sahrens return (EACCES); 1210*789Sahrens } 1211*789Sahrens } 1212*789Sahrens 1213*789Sahrens /* 1214*789Sahrens * haven't been specifcally denied at this point 1215*789Sahrens * so return UNDETERMINED. 1216*789Sahrens */ 1217*789Sahrens 1218*789Sahrens return (ACCESS_UNDETERMINED); 1219*789Sahrens } 1220*789Sahrens 1221*789Sahrens 1222*789Sahrens static int 1223*789Sahrens zfs_zaccess_common(znode_t *zp, int v4_mode, int *working_mode, cred_t *cr) 1224*789Sahrens { 1225*789Sahrens zfs_acl_t *aclp; 1226*789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1227*789Sahrens ace_t *zacep; 1228*789Sahrens gid_t gid; 1229*789Sahrens int mode_wanted = v4_mode; 1230*789Sahrens int cnt; 1231*789Sahrens int i; 1232*789Sahrens int access_deny = ACCESS_UNDETERMINED; 1233*789Sahrens uint_t entry_type; 1234*789Sahrens uid_t uid = crgetuid(cr); 1235*789Sahrens 1236*789Sahrens *working_mode = 0; 1237*789Sahrens 1238*789Sahrens if (zfsvfs->z_assign >= TXG_INITIAL) /* ZIL replay */ 1239*789Sahrens return (0); 1240*789Sahrens 1241*789Sahrens if ((v4_mode & WRITE_MASK) && 1242*789Sahrens (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) && 1243*789Sahrens (!IS_DEVVP(ZTOV(zp)))) { 1244*789Sahrens return (EROFS); 1245*789Sahrens } 1246*789Sahrens 1247*789Sahrens mutex_enter(&zp->z_acl_lock); 1248*789Sahrens 1249*789Sahrens aclp = zfs_acl_node_read(zp); 1250*789Sahrens 1251*789Sahrens zacep = aclp->z_acl; 1252*789Sahrens cnt = aclp->z_acl_count; 1253*789Sahrens 1254*789Sahrens for (i = 0; i != cnt; i++) { 1255*789Sahrens 1256*789Sahrens if (zacep[i].a_flags & ACE_INHERIT_ONLY_ACE) 1257*789Sahrens continue; 1258*789Sahrens 1259*789Sahrens entry_type = (zacep[i].a_flags & 0xf040); 1260*789Sahrens switch (entry_type) { 1261*789Sahrens case ACE_OWNER: 1262*789Sahrens if (uid == zp->z_phys->zp_uid) { 1263*789Sahrens access_deny = zfs_ace_access(&zacep[i], 1264*789Sahrens mode_wanted, working_mode); 1265*789Sahrens } 1266*789Sahrens break; 1267*789Sahrens case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 1268*789Sahrens case ACE_IDENTIFIER_GROUP: 1269*789Sahrens /* 1270*789Sahrens * Owning group gid is in znode not ACL 1271*789Sahrens */ 1272*789Sahrens if (entry_type == (ACE_IDENTIFIER_GROUP | ACE_GROUP)) 1273*789Sahrens gid = zp->z_phys->zp_gid; 1274*789Sahrens else 1275*789Sahrens gid = zacep[i].a_who; 1276*789Sahrens 1277*789Sahrens if (groupmember(gid, cr)) { 1278*789Sahrens access_deny = zfs_ace_access(&zacep[i], 1279*789Sahrens mode_wanted, working_mode); 1280*789Sahrens } 1281*789Sahrens break; 1282*789Sahrens case ACE_EVERYONE: 1283*789Sahrens access_deny = zfs_ace_access(&zacep[i], 1284*789Sahrens mode_wanted, working_mode); 1285*789Sahrens break; 1286*789Sahrens 1287*789Sahrens /* USER Entry */ 1288*789Sahrens default: 1289*789Sahrens if (entry_type == 0) { 1290*789Sahrens if (uid == zacep[i].a_who) { 1291*789Sahrens access_deny = zfs_ace_access(&zacep[i], 1292*789Sahrens mode_wanted, working_mode); 1293*789Sahrens } 1294*789Sahrens break; 1295*789Sahrens } 1296*789Sahrens zfs_acl_free(aclp); 1297*789Sahrens mutex_exit(&zp->z_acl_lock); 1298*789Sahrens return (EIO); 1299*789Sahrens } 1300*789Sahrens 1301*789Sahrens if (access_deny != ACCESS_UNDETERMINED) 1302*789Sahrens break; 1303*789Sahrens 1304*789Sahrens } 1305*789Sahrens 1306*789Sahrens mutex_exit(&zp->z_acl_lock); 1307*789Sahrens zfs_acl_free(aclp); 1308*789Sahrens 1309*789Sahrens return (access_deny); 1310*789Sahrens } 1311*789Sahrens 1312*789Sahrens 1313*789Sahrens /* 1314*789Sahrens * Determine whether Access should be granted/denied, invoking least 1315*789Sahrens * priv subsytem when a deny is determined. 1316*789Sahrens */ 1317*789Sahrens int 1318*789Sahrens zfs_zaccess(znode_t *zp, int mode, cred_t *cr) 1319*789Sahrens { 1320*789Sahrens int working_mode = 0; 1321*789Sahrens int error; 1322*789Sahrens int is_attr; 1323*789Sahrens znode_t *xzp; 1324*789Sahrens znode_t *check_zp = zp; 1325*789Sahrens 1326*789Sahrens is_attr = ((zp->z_phys->zp_flags & ZFS_XATTR) && 1327*789Sahrens (ZTOV(zp)->v_type == VDIR)); 1328*789Sahrens 1329*789Sahrens /* 1330*789Sahrens * If attribute then validate against base file 1331*789Sahrens */ 1332*789Sahrens if (is_attr) { 1333*789Sahrens if ((error = zfs_zget(zp->z_zfsvfs, 1334*789Sahrens zp->z_phys->zp_parent, &xzp)) != 0) { 1335*789Sahrens return (error); 1336*789Sahrens } 1337*789Sahrens check_zp = xzp; 1338*789Sahrens /* 1339*789Sahrens * fixup mode to map to xattr perms 1340*789Sahrens */ 1341*789Sahrens 1342*789Sahrens if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) { 1343*789Sahrens mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 1344*789Sahrens mode |= ACE_WRITE_NAMED_ATTRS; 1345*789Sahrens } 1346*789Sahrens 1347*789Sahrens if (mode & (ACE_READ_DATA|ACE_EXECUTE)) { 1348*789Sahrens mode &= ~(ACE_READ_DATA|ACE_EXECUTE); 1349*789Sahrens mode |= ACE_READ_NAMED_ATTRS; 1350*789Sahrens } 1351*789Sahrens } 1352*789Sahrens 1353*789Sahrens error = zfs_zaccess_common(check_zp, mode, &working_mode, cr); 1354*789Sahrens 1355*789Sahrens if (error == EROFS) { 1356*789Sahrens if (is_attr) 1357*789Sahrens VN_RELE(ZTOV(xzp)); 1358*789Sahrens return (error); 1359*789Sahrens } 1360*789Sahrens 1361*789Sahrens if (error || (working_mode != mode)) { 1362*789Sahrens error = secpolicy_vnode_access(cr, ZTOV(check_zp), 1363*789Sahrens check_zp->z_phys->zp_uid, ~zfs_v4_to_unix(working_mode)); 1364*789Sahrens } 1365*789Sahrens 1366*789Sahrens if (is_attr) 1367*789Sahrens VN_RELE(ZTOV(xzp)); 1368*789Sahrens 1369*789Sahrens return (error); 1370*789Sahrens } 1371*789Sahrens 1372*789Sahrens /* 1373*789Sahrens * Special zaccess function to check for special nfsv4 perm. 1374*789Sahrens * doesn't call secpolicy_vnode_access() for failure, since that 1375*789Sahrens * would probably be the wrong policy function to call. 1376*789Sahrens * instead its up to the caller to handle that situation. 1377*789Sahrens */ 1378*789Sahrens 1379*789Sahrens int 1380*789Sahrens zfs_zaccess_v4_perm(znode_t *zp, int mode, cred_t *cr) 1381*789Sahrens { 1382*789Sahrens int working_mode = 0; 1383*789Sahrens return (zfs_zaccess_common(zp, mode, &working_mode, cr)); 1384*789Sahrens } 1385*789Sahrens 1386*789Sahrens /* 1387*789Sahrens * Translate tradition unix VREAD/VWRITE/VEXEC mode into 1388*789Sahrens * native ACL format and call zfs_zaccess() 1389*789Sahrens */ 1390*789Sahrens int 1391*789Sahrens zfs_zaccess_rwx(znode_t *zp, mode_t mode, cred_t *cr) 1392*789Sahrens { 1393*789Sahrens int v4_mode = zfs_unix_to_v4(mode >> 6); 1394*789Sahrens 1395*789Sahrens return (zfs_zaccess(zp, v4_mode, cr)); 1396*789Sahrens } 1397*789Sahrens 1398*789Sahrens /* 1399*789Sahrens * Determine whether Access should be granted/deny, without 1400*789Sahrens * consulting least priv subsystem. 1401*789Sahrens * 1402*789Sahrens * 1403*789Sahrens * The following chart is the recommended NFSv4 enforcement for 1404*789Sahrens * ability to delete an object. 1405*789Sahrens * 1406*789Sahrens * ------------------------------------------------------- 1407*789Sahrens * | Parent Dir | Target Object Permissions | 1408*789Sahrens * | permissions | | 1409*789Sahrens * ------------------------------------------------------- 1410*789Sahrens * | | ACL Allows | ACL Denies| Delete | 1411*789Sahrens * | | Delete | Delete | unspecified| 1412*789Sahrens * ------------------------------------------------------- 1413*789Sahrens * | ACL Allows | Permit | Permit | Permit | 1414*789Sahrens * | DELETE_CHILD | | 1415*789Sahrens * ------------------------------------------------------- 1416*789Sahrens * | ACL Denies | Permit | Deny | Deny | 1417*789Sahrens * | DELETE_CHILD | | | | 1418*789Sahrens * ------------------------------------------------------- 1419*789Sahrens * | ACL specifies | | | | 1420*789Sahrens * | only allow | Permit | Permit | Permit | 1421*789Sahrens * | write and | | | | 1422*789Sahrens * | execute | | | | 1423*789Sahrens * ------------------------------------------------------- 1424*789Sahrens * | ACL denies | | | | 1425*789Sahrens * | write and | Permit | Deny | Deny | 1426*789Sahrens * | execute | | | | 1427*789Sahrens * ------------------------------------------------------- 1428*789Sahrens * ^ 1429*789Sahrens * | 1430*789Sahrens * No search privilege, can't even look up file? 1431*789Sahrens * 1432*789Sahrens */ 1433*789Sahrens int 1434*789Sahrens zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) 1435*789Sahrens { 1436*789Sahrens int dzp_working_mode = 0; 1437*789Sahrens int zp_working_mode = 0; 1438*789Sahrens int dzp_error, zp_error; 1439*789Sahrens 1440*789Sahrens /* 1441*789Sahrens * Arghh, this check is going to require a couple of questions 1442*789Sahrens * to be asked. We want specific DELETE permissions to 1443*789Sahrens * take precedence over WRITE/EXECUTE. We don't 1444*789Sahrens * want an ACL such as this to mess us up. 1445*789Sahrens * user:sloar:write_data:deny,user:sloar:delete:allow 1446*789Sahrens * 1447*789Sahrens * However, deny permissions may ultimately be overridden 1448*789Sahrens * by secpolicy_vnode_access(). 1449*789Sahrens */ 1450*789Sahrens 1451*789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD, 1452*789Sahrens &dzp_working_mode, cr); 1453*789Sahrens zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode, cr); 1454*789Sahrens 1455*789Sahrens if (dzp_error == EROFS || zp_error == EROFS) 1456*789Sahrens return (dzp_error); 1457*789Sahrens 1458*789Sahrens /* 1459*789Sahrens * First handle the first row 1460*789Sahrens */ 1461*789Sahrens if (dzp_working_mode & ACE_DELETE_CHILD) 1462*789Sahrens return (0); 1463*789Sahrens 1464*789Sahrens /* 1465*789Sahrens * Second row 1466*789Sahrens */ 1467*789Sahrens 1468*789Sahrens if (zp_working_mode & ACE_DELETE) 1469*789Sahrens return (0); 1470*789Sahrens 1471*789Sahrens /* 1472*789Sahrens * Third Row 1473*789Sahrens */ 1474*789Sahrens 1475*789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_WRITE_DATA|ACE_EXECUTE, 1476*789Sahrens &dzp_working_mode, cr); 1477*789Sahrens 1478*789Sahrens if (dzp_error == EROFS) 1479*789Sahrens return (dzp_error); 1480*789Sahrens 1481*789Sahrens if (dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) 1482*789Sahrens return (0); 1483*789Sahrens 1484*789Sahrens /* 1485*789Sahrens * Fourth Row 1486*789Sahrens */ 1487*789Sahrens 1488*789Sahrens if (((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) == 0) && 1489*789Sahrens (zp_working_mode & ACE_DELETE)) 1490*789Sahrens return (0); 1491*789Sahrens 1492*789Sahrens return (secpolicy_vnode_access(cr, ZTOV(zp), dzp->z_phys->zp_uid, 1493*789Sahrens S_IWRITE|S_IEXEC)); 1494*789Sahrens } 1495*789Sahrens 1496*789Sahrens int 1497*789Sahrens zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, 1498*789Sahrens znode_t *tzp, cred_t *cr) 1499*789Sahrens { 1500*789Sahrens int add_perm; 1501*789Sahrens int error; 1502*789Sahrens 1503*789Sahrens add_perm = (ZTOV(szp)->v_type == VDIR) ? 1504*789Sahrens ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE; 1505*789Sahrens 1506*789Sahrens /* 1507*789Sahrens * Rename permissions are combination of delete permission + 1508*789Sahrens * add file/subdir permission. 1509*789Sahrens */ 1510*789Sahrens 1511*789Sahrens /* 1512*789Sahrens * first make sure we do the delete portion. 1513*789Sahrens * 1514*789Sahrens * If that succeeds then check for add_file/add_subdir permissions 1515*789Sahrens */ 1516*789Sahrens 1517*789Sahrens if (error = zfs_zaccess_delete(sdzp, szp, cr)) 1518*789Sahrens return (error); 1519*789Sahrens 1520*789Sahrens /* 1521*789Sahrens * If we have a tzp, see if we can delete it? 1522*789Sahrens */ 1523*789Sahrens if (tzp) { 1524*789Sahrens if (error = zfs_zaccess_delete(tdzp, tzp, cr)) 1525*789Sahrens return (error); 1526*789Sahrens } 1527*789Sahrens 1528*789Sahrens /* 1529*789Sahrens * Now check for add permissions 1530*789Sahrens */ 1531*789Sahrens if (error = zfs_zaccess(sdzp, add_perm, cr)) 1532*789Sahrens return (error); 1533*789Sahrens 1534*789Sahrens error = zfs_sticky_remove_access(sdzp, szp, cr); 1535*789Sahrens 1536*789Sahrens return (error); 1537*789Sahrens } 1538