1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 51544Seschrock * Common Development and Distribution License (the "License"). 61544Seschrock * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 22*4300Smarks * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 27789Sahrens 28789Sahrens #include <sys/types.h> 29789Sahrens #include <sys/param.h> 30789Sahrens #include <sys/time.h> 31789Sahrens #include <sys/systm.h> 32789Sahrens #include <sys/sysmacros.h> 33789Sahrens #include <sys/resource.h> 34789Sahrens #include <sys/vfs.h> 35789Sahrens #include <sys/vnode.h> 36789Sahrens #include <sys/file.h> 37789Sahrens #include <sys/stat.h> 38789Sahrens #include <sys/kmem.h> 39789Sahrens #include <sys/cmn_err.h> 40789Sahrens #include <sys/errno.h> 41789Sahrens #include <sys/unistd.h> 421576Smarks #include <sys/sdt.h> 43789Sahrens #include <sys/fs/zfs.h> 44789Sahrens #include <sys/mode.h> 45789Sahrens #include <sys/policy.h> 46789Sahrens #include <sys/zfs_znode.h> 47789Sahrens #include <sys/zfs_acl.h> 48789Sahrens #include <sys/zfs_dir.h> 49789Sahrens #include <sys/zfs_vfsops.h> 50789Sahrens #include <sys/dmu.h> 51789Sahrens #include <sys/zap.h> 52789Sahrens #include <util/qsort.h> 53789Sahrens #include "fs/fs_subr.h" 54789Sahrens #include <acl/acl_common.h> 55789Sahrens 56789Sahrens #define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE 57789Sahrens #define DENY ACE_ACCESS_DENIED_ACE_TYPE 58789Sahrens 59789Sahrens #define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) 60789Sahrens #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \ 61789Sahrens ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE) 62789Sahrens #define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \ 63789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 64789Sahrens #define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \ 65789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS) 66789Sahrens #define WRITE_MASK (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS| \ 67789Sahrens ACE_WRITE_ATTRIBUTES|ACE_WRITE_ACL|ACE_WRITE_OWNER) 68789Sahrens 69789Sahrens #define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 70789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 71789Sahrens 72789Sahrens #define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \ 73789Sahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE) 74789Sahrens 75789Sahrens #define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \ 76789Sahrens ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE) 77789Sahrens 781576Smarks #define SECURE_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER) 79789Sahrens 80789Sahrens #define OGE_PAD 6 /* traditional owner/group/everyone ACES */ 81789Sahrens 82789Sahrens static int zfs_ace_can_use(znode_t *zp, ace_t *); 83789Sahrens 84789Sahrens static zfs_acl_t * 85789Sahrens zfs_acl_alloc(int slots) 86789Sahrens { 87789Sahrens zfs_acl_t *aclp; 88789Sahrens 89789Sahrens aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP); 90789Sahrens if (slots != 0) { 91789Sahrens aclp->z_acl = kmem_alloc(ZFS_ACL_SIZE(slots), KM_SLEEP); 92789Sahrens aclp->z_acl_count = 0; 93789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 94789Sahrens } else { 95789Sahrens aclp->z_state = 0; 96789Sahrens } 97789Sahrens aclp->z_slots = slots; 98789Sahrens return (aclp); 99789Sahrens } 100789Sahrens 101789Sahrens void 102789Sahrens zfs_acl_free(zfs_acl_t *aclp) 103789Sahrens { 104789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) { 105789Sahrens kmem_free(aclp->z_acl, ZFS_ACL_SIZE(aclp->z_slots)); 106789Sahrens } 107789Sahrens kmem_free(aclp, sizeof (zfs_acl_t)); 108789Sahrens } 109789Sahrens 110789Sahrens static uint32_t 111789Sahrens zfs_v4_to_unix(uint32_t access_mask) 112789Sahrens { 113789Sahrens uint32_t new_mask = 0; 114789Sahrens 1151576Smarks /* 1161576Smarks * This is used for mapping v4 permissions into permissions 1171576Smarks * that can be passed to secpolicy_vnode_access() 1181576Smarks */ 1191576Smarks if (access_mask & (ACE_READ_DATA | ACE_LIST_DIRECTORY | 1201576Smarks ACE_READ_ATTRIBUTES | ACE_READ_ACL)) 121789Sahrens new_mask |= S_IROTH; 1221576Smarks if (access_mask & (ACE_WRITE_DATA | ACE_APPEND_DATA | 1231576Smarks ACE_WRITE_ATTRIBUTES | ACE_ADD_FILE | ACE_WRITE_NAMED_ATTRS)) 124789Sahrens new_mask |= S_IWOTH; 1251576Smarks if (access_mask & (ACE_EXECUTE | ACE_READ_NAMED_ATTRS)) 126789Sahrens new_mask |= S_IXOTH; 127789Sahrens 128789Sahrens return (new_mask); 129789Sahrens } 130789Sahrens 131789Sahrens /* 132789Sahrens * Convert unix access mask to v4 access mask 133789Sahrens */ 134789Sahrens static uint32_t 135789Sahrens zfs_unix_to_v4(uint32_t access_mask) 136789Sahrens { 137789Sahrens uint32_t new_mask = 0; 138789Sahrens 139789Sahrens if (access_mask & 01) 140789Sahrens new_mask |= (ACE_EXECUTE); 141789Sahrens if (access_mask & 02) { 142789Sahrens new_mask |= (ACE_WRITE_DATA); 143789Sahrens } if (access_mask & 04) { 144789Sahrens new_mask |= ACE_READ_DATA; 145789Sahrens } 146789Sahrens return (new_mask); 147789Sahrens } 148789Sahrens 149789Sahrens static void 150789Sahrens zfs_set_ace(ace_t *zacep, uint32_t access_mask, int access_type, 151789Sahrens uid_t uid, int entry_type) 152789Sahrens { 153789Sahrens zacep->a_access_mask = access_mask; 154789Sahrens zacep->a_type = access_type; 155789Sahrens zacep->a_who = uid; 156789Sahrens zacep->a_flags = entry_type; 157789Sahrens } 158789Sahrens 159789Sahrens static uint64_t 160789Sahrens zfs_mode_compute(znode_t *zp, zfs_acl_t *aclp) 161789Sahrens { 162789Sahrens int i; 163789Sahrens int entry_type; 164789Sahrens mode_t mode = (zp->z_phys->zp_mode & 165789Sahrens (S_IFMT | S_ISUID | S_ISGID | S_ISVTX)); 166789Sahrens mode_t seen = 0; 167789Sahrens ace_t *acep; 168789Sahrens 169789Sahrens for (i = 0, acep = aclp->z_acl; 170789Sahrens i != aclp->z_acl_count; i++, acep++) { 1711576Smarks entry_type = (acep->a_flags & ACE_TYPE_FLAGS); 172789Sahrens if (entry_type == ACE_OWNER) { 173789Sahrens if ((acep->a_access_mask & ACE_READ_DATA) && 174789Sahrens (!(seen & S_IRUSR))) { 175789Sahrens seen |= S_IRUSR; 176789Sahrens if (acep->a_type == ALLOW) { 177789Sahrens mode |= S_IRUSR; 178789Sahrens } 179789Sahrens } 180789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA) && 181789Sahrens (!(seen & S_IWUSR))) { 182789Sahrens seen |= S_IWUSR; 183789Sahrens if (acep->a_type == ALLOW) { 184789Sahrens mode |= S_IWUSR; 185789Sahrens } 186789Sahrens } 187789Sahrens if ((acep->a_access_mask & ACE_EXECUTE) && 188789Sahrens (!(seen & S_IXUSR))) { 189789Sahrens seen |= S_IXUSR; 190789Sahrens if (acep->a_type == ALLOW) { 191789Sahrens mode |= S_IXUSR; 192789Sahrens } 193789Sahrens } 194789Sahrens } else if (entry_type == OWNING_GROUP) { 195789Sahrens if ((acep->a_access_mask & ACE_READ_DATA) && 196789Sahrens (!(seen & S_IRGRP))) { 197789Sahrens seen |= S_IRGRP; 198789Sahrens if (acep->a_type == ALLOW) { 199789Sahrens mode |= S_IRGRP; 200789Sahrens } 201789Sahrens } 202789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA) && 203789Sahrens (!(seen & S_IWGRP))) { 204789Sahrens seen |= S_IWGRP; 205789Sahrens if (acep->a_type == ALLOW) { 206789Sahrens mode |= S_IWGRP; 207789Sahrens } 208789Sahrens } 209789Sahrens if ((acep->a_access_mask & ACE_EXECUTE) && 210789Sahrens (!(seen & S_IXGRP))) { 211789Sahrens seen |= S_IXGRP; 212789Sahrens if (acep->a_type == ALLOW) { 213789Sahrens mode |= S_IXGRP; 214789Sahrens } 215789Sahrens } 216789Sahrens } else if (entry_type == ACE_EVERYONE) { 217789Sahrens if ((acep->a_access_mask & ACE_READ_DATA)) { 218789Sahrens if (!(seen & S_IRUSR)) { 219789Sahrens seen |= S_IRUSR; 220789Sahrens if (acep->a_type == ALLOW) { 221789Sahrens mode |= S_IRUSR; 222789Sahrens } 223789Sahrens } 224789Sahrens if (!(seen & S_IRGRP)) { 225789Sahrens seen |= S_IRGRP; 226789Sahrens if (acep->a_type == ALLOW) { 227789Sahrens mode |= S_IRGRP; 228789Sahrens } 229789Sahrens } 230789Sahrens if (!(seen & S_IROTH)) { 231789Sahrens seen |= S_IROTH; 232789Sahrens if (acep->a_type == ALLOW) { 233789Sahrens mode |= S_IROTH; 234789Sahrens } 235789Sahrens } 236789Sahrens } 237789Sahrens if ((acep->a_access_mask & ACE_WRITE_DATA)) { 238789Sahrens if (!(seen & S_IWUSR)) { 239789Sahrens seen |= S_IWUSR; 240789Sahrens if (acep->a_type == ALLOW) { 241789Sahrens mode |= S_IWUSR; 242789Sahrens } 243789Sahrens } 244789Sahrens if (!(seen & S_IWGRP)) { 245789Sahrens seen |= S_IWGRP; 246789Sahrens if (acep->a_type == ALLOW) { 247789Sahrens mode |= S_IWGRP; 248789Sahrens } 249789Sahrens } 250789Sahrens if (!(seen & S_IWOTH)) { 251789Sahrens seen |= S_IWOTH; 252789Sahrens if (acep->a_type == ALLOW) { 253789Sahrens mode |= S_IWOTH; 254789Sahrens } 255789Sahrens } 256789Sahrens } 257789Sahrens if ((acep->a_access_mask & ACE_EXECUTE)) { 258789Sahrens if (!(seen & S_IXUSR)) { 259789Sahrens seen |= S_IXUSR; 260789Sahrens if (acep->a_type == ALLOW) { 261789Sahrens mode |= S_IXUSR; 262789Sahrens } 263789Sahrens } 264789Sahrens if (!(seen & S_IXGRP)) { 265789Sahrens seen |= S_IXGRP; 266789Sahrens if (acep->a_type == ALLOW) { 267789Sahrens mode |= S_IXGRP; 268789Sahrens } 269789Sahrens } 270789Sahrens if (!(seen & S_IXOTH)) { 271789Sahrens seen |= S_IXOTH; 272789Sahrens if (acep->a_type == ALLOW) { 273789Sahrens mode |= S_IXOTH; 274789Sahrens } 275789Sahrens } 276789Sahrens } 277789Sahrens } 278789Sahrens } 279789Sahrens return (mode); 280789Sahrens } 281789Sahrens 282789Sahrens static zfs_acl_t * 283789Sahrens zfs_acl_node_read_internal(znode_t *zp) 284789Sahrens { 285789Sahrens zfs_acl_t *aclp; 286789Sahrens 287789Sahrens aclp = zfs_acl_alloc(0); 288789Sahrens aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 289789Sahrens aclp->z_acl = &zp->z_phys->zp_acl.z_ace_data[0]; 290789Sahrens 291789Sahrens return (aclp); 292789Sahrens } 293789Sahrens 294789Sahrens /* 295789Sahrens * Read an external acl object. 296789Sahrens */ 2971544Seschrock static int 2981544Seschrock zfs_acl_node_read(znode_t *zp, zfs_acl_t **aclpp) 299789Sahrens { 300789Sahrens uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj; 301789Sahrens zfs_acl_t *aclp; 3021544Seschrock int error; 303789Sahrens 304789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 305789Sahrens 3061544Seschrock if (zp->z_phys->zp_acl.z_acl_extern_obj == 0) { 3071544Seschrock *aclpp = zfs_acl_node_read_internal(zp); 3081544Seschrock return (0); 3091544Seschrock } 310789Sahrens 311789Sahrens aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_count); 312789Sahrens 3131544Seschrock error = dmu_read(zp->z_zfsvfs->z_os, extacl, 0, 314789Sahrens ZFS_ACL_SIZE(zp->z_phys->zp_acl.z_acl_count), aclp->z_acl); 3151544Seschrock if (error != 0) { 3161544Seschrock zfs_acl_free(aclp); 3171544Seschrock return (error); 3181544Seschrock } 319789Sahrens 320789Sahrens aclp->z_acl_count = zp->z_phys->zp_acl.z_acl_count; 321789Sahrens 3221544Seschrock *aclpp = aclp; 3231544Seschrock return (0); 324789Sahrens } 325789Sahrens 326789Sahrens static boolean_t 327789Sahrens zfs_acl_valid(znode_t *zp, ace_t *uace, int aclcnt, int *inherit) 328789Sahrens { 329789Sahrens ace_t *acep; 330789Sahrens int i; 331789Sahrens 332789Sahrens *inherit = 0; 333789Sahrens 334789Sahrens if (aclcnt > MAX_ACL_ENTRIES || aclcnt <= 0) { 335789Sahrens return (B_FALSE); 336789Sahrens } 337789Sahrens 338789Sahrens for (i = 0, acep = uace; i != aclcnt; i++, acep++) { 339789Sahrens 340789Sahrens /* 341789Sahrens * first check type of entry 342789Sahrens */ 343789Sahrens 3441576Smarks switch (acep->a_flags & ACE_TYPE_FLAGS) { 345789Sahrens case ACE_OWNER: 346789Sahrens acep->a_who = -1; 347789Sahrens break; 348789Sahrens case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 349789Sahrens case ACE_IDENTIFIER_GROUP: 350789Sahrens if (acep->a_flags & ACE_GROUP) { 351789Sahrens acep->a_who = -1; 352789Sahrens } 353789Sahrens break; 354789Sahrens case ACE_EVERYONE: 355789Sahrens acep->a_who = -1; 356789Sahrens break; 357789Sahrens } 358789Sahrens 359789Sahrens /* 360789Sahrens * next check inheritance level flags 361789Sahrens */ 362789Sahrens 363789Sahrens if (acep->a_type != ALLOW && acep->a_type != DENY) 364789Sahrens return (B_FALSE); 365789Sahrens 366789Sahrens /* 367789Sahrens * Only directories should have inheritance flags. 368789Sahrens */ 369789Sahrens if (ZTOV(zp)->v_type != VDIR && (acep->a_flags & 370789Sahrens (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE| 371789Sahrens ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) { 372789Sahrens return (B_FALSE); 373789Sahrens } 374789Sahrens 375789Sahrens if (acep->a_flags & 376789Sahrens (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)) 377789Sahrens *inherit = 1; 378789Sahrens 379789Sahrens if (acep->a_flags & 380789Sahrens (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) { 381789Sahrens if ((acep->a_flags & (ACE_FILE_INHERIT_ACE| 382789Sahrens ACE_DIRECTORY_INHERIT_ACE)) == 0) { 383789Sahrens return (B_FALSE); 384789Sahrens } 385789Sahrens } 386789Sahrens } 387789Sahrens 388789Sahrens return (B_TRUE); 389789Sahrens } 390789Sahrens /* 391789Sahrens * common code for setting acl's. 392789Sahrens * 393789Sahrens * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl. 394789Sahrens * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's 395789Sahrens * already checked the acl and knows whether to inherit. 396789Sahrens */ 397789Sahrens int 398789Sahrens zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, dmu_tx_t *tx, int *ihp) 399789Sahrens { 400789Sahrens int inherit = 0; 401789Sahrens int error; 402789Sahrens znode_phys_t *zphys = zp->z_phys; 403789Sahrens zfs_znode_acl_t *zacl = &zphys->zp_acl; 404789Sahrens uint32_t acl_phys_size = ZFS_ACL_SIZE(aclp->z_acl_count); 405789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 406789Sahrens uint64_t aoid = zphys->zp_acl.z_acl_extern_obj; 407789Sahrens 408789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 409789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 410789Sahrens 411789Sahrens if (ihp) 412789Sahrens inherit = *ihp; /* already determined by caller */ 413789Sahrens else if (!zfs_acl_valid(zp, aclp->z_acl, 414789Sahrens aclp->z_acl_count, &inherit)) { 415789Sahrens return (EINVAL); 416789Sahrens } 417789Sahrens 418789Sahrens dmu_buf_will_dirty(zp->z_dbuf, tx); 419789Sahrens 420789Sahrens /* 421789Sahrens * Will ACL fit internally? 422789Sahrens */ 423789Sahrens if (aclp->z_acl_count > ACE_SLOT_CNT) { 424789Sahrens if (aoid == 0) { 425789Sahrens aoid = dmu_object_alloc(zfsvfs->z_os, 426789Sahrens DMU_OT_ACL, acl_phys_size, DMU_OT_NONE, 0, tx); 427789Sahrens } else { 428789Sahrens (void) dmu_object_set_blocksize(zfsvfs->z_os, aoid, 429789Sahrens acl_phys_size, 0, tx); 430789Sahrens } 431789Sahrens zphys->zp_acl.z_acl_extern_obj = aoid; 432789Sahrens zphys->zp_acl.z_acl_count = aclp->z_acl_count; 433789Sahrens dmu_write(zfsvfs->z_os, aoid, 0, 434789Sahrens acl_phys_size, aclp->z_acl, tx); 435789Sahrens } else { 436789Sahrens /* 437789Sahrens * Migrating back embedded? 438789Sahrens */ 439789Sahrens if (zphys->zp_acl.z_acl_extern_obj) { 440789Sahrens error = dmu_object_free(zfsvfs->z_os, 441*4300Smarks zp->z_phys->zp_acl.z_acl_extern_obj, tx); 442789Sahrens if (error) 443789Sahrens return (error); 444789Sahrens zphys->zp_acl.z_acl_extern_obj = 0; 445789Sahrens } 446789Sahrens bcopy(aclp->z_acl, zacl->z_ace_data, 447789Sahrens aclp->z_acl_count * sizeof (ace_t)); 448789Sahrens zacl->z_acl_count = aclp->z_acl_count; 449789Sahrens } 450905Smarks 451905Smarks zp->z_phys->zp_flags &= ~(ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE); 452905Smarks if (inherit) { 453789Sahrens zp->z_phys->zp_flags |= ZFS_INHERIT_ACE; 454905Smarks } else if (ace_trivial(zacl->z_ace_data, zacl->z_acl_count) == 0) { 455905Smarks zp->z_phys->zp_flags |= ZFS_ACL_TRIVIAL; 456905Smarks } 457789Sahrens 458789Sahrens zphys->zp_mode = zfs_mode_compute(zp, aclp); 459789Sahrens zfs_time_stamper_locked(zp, STATE_CHANGED, tx); 460789Sahrens 461789Sahrens return (0); 462789Sahrens } 463789Sahrens 464789Sahrens /* 465789Sahrens * Create space for slots_needed ACEs to be append 466789Sahrens * to aclp. 467789Sahrens */ 468789Sahrens static void 469789Sahrens zfs_acl_append(zfs_acl_t *aclp, int slots_needed) 470789Sahrens { 471789Sahrens ace_t *newacep; 472789Sahrens ace_t *oldaclp; 473789Sahrens int slot_cnt; 474789Sahrens int slots_left = aclp->z_slots - aclp->z_acl_count; 475789Sahrens 476789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 477789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 478789Sahrens if (slots_left < slots_needed || aclp->z_state != ACL_DATA_ALLOCED) { 479789Sahrens slot_cnt = aclp->z_slots + 1 + (slots_needed - slots_left); 480789Sahrens newacep = kmem_alloc(ZFS_ACL_SIZE(slot_cnt), KM_SLEEP); 481789Sahrens bcopy(aclp->z_acl, newacep, 482789Sahrens ZFS_ACL_SIZE(aclp->z_acl_count)); 483789Sahrens oldaclp = aclp->z_acl; 484789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 485789Sahrens kmem_free(oldaclp, ZFS_ACL_SIZE(aclp->z_slots)); 486789Sahrens aclp->z_acl = newacep; 487789Sahrens aclp->z_slots = slot_cnt; 488789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 489789Sahrens } 490789Sahrens } 491789Sahrens 492789Sahrens /* 493789Sahrens * Remove "slot" ACE from aclp 494789Sahrens */ 495789Sahrens static void 496789Sahrens zfs_ace_remove(zfs_acl_t *aclp, int slot) 497789Sahrens { 498789Sahrens if (aclp->z_acl_count > 1) { 499789Sahrens (void) memmove(&aclp->z_acl[slot], 500789Sahrens &aclp->z_acl[slot +1], sizeof (ace_t) * 501789Sahrens (--aclp->z_acl_count - slot)); 502789Sahrens } else 503789Sahrens aclp->z_acl_count--; 504789Sahrens } 505789Sahrens 506789Sahrens /* 507789Sahrens * Update access mask for prepended ACE 508789Sahrens * 509789Sahrens * This applies the "groupmask" value for aclmode property. 510789Sahrens */ 511789Sahrens static void 512789Sahrens zfs_acl_prepend_fixup(ace_t *acep, ace_t *origacep, mode_t mode, uid_t owner) 513789Sahrens { 514789Sahrens 515789Sahrens int rmask, wmask, xmask; 516789Sahrens int user_ace; 517789Sahrens 518789Sahrens user_ace = (!(acep->a_flags & 519789Sahrens (ACE_OWNER|ACE_GROUP|ACE_IDENTIFIER_GROUP))); 520789Sahrens 521789Sahrens if (user_ace && (acep->a_who == owner)) { 522789Sahrens rmask = S_IRUSR; 523789Sahrens wmask = S_IWUSR; 524789Sahrens xmask = S_IXUSR; 525789Sahrens } else { 526789Sahrens rmask = S_IRGRP; 527789Sahrens wmask = S_IWGRP; 528789Sahrens xmask = S_IXGRP; 529789Sahrens } 530789Sahrens 531789Sahrens if (origacep->a_access_mask & ACE_READ_DATA) { 532789Sahrens if (mode & rmask) 533789Sahrens acep->a_access_mask &= ~ACE_READ_DATA; 534789Sahrens else 535789Sahrens acep->a_access_mask |= ACE_READ_DATA; 536789Sahrens } 537789Sahrens 538789Sahrens if (origacep->a_access_mask & ACE_WRITE_DATA) { 539789Sahrens if (mode & wmask) 540789Sahrens acep->a_access_mask &= ~ACE_WRITE_DATA; 541789Sahrens else 542789Sahrens acep->a_access_mask |= ACE_WRITE_DATA; 543789Sahrens } 544789Sahrens 545789Sahrens if (origacep->a_access_mask & ACE_APPEND_DATA) { 546789Sahrens if (mode & wmask) 547789Sahrens acep->a_access_mask &= ~ACE_APPEND_DATA; 548789Sahrens else 549789Sahrens acep->a_access_mask |= ACE_APPEND_DATA; 550789Sahrens } 551789Sahrens 552789Sahrens if (origacep->a_access_mask & ACE_EXECUTE) { 553789Sahrens if (mode & xmask) 554789Sahrens acep->a_access_mask &= ~ACE_EXECUTE; 555789Sahrens else 556789Sahrens acep->a_access_mask |= ACE_EXECUTE; 557789Sahrens } 558789Sahrens } 559789Sahrens 560789Sahrens /* 561789Sahrens * Apply mode to canonical six ACEs. 562789Sahrens */ 563789Sahrens static void 564789Sahrens zfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode) 565789Sahrens { 566789Sahrens int cnt; 567789Sahrens ace_t *acep; 568789Sahrens 569789Sahrens cnt = aclp->z_acl_count -1; 570789Sahrens acep = aclp->z_acl; 571789Sahrens 572789Sahrens /* 573789Sahrens * Fixup final ACEs to match the mode 574789Sahrens */ 575789Sahrens 576789Sahrens ASSERT(cnt >= 5); 577789Sahrens adjust_ace_pair(&acep[cnt - 1], mode); /* everyone@ */ 578789Sahrens adjust_ace_pair(&acep[cnt - 3], (mode & 0070) >> 3); /* group@ */ 579789Sahrens adjust_ace_pair(&acep[cnt - 5], (mode & 0700) >> 6); /* owner@ */ 580789Sahrens } 581789Sahrens 582789Sahrens 583789Sahrens static int 584789Sahrens zfs_acl_ace_match(ace_t *acep, int allow_deny, int type, int mask) 585789Sahrens { 586789Sahrens return (acep->a_access_mask == mask && acep->a_type == allow_deny && 5871576Smarks ((acep->a_flags & ACE_TYPE_FLAGS) == type)); 588789Sahrens } 589789Sahrens 590789Sahrens /* 591789Sahrens * Can prepended ACE be reused? 592789Sahrens */ 593789Sahrens static int 594789Sahrens zfs_reuse_deny(ace_t *acep, int i) 595789Sahrens { 596789Sahrens int okay_masks; 597789Sahrens 598789Sahrens if (i < 1) 599789Sahrens return (B_FALSE); 600789Sahrens 601789Sahrens if (acep[i-1].a_type != DENY) 602789Sahrens return (B_FALSE); 603789Sahrens 604789Sahrens if (acep[i-1].a_flags != (acep[i].a_flags & ACE_IDENTIFIER_GROUP)) 605789Sahrens return (B_FALSE); 606789Sahrens 607789Sahrens okay_masks = (acep[i].a_access_mask & OKAY_MASK_BITS); 608789Sahrens 609789Sahrens if (acep[i-1].a_access_mask & ~okay_masks) 610789Sahrens return (B_FALSE); 611789Sahrens 612789Sahrens return (B_TRUE); 613789Sahrens } 614789Sahrens 615789Sahrens /* 616789Sahrens * Create space to prepend an ACE 617789Sahrens */ 618789Sahrens static void 619789Sahrens zfs_acl_prepend(zfs_acl_t *aclp, int i) 620789Sahrens { 621789Sahrens ace_t *oldaclp = NULL; 622789Sahrens ace_t *to, *from; 623789Sahrens int slots_left = aclp->z_slots - aclp->z_acl_count; 624789Sahrens int oldslots; 625789Sahrens int need_free = 0; 626789Sahrens 627789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 628789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 629789Sahrens 630789Sahrens if (slots_left == 0 || aclp->z_state != ACL_DATA_ALLOCED) { 631789Sahrens 632789Sahrens to = kmem_alloc(ZFS_ACL_SIZE(aclp->z_acl_count + 633789Sahrens OGE_PAD), KM_SLEEP); 634789Sahrens if (aclp->z_state == ACL_DATA_ALLOCED) 635789Sahrens need_free++; 636789Sahrens from = aclp->z_acl; 637789Sahrens oldaclp = aclp->z_acl; 638789Sahrens (void) memmove(to, from, 639789Sahrens sizeof (ace_t) * aclp->z_acl_count); 640789Sahrens aclp->z_state = ACL_DATA_ALLOCED; 641789Sahrens } else { 642789Sahrens from = aclp->z_acl; 643789Sahrens to = aclp->z_acl; 644789Sahrens } 645789Sahrens 646789Sahrens 647789Sahrens (void) memmove(&to[i + 1], &from[i], 648789Sahrens sizeof (ace_t) * (aclp->z_acl_count - i)); 649789Sahrens 650789Sahrens if (oldaclp) { 651789Sahrens aclp->z_acl = to; 652789Sahrens oldslots = aclp->z_slots; 653789Sahrens aclp->z_slots = aclp->z_acl_count + OGE_PAD; 654789Sahrens if (need_free) 655789Sahrens kmem_free(oldaclp, ZFS_ACL_SIZE(oldslots)); 656789Sahrens } 657789Sahrens 658789Sahrens } 659789Sahrens 660789Sahrens /* 661789Sahrens * Prepend deny ACE 662789Sahrens */ 663789Sahrens static void 664789Sahrens zfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, int i, 665789Sahrens mode_t mode) 666789Sahrens { 667789Sahrens ace_t *acep; 668789Sahrens 669789Sahrens zfs_acl_prepend(aclp, i); 670789Sahrens 671789Sahrens acep = aclp->z_acl; 672789Sahrens zfs_set_ace(&acep[i], 0, DENY, acep[i + 1].a_who, 6731576Smarks (acep[i + 1].a_flags & ACE_TYPE_FLAGS)); 674789Sahrens zfs_acl_prepend_fixup(&acep[i], &acep[i+1], mode, zp->z_phys->zp_uid); 675789Sahrens aclp->z_acl_count++; 676789Sahrens } 677789Sahrens 678789Sahrens /* 679789Sahrens * Split an inherited ACE into inherit_only ACE 680789Sahrens * and original ACE with inheritance flags stripped off. 681789Sahrens */ 682789Sahrens static void 683789Sahrens zfs_acl_split_ace(zfs_acl_t *aclp, int i) 684789Sahrens { 685789Sahrens ace_t *acep = aclp->z_acl; 686789Sahrens 687789Sahrens zfs_acl_prepend(aclp, i); 688789Sahrens acep = aclp->z_acl; 689789Sahrens acep[i] = acep[i + 1]; 690789Sahrens acep[i].a_flags |= ACE_INHERIT_ONLY_ACE; 691789Sahrens acep[i + 1].a_flags &= ~ALL_INHERIT; 692789Sahrens aclp->z_acl_count++; 693789Sahrens } 694789Sahrens 695789Sahrens /* 696789Sahrens * Are ACES started at index i, the canonical six ACES? 697789Sahrens */ 698789Sahrens static int 699789Sahrens zfs_have_canonical_six(zfs_acl_t *aclp, int i) 700789Sahrens { 701789Sahrens ace_t *acep = aclp->z_acl; 702789Sahrens 703789Sahrens if ((zfs_acl_ace_match(&acep[i], 704789Sahrens DENY, ACE_OWNER, 0) && 705789Sahrens zfs_acl_ace_match(&acep[i + 1], ALLOW, ACE_OWNER, 706789Sahrens OWNER_ALLOW_MASK) && zfs_acl_ace_match(&acep[i + 2], 707789Sahrens DENY, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 3], 708789Sahrens ALLOW, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 4], 709789Sahrens DENY, ACE_EVERYONE, EVERYONE_DENY_MASK) && 710789Sahrens zfs_acl_ace_match(&acep[i + 5], ALLOW, ACE_EVERYONE, 711789Sahrens EVERYONE_ALLOW_MASK))) { 712789Sahrens return (1); 713789Sahrens } else { 714789Sahrens return (0); 715789Sahrens } 716789Sahrens } 717789Sahrens 718789Sahrens /* 719789Sahrens * Apply step 1g, to group entries 720789Sahrens * 721789Sahrens * Need to deal with corner case where group may have 722789Sahrens * greater permissions than owner. If so then limit 723789Sahrens * group permissions, based on what extra permissions 724789Sahrens * group has. 725789Sahrens */ 726789Sahrens static void 727789Sahrens zfs_fixup_group_entries(ace_t *acep, mode_t mode) 728789Sahrens { 729789Sahrens mode_t extramode = (mode >> 3) & 07; 730789Sahrens mode_t ownermode = (mode >> 6); 731789Sahrens 732789Sahrens if (acep[0].a_flags & ACE_IDENTIFIER_GROUP) { 733789Sahrens 734789Sahrens extramode &= ~ownermode; 735789Sahrens 736789Sahrens if (extramode) { 737789Sahrens if (extramode & 04) { 738789Sahrens acep[0].a_access_mask &= ~ACE_READ_DATA; 739789Sahrens acep[1].a_access_mask &= ~ACE_READ_DATA; 740789Sahrens } 741789Sahrens if (extramode & 02) { 742789Sahrens acep[0].a_access_mask &= 743789Sahrens ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 744789Sahrens acep[1].a_access_mask &= 745789Sahrens ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 746789Sahrens } 747789Sahrens if (extramode & 01) { 748789Sahrens acep[0].a_access_mask &= ~ACE_EXECUTE; 749789Sahrens acep[1].a_access_mask &= ~ACE_EXECUTE; 750789Sahrens } 751789Sahrens } 752789Sahrens } 753789Sahrens } 754789Sahrens 755789Sahrens /* 756789Sahrens * Apply the chmod algorithm as described 757789Sahrens * in PSARC/2002/240 758789Sahrens */ 759789Sahrens static int 760789Sahrens zfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp, 761789Sahrens dmu_tx_t *tx) 762789Sahrens { 763789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 764789Sahrens ace_t *acep; 765789Sahrens int i; 766789Sahrens int error; 767789Sahrens int entry_type; 768789Sahrens int reuse_deny; 769789Sahrens int need_canonical_six = 1; 770905Smarks int inherit = 0; 771905Smarks int iflags; 772789Sahrens 773789Sahrens ASSERT(MUTEX_HELD(&zp->z_acl_lock)); 774789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 775789Sahrens 776789Sahrens i = 0; 777789Sahrens while (i < aclp->z_acl_count) { 778789Sahrens acep = aclp->z_acl; 7791576Smarks entry_type = (acep[i].a_flags & ACE_TYPE_FLAGS); 780905Smarks iflags = (acep[i].a_flags & ALL_INHERIT); 781789Sahrens 782789Sahrens if ((acep[i].a_type != ALLOW && acep[i].a_type != DENY) || 783905Smarks (iflags & ACE_INHERIT_ONLY_ACE)) { 784789Sahrens i++; 785905Smarks if (iflags) 786905Smarks inherit = 1; 787789Sahrens continue; 788789Sahrens } 789789Sahrens 790789Sahrens 7912676Seschrock if (zfsvfs->z_acl_mode == ZFS_ACL_DISCARD) { 792789Sahrens zfs_ace_remove(aclp, i); 793789Sahrens continue; 794789Sahrens } 795789Sahrens 796789Sahrens /* 797789Sahrens * Need to split ace into two? 798789Sahrens */ 799905Smarks if ((iflags & (ACE_FILE_INHERIT_ACE| 800789Sahrens ACE_DIRECTORY_INHERIT_ACE)) && 801905Smarks (!(iflags & ACE_INHERIT_ONLY_ACE))) { 802789Sahrens zfs_acl_split_ace(aclp, i); 803789Sahrens i++; 804905Smarks inherit = 1; 805789Sahrens continue; 806789Sahrens } 807789Sahrens 808789Sahrens if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE || 809789Sahrens (entry_type == OWNING_GROUP)) { 810789Sahrens acep[i].a_access_mask &= ~OGE_CLEAR; 811789Sahrens i++; 812789Sahrens continue; 813789Sahrens 814789Sahrens } else { 815789Sahrens if (acep[i].a_type == ALLOW) { 816789Sahrens 817789Sahrens /* 818789Sahrens * Check preceding ACE if any, to see 819789Sahrens * if we need to prepend a DENY ACE. 820789Sahrens * This is only applicable when the acl_mode 821789Sahrens * property == groupmask. 822789Sahrens */ 8232676Seschrock if (zfsvfs->z_acl_mode == ZFS_ACL_GROUPMASK) { 824789Sahrens 825789Sahrens reuse_deny = zfs_reuse_deny(acep, i); 826789Sahrens 827789Sahrens if (reuse_deny == B_FALSE) { 828789Sahrens zfs_acl_prepend_deny(zp, aclp, 829789Sahrens i, mode); 830789Sahrens i++; 831789Sahrens acep = aclp->z_acl; 832789Sahrens } else { 833789Sahrens zfs_acl_prepend_fixup( 834789Sahrens &acep[i - 1], 835789Sahrens &acep[i], mode, 836789Sahrens zp->z_phys->zp_uid); 837789Sahrens } 838789Sahrens zfs_fixup_group_entries(&acep[i - 1], 839789Sahrens mode); 840789Sahrens } 841789Sahrens } 842789Sahrens i++; 843789Sahrens } 844789Sahrens } 845789Sahrens 846789Sahrens /* 847789Sahrens * Check out last six aces, if we have six. 848789Sahrens */ 849789Sahrens 850789Sahrens if (aclp->z_acl_count >= 6) { 851789Sahrens i = aclp->z_acl_count - 6; 852789Sahrens 853789Sahrens if (zfs_have_canonical_six(aclp, i)) { 854789Sahrens need_canonical_six = 0; 855789Sahrens } 856789Sahrens } 857789Sahrens 858789Sahrens if (need_canonical_six) { 859789Sahrens 860789Sahrens zfs_acl_append(aclp, 6); 861789Sahrens i = aclp->z_acl_count; 862789Sahrens acep = aclp->z_acl; 863789Sahrens zfs_set_ace(&acep[i++], 0, DENY, -1, ACE_OWNER); 864789Sahrens zfs_set_ace(&acep[i++], OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER); 865789Sahrens zfs_set_ace(&acep[i++], 0, DENY, -1, OWNING_GROUP); 866789Sahrens zfs_set_ace(&acep[i++], 0, ALLOW, -1, OWNING_GROUP); 867789Sahrens zfs_set_ace(&acep[i++], EVERYONE_DENY_MASK, 868789Sahrens DENY, -1, ACE_EVERYONE); 869789Sahrens zfs_set_ace(&acep[i++], EVERYONE_ALLOW_MASK, 870789Sahrens ALLOW, -1, ACE_EVERYONE); 871789Sahrens aclp->z_acl_count += 6; 872789Sahrens } 873789Sahrens 874789Sahrens zfs_acl_fixup_canonical_six(aclp, mode); 875789Sahrens 876789Sahrens zp->z_phys->zp_mode = mode; 877905Smarks error = zfs_aclset_common(zp, aclp, tx, &inherit); 878789Sahrens return (error); 879789Sahrens } 880789Sahrens 881789Sahrens 882789Sahrens int 883789Sahrens zfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx) 884789Sahrens { 8851544Seschrock zfs_acl_t *aclp = NULL; 886789Sahrens int error; 887789Sahrens 888789Sahrens ASSERT(MUTEX_HELD(&zp->z_lock)); 889789Sahrens mutex_enter(&zp->z_acl_lock); 8901544Seschrock error = zfs_acl_node_read(zp, &aclp); 8911544Seschrock if (error == 0) 8921544Seschrock error = zfs_acl_chmod(zp, mode, aclp, tx); 893789Sahrens mutex_exit(&zp->z_acl_lock); 8941544Seschrock if (aclp) 8951544Seschrock zfs_acl_free(aclp); 896789Sahrens return (error); 897789Sahrens } 898789Sahrens 899789Sahrens /* 900789Sahrens * strip off write_owner and write_acl 901789Sahrens */ 902789Sahrens static void 903789Sahrens zfs_securemode_update(zfsvfs_t *zfsvfs, ace_t *acep) 904789Sahrens { 9052676Seschrock if ((zfsvfs->z_acl_inherit == ZFS_ACL_SECURE) && 9061576Smarks (acep->a_type == ALLOW)) 9071576Smarks acep->a_access_mask &= ~SECURE_CLEAR; 908789Sahrens } 909789Sahrens 910789Sahrens /* 911789Sahrens * inherit inheritable ACEs from parent 912789Sahrens */ 913789Sahrens static zfs_acl_t * 914789Sahrens zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp) 915789Sahrens { 916789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 917789Sahrens ace_t *pacep; 918789Sahrens ace_t *acep; 919789Sahrens int ace_cnt = 0; 920789Sahrens int pace_cnt; 921789Sahrens int i, j; 922789Sahrens zfs_acl_t *aclp = NULL; 923789Sahrens 924789Sahrens i = j = 0; 925789Sahrens pace_cnt = paclp->z_acl_count; 926789Sahrens pacep = paclp->z_acl; 9272676Seschrock if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) { 928789Sahrens for (i = 0; i != pace_cnt; i++) { 929789Sahrens 9302676Seschrock if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW && 931789Sahrens pacep[i].a_type == ALLOW) 932789Sahrens continue; 933789Sahrens 934789Sahrens if (zfs_ace_can_use(zp, &pacep[i])) { 935789Sahrens ace_cnt++; 936789Sahrens if (!(pacep[i].a_flags & 937789Sahrens ACE_NO_PROPAGATE_INHERIT_ACE)) 938789Sahrens ace_cnt++; 939789Sahrens } 940789Sahrens } 941789Sahrens } 942789Sahrens 943789Sahrens aclp = zfs_acl_alloc(ace_cnt + OGE_PAD); 9442676Seschrock if (ace_cnt && zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) { 945789Sahrens acep = aclp->z_acl; 946789Sahrens pacep = paclp->z_acl; 947789Sahrens for (i = 0; i != pace_cnt; i++) { 948789Sahrens 9492676Seschrock if (zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW && 950789Sahrens pacep[i].a_type == ALLOW) 951789Sahrens continue; 952789Sahrens 953789Sahrens if (zfs_ace_can_use(zp, &pacep[i])) { 9541576Smarks 955789Sahrens /* 956789Sahrens * Now create entry for inherited ace 957789Sahrens */ 9581576Smarks 959789Sahrens acep[j] = pacep[i]; 960789Sahrens 9611576Smarks /* 9621576Smarks * When AUDIT/ALARM a_types are supported 9631576Smarks * they should be inherited here. 9641576Smarks */ 965789Sahrens 9661576Smarks if ((pacep[i].a_flags & 9671576Smarks ACE_NO_PROPAGATE_INHERIT_ACE) || 9681576Smarks (ZTOV(zp)->v_type != VDIR)) { 969789Sahrens acep[j].a_flags &= ~ALL_INHERIT; 970789Sahrens zfs_securemode_update(zfsvfs, &acep[j]); 971789Sahrens j++; 972789Sahrens continue; 973789Sahrens } 974789Sahrens 975789Sahrens ASSERT(ZTOV(zp)->v_type == VDIR); 976789Sahrens 977789Sahrens /* 978789Sahrens * If we are inheriting an ACE targeted for 979865Smarks * only files, then make sure inherit_only 980865Smarks * is on for future propagation. 981789Sahrens */ 9821576Smarks if ((pacep[i].a_flags & (ACE_FILE_INHERIT_ACE | 9831576Smarks ACE_DIRECTORY_INHERIT_ACE)) != 984865Smarks ACE_FILE_INHERIT_ACE) { 9851576Smarks j++; 9861576Smarks acep[j] = acep[j-1]; 9871576Smarks acep[j-1].a_flags |= 9881576Smarks ACE_INHERIT_ONLY_ACE; 9891576Smarks acep[j].a_flags &= ~ALL_INHERIT; 990865Smarks } else { 9911576Smarks acep[j].a_flags |= ACE_INHERIT_ONLY_ACE; 992865Smarks } 993789Sahrens zfs_securemode_update(zfsvfs, &acep[j]); 994789Sahrens j++; 995789Sahrens } 996789Sahrens } 997789Sahrens } 998789Sahrens aclp->z_acl_count = j; 999789Sahrens ASSERT(aclp->z_slots >= aclp->z_acl_count); 1000789Sahrens 1001789Sahrens return (aclp); 1002789Sahrens } 1003789Sahrens 1004789Sahrens /* 1005789Sahrens * Create file system object initial permissions 1006789Sahrens * including inheritable ACEs. 1007789Sahrens */ 1008789Sahrens void 1009789Sahrens zfs_perm_init(znode_t *zp, znode_t *parent, int flag, 1010789Sahrens vattr_t *vap, dmu_tx_t *tx, cred_t *cr) 1011789Sahrens { 1012789Sahrens uint64_t mode; 1013789Sahrens uid_t uid; 1014789Sahrens gid_t gid; 1015789Sahrens int error; 1016789Sahrens int pull_down; 1017789Sahrens zfs_acl_t *aclp, *paclp; 1018789Sahrens 1019789Sahrens mode = MAKEIMODE(vap->va_type, vap->va_mode); 1020789Sahrens 1021789Sahrens /* 1022789Sahrens * Determine uid and gid. 1023789Sahrens */ 1024789Sahrens if ((flag & (IS_ROOT_NODE | IS_REPLAY)) || 1025789Sahrens ((flag & IS_XATTR) && (vap->va_type == VDIR))) { 1026789Sahrens uid = vap->va_uid; 1027789Sahrens gid = vap->va_gid; 1028789Sahrens } else { 1029789Sahrens uid = crgetuid(cr); 1030789Sahrens if ((vap->va_mask & AT_GID) && 1031789Sahrens ((vap->va_gid == parent->z_phys->zp_gid) || 1032789Sahrens groupmember(vap->va_gid, cr) || 10332058Sxs154138 secpolicy_vnode_create_gid(cr) == 0)) 1034789Sahrens gid = vap->va_gid; 1035789Sahrens else 1036789Sahrens gid = (parent->z_phys->zp_mode & S_ISGID) ? 1037789Sahrens parent->z_phys->zp_gid : crgetgid(cr); 1038789Sahrens } 1039789Sahrens 1040789Sahrens /* 1041789Sahrens * If we're creating a directory, and the parent directory has the 1042789Sahrens * set-GID bit set, set in on the new directory. 1043789Sahrens * Otherwise, if the user is neither privileged nor a member of the 1044789Sahrens * file's new group, clear the file's set-GID bit. 1045789Sahrens */ 1046789Sahrens 1047789Sahrens if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR)) 1048789Sahrens mode |= S_ISGID; 1049789Sahrens else { 1050789Sahrens if ((mode & S_ISGID) && 1051789Sahrens secpolicy_vnode_setids_setgids(cr, gid) != 0) 1052789Sahrens mode &= ~S_ISGID; 1053789Sahrens } 1054789Sahrens 1055789Sahrens zp->z_phys->zp_uid = uid; 1056789Sahrens zp->z_phys->zp_gid = gid; 1057789Sahrens zp->z_phys->zp_mode = mode; 1058789Sahrens 1059789Sahrens mutex_enter(&parent->z_lock); 1060789Sahrens pull_down = (parent->z_phys->zp_flags & ZFS_INHERIT_ACE); 1061789Sahrens if (pull_down) { 1062789Sahrens mutex_enter(&parent->z_acl_lock); 10631544Seschrock VERIFY(0 == zfs_acl_node_read(parent, &paclp)); 1064789Sahrens mutex_exit(&parent->z_acl_lock); 1065789Sahrens aclp = zfs_acl_inherit(zp, paclp); 1066789Sahrens zfs_acl_free(paclp); 1067789Sahrens } else { 1068789Sahrens aclp = zfs_acl_alloc(6); 1069789Sahrens } 1070789Sahrens mutex_exit(&parent->z_lock); 1071789Sahrens mutex_enter(&zp->z_lock); 1072789Sahrens mutex_enter(&zp->z_acl_lock); 1073789Sahrens error = zfs_acl_chmod(zp, mode, aclp, tx); 1074789Sahrens mutex_exit(&zp->z_lock); 1075789Sahrens mutex_exit(&zp->z_acl_lock); 1076789Sahrens ASSERT3U(error, ==, 0); 1077789Sahrens zfs_acl_free(aclp); 1078789Sahrens } 1079789Sahrens 1080789Sahrens /* 1081975Smarks * Should ACE be inherited? 1082789Sahrens */ 1083789Sahrens static int 1084789Sahrens zfs_ace_can_use(znode_t *zp, ace_t *acep) 1085789Sahrens { 1086789Sahrens int vtype = ZTOV(zp)->v_type; 1087789Sahrens 1088789Sahrens int iflags = (acep->a_flags & 0xf); 1089789Sahrens 1090789Sahrens if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) 1091789Sahrens return (1); 1092789Sahrens else if (iflags & ACE_FILE_INHERIT_ACE) 1093975Smarks return (!((vtype == VDIR) && 1094975Smarks (iflags & ACE_NO_PROPAGATE_INHERIT_ACE))); 1095789Sahrens return (0); 1096789Sahrens } 1097789Sahrens 1098789Sahrens /* 1099789Sahrens * Retrieve a files ACL 1100789Sahrens */ 1101789Sahrens int 1102789Sahrens zfs_getacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr) 1103789Sahrens { 1104789Sahrens zfs_acl_t *aclp; 1105789Sahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); 1106789Sahrens int error; 1107789Sahrens 1108789Sahrens if (error = zfs_zaccess(zp, ACE_READ_ACL, cr)) { 1109789Sahrens /* 1110789Sahrens * If owner of file then allow reading of the 1111789Sahrens * ACL. 1112789Sahrens */ 1113789Sahrens if (crgetuid(cr) != zp->z_phys->zp_uid) 1114789Sahrens return (error); 1115789Sahrens } 1116789Sahrens 1117789Sahrens if (mask == 0) 1118789Sahrens return (ENOSYS); 1119789Sahrens 1120789Sahrens mutex_enter(&zp->z_acl_lock); 1121789Sahrens 11221544Seschrock error = zfs_acl_node_read(zp, &aclp); 11231544Seschrock if (error != 0) { 11241544Seschrock mutex_exit(&zp->z_acl_lock); 11251544Seschrock return (error); 11261544Seschrock } 11271544Seschrock 1128789Sahrens 1129789Sahrens if (mask & VSA_ACECNT) { 1130789Sahrens vsecp->vsa_aclcnt = aclp->z_acl_count; 1131789Sahrens } 1132789Sahrens 1133789Sahrens if (mask & VSA_ACE) { 1134789Sahrens vsecp->vsa_aclentp = kmem_alloc(aclp->z_acl_count * 1135789Sahrens sizeof (ace_t), KM_SLEEP); 1136789Sahrens bcopy(aclp->z_acl, vsecp->vsa_aclentp, 1137789Sahrens aclp->z_acl_count * sizeof (ace_t)); 1138789Sahrens } 1139789Sahrens 1140789Sahrens mutex_exit(&zp->z_acl_lock); 1141789Sahrens 1142789Sahrens zfs_acl_free(aclp); 1143789Sahrens 1144789Sahrens return (0); 1145789Sahrens } 1146789Sahrens 1147789Sahrens /* 1148789Sahrens * Set a files ACL 1149789Sahrens */ 1150789Sahrens int 1151789Sahrens zfs_setacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr) 1152789Sahrens { 1153789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1154789Sahrens zilog_t *zilog = zfsvfs->z_log; 1155789Sahrens ace_t *acep = vsecp->vsa_aclentp; 1156789Sahrens int aclcnt = vsecp->vsa_aclcnt; 1157789Sahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); 1158789Sahrens dmu_tx_t *tx; 1159789Sahrens int error; 1160789Sahrens int inherit; 1161789Sahrens zfs_acl_t *aclp; 1162789Sahrens 1163789Sahrens if (mask == 0) 1164*4300Smarks return (ENOSYS); 1165789Sahrens 1166789Sahrens if (!zfs_acl_valid(zp, acep, aclcnt, &inherit)) 1167789Sahrens return (EINVAL); 1168789Sahrens top: 1169789Sahrens error = zfs_zaccess_v4_perm(zp, ACE_WRITE_ACL, cr); 1170789Sahrens if (error == EACCES || error == ACCESS_UNDETERMINED) { 1171789Sahrens if ((error = secpolicy_vnode_setdac(cr, 1172789Sahrens zp->z_phys->zp_uid)) != 0) { 1173789Sahrens return (error); 1174789Sahrens } 1175789Sahrens } else if (error) { 1176789Sahrens return (error == EROFS ? error : EPERM); 1177789Sahrens } 1178789Sahrens 1179789Sahrens mutex_enter(&zp->z_lock); 1180789Sahrens mutex_enter(&zp->z_acl_lock); 1181789Sahrens 1182789Sahrens tx = dmu_tx_create(zfsvfs->z_os); 1183789Sahrens dmu_tx_hold_bonus(tx, zp->z_id); 1184789Sahrens 1185789Sahrens if (zp->z_phys->zp_acl.z_acl_extern_obj) { 1186789Sahrens dmu_tx_hold_write(tx, zp->z_phys->zp_acl.z_acl_extern_obj, 1187789Sahrens 0, ZFS_ACL_SIZE(aclcnt)); 1188789Sahrens } else if (aclcnt > ACE_SLOT_CNT) { 1189789Sahrens dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, ZFS_ACL_SIZE(aclcnt)); 1190789Sahrens } 1191789Sahrens 1192789Sahrens error = dmu_tx_assign(tx, zfsvfs->z_assign); 1193789Sahrens if (error) { 1194789Sahrens mutex_exit(&zp->z_acl_lock); 1195789Sahrens mutex_exit(&zp->z_lock); 1196789Sahrens 1197789Sahrens if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) { 11982113Sahrens dmu_tx_wait(tx); 11992113Sahrens dmu_tx_abort(tx); 1200789Sahrens goto top; 1201789Sahrens } 12022113Sahrens dmu_tx_abort(tx); 1203789Sahrens return (error); 1204789Sahrens } 1205789Sahrens 1206789Sahrens aclp = zfs_acl_alloc(aclcnt); 1207789Sahrens bcopy(acep, aclp->z_acl, sizeof (ace_t) * aclcnt); 1208789Sahrens aclp->z_acl_count = aclcnt; 1209789Sahrens error = zfs_aclset_common(zp, aclp, tx, &inherit); 1210789Sahrens ASSERT(error == 0); 1211789Sahrens 1212789Sahrens zfs_acl_free(aclp); 12132638Sperrin zfs_log_acl(zilog, tx, TX_ACL, zp, aclcnt, acep); 1214789Sahrens dmu_tx_commit(tx); 1215789Sahrens done: 1216789Sahrens mutex_exit(&zp->z_acl_lock); 1217789Sahrens mutex_exit(&zp->z_lock); 1218789Sahrens 1219789Sahrens return (error); 1220789Sahrens } 1221789Sahrens 1222789Sahrens static int 12231576Smarks zfs_ace_access(ace_t *zacep, int *working_mode) 1224789Sahrens { 12251576Smarks if (*working_mode == 0) { 1226789Sahrens return (0); 1227789Sahrens } 1228789Sahrens 12291576Smarks if (zacep->a_access_mask & *working_mode) { 1230789Sahrens if (zacep->a_type == ALLOW) { 12311576Smarks *working_mode &= 12321576Smarks ~(*working_mode & zacep->a_access_mask); 12331576Smarks if (*working_mode == 0) 1234789Sahrens return (0); 1235789Sahrens } else if (zacep->a_type == DENY) { 1236789Sahrens return (EACCES); 1237789Sahrens } 1238789Sahrens } 1239789Sahrens 1240789Sahrens /* 1241789Sahrens * haven't been specifcally denied at this point 1242789Sahrens * so return UNDETERMINED. 1243789Sahrens */ 1244789Sahrens 1245789Sahrens return (ACCESS_UNDETERMINED); 1246789Sahrens } 1247789Sahrens 1248789Sahrens 1249789Sahrens static int 1250789Sahrens zfs_zaccess_common(znode_t *zp, int v4_mode, int *working_mode, cred_t *cr) 1251789Sahrens { 1252789Sahrens zfs_acl_t *aclp; 1253789Sahrens zfsvfs_t *zfsvfs = zp->z_zfsvfs; 1254789Sahrens ace_t *zacep; 1255789Sahrens gid_t gid; 1256789Sahrens int cnt; 1257789Sahrens int i; 12581544Seschrock int error; 1259789Sahrens int access_deny = ACCESS_UNDETERMINED; 1260789Sahrens uint_t entry_type; 1261789Sahrens uid_t uid = crgetuid(cr); 1262789Sahrens 12632638Sperrin if (zfsvfs->z_assign >= TXG_INITIAL) { /* ZIL replay */ 12642638Sperrin *working_mode = 0; 12652638Sperrin return (0); 12662638Sperrin } 1267789Sahrens 12682638Sperrin *working_mode = v4_mode; 1269789Sahrens 1270789Sahrens if ((v4_mode & WRITE_MASK) && 1271789Sahrens (zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) && 1272789Sahrens (!IS_DEVVP(ZTOV(zp)))) { 1273789Sahrens return (EROFS); 1274789Sahrens } 1275789Sahrens 1276789Sahrens mutex_enter(&zp->z_acl_lock); 1277789Sahrens 12781544Seschrock error = zfs_acl_node_read(zp, &aclp); 12791544Seschrock if (error != 0) { 12801544Seschrock mutex_exit(&zp->z_acl_lock); 12811544Seschrock return (error); 12821544Seschrock } 12831544Seschrock 1284789Sahrens 1285789Sahrens zacep = aclp->z_acl; 1286789Sahrens cnt = aclp->z_acl_count; 1287789Sahrens 1288789Sahrens for (i = 0; i != cnt; i++) { 1289789Sahrens 12901576Smarks DTRACE_PROBE2(zfs__access__common, 12911576Smarks ace_t *, &zacep[i], int, *working_mode); 12921576Smarks 1293789Sahrens if (zacep[i].a_flags & ACE_INHERIT_ONLY_ACE) 1294789Sahrens continue; 1295789Sahrens 12961576Smarks entry_type = (zacep[i].a_flags & ACE_TYPE_FLAGS); 1297789Sahrens switch (entry_type) { 1298789Sahrens case ACE_OWNER: 1299789Sahrens if (uid == zp->z_phys->zp_uid) { 1300789Sahrens access_deny = zfs_ace_access(&zacep[i], 13011576Smarks working_mode); 1302789Sahrens } 1303789Sahrens break; 1304789Sahrens case (ACE_IDENTIFIER_GROUP | ACE_GROUP): 1305789Sahrens case ACE_IDENTIFIER_GROUP: 1306789Sahrens /* 1307789Sahrens * Owning group gid is in znode not ACL 1308789Sahrens */ 1309789Sahrens if (entry_type == (ACE_IDENTIFIER_GROUP | ACE_GROUP)) 1310789Sahrens gid = zp->z_phys->zp_gid; 1311789Sahrens else 1312789Sahrens gid = zacep[i].a_who; 1313789Sahrens 1314789Sahrens if (groupmember(gid, cr)) { 1315789Sahrens access_deny = zfs_ace_access(&zacep[i], 13161576Smarks working_mode); 1317789Sahrens } 1318789Sahrens break; 1319789Sahrens case ACE_EVERYONE: 13201576Smarks access_deny = zfs_ace_access(&zacep[i], working_mode); 1321789Sahrens break; 1322789Sahrens 1323789Sahrens /* USER Entry */ 1324789Sahrens default: 1325789Sahrens if (entry_type == 0) { 1326789Sahrens if (uid == zacep[i].a_who) { 1327789Sahrens access_deny = zfs_ace_access(&zacep[i], 13281576Smarks working_mode); 1329789Sahrens } 1330789Sahrens break; 1331789Sahrens } 1332789Sahrens zfs_acl_free(aclp); 1333789Sahrens mutex_exit(&zp->z_acl_lock); 1334789Sahrens return (EIO); 1335789Sahrens } 1336789Sahrens 1337789Sahrens if (access_deny != ACCESS_UNDETERMINED) 1338789Sahrens break; 1339789Sahrens } 1340789Sahrens 1341789Sahrens mutex_exit(&zp->z_acl_lock); 1342789Sahrens zfs_acl_free(aclp); 1343789Sahrens 1344789Sahrens return (access_deny); 1345789Sahrens } 1346789Sahrens 1347789Sahrens 1348789Sahrens /* 1349789Sahrens * Determine whether Access should be granted/denied, invoking least 1350789Sahrens * priv subsytem when a deny is determined. 1351789Sahrens */ 1352789Sahrens int 1353789Sahrens zfs_zaccess(znode_t *zp, int mode, cred_t *cr) 1354789Sahrens { 13551576Smarks int working_mode; 1356789Sahrens int error; 1357789Sahrens int is_attr; 1358789Sahrens znode_t *xzp; 1359789Sahrens znode_t *check_zp = zp; 1360789Sahrens 1361789Sahrens is_attr = ((zp->z_phys->zp_flags & ZFS_XATTR) && 1362789Sahrens (ZTOV(zp)->v_type == VDIR)); 1363789Sahrens 1364789Sahrens /* 1365789Sahrens * If attribute then validate against base file 1366789Sahrens */ 1367789Sahrens if (is_attr) { 1368789Sahrens if ((error = zfs_zget(zp->z_zfsvfs, 1369789Sahrens zp->z_phys->zp_parent, &xzp)) != 0) { 1370789Sahrens return (error); 1371789Sahrens } 1372789Sahrens check_zp = xzp; 1373789Sahrens /* 1374789Sahrens * fixup mode to map to xattr perms 1375789Sahrens */ 1376789Sahrens 1377789Sahrens if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) { 1378789Sahrens mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA); 1379789Sahrens mode |= ACE_WRITE_NAMED_ATTRS; 1380789Sahrens } 1381789Sahrens 1382789Sahrens if (mode & (ACE_READ_DATA|ACE_EXECUTE)) { 1383789Sahrens mode &= ~(ACE_READ_DATA|ACE_EXECUTE); 1384789Sahrens mode |= ACE_READ_NAMED_ATTRS; 1385789Sahrens } 1386789Sahrens } 1387789Sahrens 1388789Sahrens error = zfs_zaccess_common(check_zp, mode, &working_mode, cr); 1389789Sahrens 1390789Sahrens if (error == EROFS) { 1391789Sahrens if (is_attr) 1392789Sahrens VN_RELE(ZTOV(xzp)); 1393789Sahrens return (error); 1394789Sahrens } 1395789Sahrens 13961576Smarks if (error || working_mode) { 13971576Smarks working_mode = (zfs_v4_to_unix(working_mode) << 6); 1398789Sahrens error = secpolicy_vnode_access(cr, ZTOV(check_zp), 13991576Smarks check_zp->z_phys->zp_uid, working_mode); 1400789Sahrens } 1401789Sahrens 1402789Sahrens if (is_attr) 1403789Sahrens VN_RELE(ZTOV(xzp)); 1404789Sahrens 1405789Sahrens return (error); 1406789Sahrens } 1407789Sahrens 1408789Sahrens /* 1409789Sahrens * Special zaccess function to check for special nfsv4 perm. 1410789Sahrens * doesn't call secpolicy_vnode_access() for failure, since that 1411789Sahrens * would probably be the wrong policy function to call. 1412789Sahrens * instead its up to the caller to handle that situation. 1413789Sahrens */ 1414789Sahrens 1415789Sahrens int 1416789Sahrens zfs_zaccess_v4_perm(znode_t *zp, int mode, cred_t *cr) 1417789Sahrens { 1418789Sahrens int working_mode = 0; 1419789Sahrens return (zfs_zaccess_common(zp, mode, &working_mode, cr)); 1420789Sahrens } 1421789Sahrens 1422789Sahrens /* 1423789Sahrens * Translate tradition unix VREAD/VWRITE/VEXEC mode into 1424789Sahrens * native ACL format and call zfs_zaccess() 1425789Sahrens */ 1426789Sahrens int 1427789Sahrens zfs_zaccess_rwx(znode_t *zp, mode_t mode, cred_t *cr) 1428789Sahrens { 1429789Sahrens int v4_mode = zfs_unix_to_v4(mode >> 6); 1430789Sahrens 1431789Sahrens return (zfs_zaccess(zp, v4_mode, cr)); 1432789Sahrens } 1433789Sahrens 14342604Smarks static int 14352604Smarks zfs_delete_final_check(znode_t *zp, znode_t *dzp, cred_t *cr) 14362604Smarks { 14372604Smarks int error; 14382604Smarks 14392604Smarks error = secpolicy_vnode_access(cr, ZTOV(zp), 14402604Smarks dzp->z_phys->zp_uid, S_IWRITE|S_IEXEC); 14412604Smarks 14422604Smarks if (error == 0) 14432604Smarks error = zfs_sticky_remove_access(dzp, zp, cr); 14442604Smarks 14452604Smarks return (error); 14462604Smarks } 14472604Smarks 1448789Sahrens /* 1449789Sahrens * Determine whether Access should be granted/deny, without 1450789Sahrens * consulting least priv subsystem. 1451789Sahrens * 1452789Sahrens * 1453789Sahrens * The following chart is the recommended NFSv4 enforcement for 1454789Sahrens * ability to delete an object. 1455789Sahrens * 1456789Sahrens * ------------------------------------------------------- 1457789Sahrens * | Parent Dir | Target Object Permissions | 1458789Sahrens * | permissions | | 1459789Sahrens * ------------------------------------------------------- 1460789Sahrens * | | ACL Allows | ACL Denies| Delete | 1461789Sahrens * | | Delete | Delete | unspecified| 1462789Sahrens * ------------------------------------------------------- 1463789Sahrens * | ACL Allows | Permit | Permit | Permit | 1464789Sahrens * | DELETE_CHILD | | 1465789Sahrens * ------------------------------------------------------- 1466789Sahrens * | ACL Denies | Permit | Deny | Deny | 1467789Sahrens * | DELETE_CHILD | | | | 1468789Sahrens * ------------------------------------------------------- 1469789Sahrens * | ACL specifies | | | | 1470789Sahrens * | only allow | Permit | Permit | Permit | 1471789Sahrens * | write and | | | | 1472789Sahrens * | execute | | | | 1473789Sahrens * ------------------------------------------------------- 1474789Sahrens * | ACL denies | | | | 1475789Sahrens * | write and | Permit | Deny | Deny | 1476789Sahrens * | execute | | | | 1477789Sahrens * ------------------------------------------------------- 1478789Sahrens * ^ 1479789Sahrens * | 1480789Sahrens * No search privilege, can't even look up file? 1481789Sahrens * 1482789Sahrens */ 1483789Sahrens int 1484789Sahrens zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr) 1485789Sahrens { 1486789Sahrens int dzp_working_mode = 0; 1487789Sahrens int zp_working_mode = 0; 1488789Sahrens int dzp_error, zp_error; 1489789Sahrens 1490789Sahrens /* 1491789Sahrens * Arghh, this check is going to require a couple of questions 1492789Sahrens * to be asked. We want specific DELETE permissions to 1493789Sahrens * take precedence over WRITE/EXECUTE. We don't 1494789Sahrens * want an ACL such as this to mess us up. 14952604Smarks * user:joe:write_data:deny,user:joe:delete:allow 1496789Sahrens * 1497789Sahrens * However, deny permissions may ultimately be overridden 1498789Sahrens * by secpolicy_vnode_access(). 1499789Sahrens */ 1500789Sahrens 1501789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD, 1502789Sahrens &dzp_working_mode, cr); 1503789Sahrens zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode, cr); 1504789Sahrens 1505789Sahrens if (dzp_error == EROFS || zp_error == EROFS) 1506789Sahrens return (dzp_error); 1507789Sahrens 1508789Sahrens /* 15092604Smarks * First check the first row. 15102604Smarks * We only need to see if parent Allows delete_child 1511789Sahrens */ 15121576Smarks if ((dzp_working_mode & ACE_DELETE_CHILD) == 0) 1513789Sahrens return (0); 1514789Sahrens 1515789Sahrens /* 1516789Sahrens * Second row 15172604Smarks * we already have the necessary information in 15182604Smarks * zp_working_mode, zp_error and dzp_error. 1519789Sahrens */ 1520789Sahrens 15211576Smarks if ((zp_working_mode & ACE_DELETE) == 0) 1522789Sahrens return (0); 1523789Sahrens 1524789Sahrens /* 15252604Smarks * Now zp_error should either be EACCES which indicates 15262604Smarks * a "deny" delete entry or ACCESS_UNDETERMINED if the "delete" 15272604Smarks * entry exists on the target. 15282604Smarks * 15292604Smarks * dzp_error should be either EACCES which indicates a "deny" 15302604Smarks * entry for delete_child or ACCESS_UNDETERMINED if no delete_child 15312604Smarks * entry exists. If value is EACCES then we are done 15322604Smarks * and zfs_delete_final_check() will make the final decision 15332604Smarks * regarding to allow the delete. 15342604Smarks */ 15352604Smarks 15362604Smarks ASSERT(zp_error != 0 && dzp_error != 0); 15372604Smarks if (dzp_error == EACCES) 15382604Smarks return (zfs_delete_final_check(zp, dzp, cr)); 15392604Smarks 15402604Smarks /* 1541789Sahrens * Third Row 15422604Smarks * Only need to check for write/execute on parent 1543789Sahrens */ 1544789Sahrens 1545789Sahrens dzp_error = zfs_zaccess_common(dzp, ACE_WRITE_DATA|ACE_EXECUTE, 1546789Sahrens &dzp_working_mode, cr); 1547789Sahrens 1548789Sahrens if (dzp_error == EROFS) 1549789Sahrens return (dzp_error); 1550789Sahrens 15511576Smarks if ((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) == 0) 15522604Smarks return (zfs_sticky_remove_access(dzp, zp, cr)); 1553789Sahrens 1554789Sahrens /* 1555789Sahrens * Fourth Row 1556789Sahrens */ 1557789Sahrens 15581576Smarks if (((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) != 0) && 15591576Smarks ((zp_working_mode & ACE_DELETE) == 0)) 15602604Smarks return (zfs_sticky_remove_access(dzp, zp, cr)); 1561789Sahrens 15622604Smarks return (zfs_delete_final_check(zp, dzp, cr)); 1563789Sahrens } 1564789Sahrens 1565789Sahrens int 1566789Sahrens zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp, 1567789Sahrens znode_t *tzp, cred_t *cr) 1568789Sahrens { 1569789Sahrens int add_perm; 1570789Sahrens int error; 1571789Sahrens 1572789Sahrens add_perm = (ZTOV(szp)->v_type == VDIR) ? 1573789Sahrens ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE; 1574789Sahrens 1575789Sahrens /* 1576789Sahrens * Rename permissions are combination of delete permission + 1577789Sahrens * add file/subdir permission. 1578789Sahrens */ 1579789Sahrens 1580789Sahrens /* 1581789Sahrens * first make sure we do the delete portion. 1582789Sahrens * 1583789Sahrens * If that succeeds then check for add_file/add_subdir permissions 1584789Sahrens */ 1585789Sahrens 1586789Sahrens if (error = zfs_zaccess_delete(sdzp, szp, cr)) 1587789Sahrens return (error); 1588789Sahrens 1589789Sahrens /* 1590789Sahrens * If we have a tzp, see if we can delete it? 1591789Sahrens */ 1592789Sahrens if (tzp) { 1593789Sahrens if (error = zfs_zaccess_delete(tdzp, tzp, cr)) 1594789Sahrens return (error); 1595789Sahrens } 1596789Sahrens 1597789Sahrens /* 1598789Sahrens * Now check for add permissions 1599789Sahrens */ 16001308Smarks error = zfs_zaccess(tdzp, add_perm, cr); 1601789Sahrens 1602789Sahrens return (error); 1603789Sahrens } 1604