zfs_acl.c revision ea8dc4b6d2251b437950c0056bc626b311c73c27
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Common Development and Distribution License (the "License").
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
84c5a1550ecbf7356ab4133238160367c507f4fbmarks * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define WRITE_MASK (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS| \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define SECURE_NO_INHERIT (ACE_WRITE_ACL|ACE_WRITE_OWNER)
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define OGE_PAD 6 /* traditional owner/group/everyone ACES */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (slots != 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp->z_acl = kmem_alloc(ZFS_ACL_SIZE(slots), KM_SLEEP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (access_mask & (ACE_READ_DATA | ACE_LIST_DIRECTORY))
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (access_mask & (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_ADD_FILE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (access_mask & (ACE_EXECUTE|ACE_READ_NAMED_ATTRS))
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Convert unix access mask to v4 access mask
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_set_ace(ace_t *zacep, uint32_t access_mask, int access_type,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Read an external acl object.
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint64_t extacl = zp->z_phys->zp_acl.z_acl_extern_obj;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens aclp = zfs_acl_alloc(zp->z_phys->zp_acl.z_acl_count);
fa9e4066f08beec538e775443c5be79dd423fcabahrens ZFS_ACL_SIZE(zp->z_phys->zp_acl.z_acl_count), aclp->z_acl);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_valid(znode_t *zp, ace_t *uace, int aclcnt, int *inherit)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * first check type of entry
fa9e4066f08beec538e775443c5be79dd423fcabahrens * next check inheritance level flags
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Only directories should have inheritance flags.
fa9e4066f08beec538e775443c5be79dd423fcabahrens ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE))) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * common code for setting acl's.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * already checked the acl and knows whether to inherit.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, dmu_tx_t *tx, int *ihp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint32_t acl_phys_size = ZFS_ACL_SIZE(aclp->z_acl_count);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Will ACL fit internally?
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (aoid == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Migrating back embedded?
de122929e7c37df60cbea70616404e22d20e025bmarks zp->z_phys->zp_flags &= ~(ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE);
de122929e7c37df60cbea70616404e22d20e025bmarks } else if (ace_trivial(zacl->z_ace_data, zacl->z_acl_count) == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create space for slots_needed ACEs to be append
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (slots_left < slots_needed || aclp->z_state != ACL_DATA_ALLOCED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens slot_cnt = aclp->z_slots + 1 + (slots_needed - slots_left);
fa9e4066f08beec538e775443c5be79dd423fcabahrens newacep = kmem_alloc(ZFS_ACL_SIZE(slot_cnt), KM_SLEEP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Remove "slot" ACE from aclp
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Update access mask for prepended ACE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This applies the "groupmask" value for aclmode property.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_prepend_fixup(ace_t *acep, ace_t *origacep, mode_t mode, uid_t owner)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Apply mode to canonical six ACEs.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_fixup_canonical_six(zfs_acl_t *aclp, mode_t mode)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Fixup final ACEs to match the mode
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&acep[cnt - 1], mode); /* everyone@ */
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&acep[cnt - 3], (mode & 0070) >> 3); /* group@ */
fa9e4066f08beec538e775443c5be79dd423fcabahrens adjust_ace_pair(&acep[cnt - 5], (mode & 0700) >> 6); /* owner@ */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_ace_match(ace_t *acep, int allow_deny, int type, int mask)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (acep->a_access_mask == mask && acep->a_type == allow_deny &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Can prepended ACE be reused?
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (acep[i-1].a_flags != (acep[i].a_flags & ACE_IDENTIFIER_GROUP))
fa9e4066f08beec538e775443c5be79dd423fcabahrens okay_masks = (acep[i].a_access_mask & OKAY_MASK_BITS);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create space to prepend an ACE
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (slots_left == 0 || aclp->z_state != ACL_DATA_ALLOCED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Prepend deny ACE
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_prepend_deny(znode_t *zp, zfs_acl_t *aclp, int i,
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_acl_prepend_fixup(&acep[i], &acep[i+1], mode, zp->z_phys->zp_uid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Split an inherited ACE into inherit_only ACE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and original ACE with inheritance flags stripped off.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Are ACES started at index i, the canonical six ACES?
fa9e4066f08beec538e775443c5be79dd423fcabahrens DENY, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 3],
fa9e4066f08beec538e775443c5be79dd423fcabahrens ALLOW, OWNING_GROUP, 0) && zfs_acl_ace_match(&acep[i + 4],
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Apply step 1g, to group entries
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Need to deal with corner case where group may have
fa9e4066f08beec538e775443c5be79dd423fcabahrens * greater permissions than owner. If so then limit
fa9e4066f08beec538e775443c5be79dd423fcabahrens * group permissions, based on what extra permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * group has.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Apply the chmod algorithm as described
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in PSARC/2002/240
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_chmod(znode_t *zp, uint64_t mode, zfs_acl_t *aclp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((acep[i].a_type != ALLOW && acep[i].a_type != DENY) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Need to split ace into two?
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check preceding ACE if any, to see
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if we need to prepend a DENY ACE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This is only applicable when the acl_mode
fa9e4066f08beec538e775443c5be79dd423fcabahrens * property == groupmask.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Check out last six aces, if we have six.
fa9e4066f08beec538e775443c5be79dd423fcabahrens zfs_set_ace(&acep[i++], OWNER_ALLOW_MASK, ALLOW, -1, ACE_OWNER);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_acl_chmod_setattr(znode_t *zp, uint64_t mode, dmu_tx_t *tx)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * strip off write_owner and write_acl
fa9e4066f08beec538e775443c5be79dd423fcabahrens * inherit inheritable ACEs from parent
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i != pace_cnt; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i != pace_cnt; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Now create entry for inherited ace
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we are inheriting an ACE targeted for
55601ddb0a1b2278559e8e1723ff6e08c0aeb553marks * only files, then make sure inherit_only
55601ddb0a1b2278559e8e1723ff6e08c0aeb553marks * is on for future propagation.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create file system object initial permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * including inheritable ACEs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine uid and gid.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we're creating a directory, and the parent directory has the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * set-GID bit set, set in on the new directory.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Otherwise, if the user is neither privileged nor a member of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file's new group, clear the file's set-GID bit.
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((parent->z_phys->zp_mode & S_ISGID) && (vap->va_type == VDIR))
fa9e4066f08beec538e775443c5be79dd423fcabahrens pull_down = (parent->z_phys->zp_flags & ZFS_INHERIT_ACE);
0a787dc5d2d96ab63f180c8895835c584db505f2marks * Should ACE be inherited?
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Retrieve a files ACL
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_getacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If owner of file then allow reading of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Set a files ACL
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_setacl(znode_t *zp, vsecattr_t *vsecp, cred_t *cr)
fa9e4066f08beec538e775443c5be79dd423fcabahrens ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error == EACCES || error == ACCESS_UNDETERMINED) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (error) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens dmu_tx_hold_write(tx, zp->z_phys->zp_acl.z_acl_extern_obj,
fa9e4066f08beec538e775443c5be79dd423fcabahrens dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, ZFS_ACL_SIZE(aclcnt));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens seq = zfs_log_acl(zilog, tx, TX_ACL, zp, aclcnt, acep);
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_ace_access(ace_t *zacep, int mode_wanted, int *working_mode)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens *working_mode |= (mode_wanted & zacep->a_access_mask);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * haven't been specifcally denied at this point
fa9e4066f08beec538e775443c5be79dd423fcabahrens * so return UNDETERMINED.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_zaccess_common(znode_t *zp, int v4_mode, int *working_mode, cred_t *cr)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (zfsvfs->z_assign >= TXG_INITIAL) /* ZIL replay */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i != cnt; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Owning group gid is in znode not ACL
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (entry_type == (ACE_IDENTIFIER_GROUP | ACE_GROUP))
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* USER Entry */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine whether Access should be granted/denied, invoking least
fa9e4066f08beec538e775443c5be79dd423fcabahrens * priv subsytem when a deny is determined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If attribute then validate against base file
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fixup mode to map to xattr perms
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = zfs_zaccess_common(check_zp, mode, &working_mode, cr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens check_zp->z_phys->zp_uid, ~zfs_v4_to_unix(working_mode));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Special zaccess function to check for special nfsv4 perm.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * doesn't call secpolicy_vnode_access() for failure, since that
fa9e4066f08beec538e775443c5be79dd423fcabahrens * would probably be the wrong policy function to call.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * instead its up to the caller to handle that situation.
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_zaccess_v4_perm(znode_t *zp, int mode, cred_t *cr)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (zfs_zaccess_common(zp, mode, &working_mode, cr));
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Translate tradition unix VREAD/VWRITE/VEXEC mode into
fa9e4066f08beec538e775443c5be79dd423fcabahrens * native ACL format and call zfs_zaccess()
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Determine whether Access should be granted/deny, without
fa9e4066f08beec538e775443c5be79dd423fcabahrens * consulting least priv subsystem.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The following chart is the recommended NFSv4 enforcement for
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ability to delete an object.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | Parent Dir | Target Object Permissions |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | permissions | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | | ACL Allows | ACL Denies| Delete |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | | Delete | Delete | unspecified|
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | ACL Allows | Permit | Permit | Permit |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | DELETE_CHILD | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | ACL Denies | Permit | Deny | Deny |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | DELETE_CHILD | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | ACL specifies | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | only allow | Permit | Permit | Permit |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | write and | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | execute | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | ACL denies | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | write and | Permit | Deny | Deny |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * | execute | | | |
fa9e4066f08beec538e775443c5be79dd423fcabahrens * -------------------------------------------------------
fa9e4066f08beec538e775443c5be79dd423fcabahrens * No search privilege, can't even look up file?
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Arghh, this check is going to require a couple of questions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to be asked. We want specific DELETE permissions to
fa9e4066f08beec538e775443c5be79dd423fcabahrens * take precedence over WRITE/EXECUTE. We don't
fa9e4066f08beec538e775443c5be79dd423fcabahrens * want an ACL such as this to mess us up.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * user:sloar:write_data:deny,user:sloar:delete:allow
fa9e4066f08beec538e775443c5be79dd423fcabahrens * However, deny permissions may ultimately be overridden
fa9e4066f08beec538e775443c5be79dd423fcabahrens * by secpolicy_vnode_access().
fa9e4066f08beec538e775443c5be79dd423fcabahrens dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD,
fa9e4066f08beec538e775443c5be79dd423fcabahrens zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode, cr);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * First handle the first row
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Second row
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Third Row
fa9e4066f08beec538e775443c5be79dd423fcabahrens dzp_error = zfs_zaccess_common(dzp, ACE_WRITE_DATA|ACE_EXECUTE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Fourth Row
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (((dzp_working_mode & (ACE_WRITE_DATA|ACE_EXECUTE)) == 0) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Rename permissions are combination of delete permission +
fa9e4066f08beec538e775443c5be79dd423fcabahrens * add file/subdir permission.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * first make sure we do the delete portion.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If that succeeds then check for add_file/add_subdir permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we have a tzp, see if we can delete it?
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Now check for add permissions