summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authormarks <none@none>2008-04-09 06:51:13 -0700
committermarks <none@none>2008-04-09 06:51:13 -0700
commitb3d141f8c7a5335d670721a81f797b1834ee327b (patch)
tree36515f3ec8c3d7bc9d130e6622615bb858f58e64 /usr/src
parent5529abe02121fd6e540b19adb0d8f1715de83b58 (diff)
downloadillumos-joyent-b3d141f8c7a5335d670721a81f797b1834ee327b.tar.gz
PSARC/2008/231 New ZFS "passthrough" ACL inheritance rules
6538405 ZFS needs mechanism to bypass file creation mode
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/common/zfs/zfs_prop.c9
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_acl.h2
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_acl.c156
3 files changed, 90 insertions, 77 deletions
diff --git a/usr/src/common/zfs/zfs_prop.c b/usr/src/common/zfs/zfs_prop.c
index c65f441d89..8527e932f4 100644
--- a/usr/src/common/zfs/zfs_prop.c
+++ b/usr/src/common/zfs/zfs_prop.c
@@ -96,8 +96,9 @@ zfs_prop_init(void)
static zprop_index_t acl_inherit_table[] = {
{ "discard", ZFS_ACL_DISCARD },
{ "noallow", ZFS_ACL_NOALLOW },
- { "secure", ZFS_ACL_SECURE },
+ { "restricted", ZFS_ACL_RESTRICTED },
{ "passthrough", ZFS_ACL_PASSTHROUGH },
+ { "secure", ZFS_ACL_RESTRICTED }, /* bkwrd compatability */
{ NULL }
};
@@ -165,10 +166,10 @@ zfs_prop_init(void)
register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_GROUPMASK,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"discard | groupmask | passthrough", "ACLMODE", acl_mode_table);
- register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_SECURE,
+ register_index(ZFS_PROP_ACLINHERIT, "aclinherit", ZFS_ACL_RESTRICTED,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
- "discard | noallow | secure | passthrough", "ACLINHERIT",
- acl_inherit_table);
+ "discard | noallow | restricted | passthrough",
+ "ACLINHERIT", acl_inherit_table);
register_index(ZFS_PROP_COPIES, "copies", 1,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"1 | 2 | 3", "COPIES", copies_table);
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
index 926dfcedec..7b68f3e545 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_acl.h
@@ -180,7 +180,7 @@ typedef struct zfs_acl {
#define ZFS_ACL_NOALLOW 1
#define ZFS_ACL_GROUPMASK 2
#define ZFS_ACL_PASSTHROUGH 3
-#define ZFS_ACL_SECURE 4
+#define ZFS_ACL_RESTRICTED 4
struct znode;
struct zfsvfs;
diff --git a/usr/src/uts/common/fs/zfs/zfs_acl.c b/usr/src/uts/common/fs/zfs/zfs_acl.c
index 0ef73f475d..4f5768fceb 100644
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_acl.c
@@ -85,7 +85,7 @@
#define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE)
-#define SECURE_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER)
+#define RESTRICTED_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER)
#define V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\
ZFS_ACL_PROTECTED)
@@ -1615,13 +1615,13 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
* strip off write_owner and write_acl
*/
static void
-zfs_securemode_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
+zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
{
uint32_t mask = aclp->z_ops.ace_mask_get(acep);
- if ((zfsvfs->z_acl_inherit == ZFS_ACL_SECURE) &&
+ if ((zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
(aclp->z_ops.ace_type_get(acep) == ALLOW)) {
- mask &= ~SECURE_CLEAR;
+ mask &= ~RESTRICTED_CLEAR;
aclp->z_ops.ace_mask_set(acep, mask);
}
}
@@ -1647,7 +1647,7 @@ zfs_ace_can_use(znode_t *zp, uint16_t acep_flags)
* inherit inheritable ACEs from parent
*/
static zfs_acl_t *
-zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp)
+zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp, boolean_t *need_chmod)
{
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
void *pacep;
@@ -1660,7 +1660,9 @@ zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp)
size_t ace_size;
void *data1, *data2;
size_t data1sz, data2sz;
+ enum vtype vntype = ZTOV(zp)->v_type;
+ *need_chmod = B_TRUE;
pacep = NULL;
aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
if (zfsvfs->z_acl_inherit != ZFS_ACL_DISCARD) {
@@ -1673,82 +1675,90 @@ zfs_acl_inherit(znode_t *zp, zfs_acl_t *paclp)
ace_size = aclp->z_ops.ace_size(pacep);
- if (zfs_ace_can_use(zp, iflags)) {
- aclnode =
- zfs_acl_node_alloc(ace_size);
+ if (!zfs_ace_can_use(zp, iflags))
+ continue;
+
+ /*
+ * If owner@, group@, or everyone@ inheritable
+ * then zfs_acl_chmod() isn't needed.
+ */
+ if (zfsvfs->z_acl_inherit ==
+ ZFS_ACL_PASSTHROUGH &&
+ ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
+ ((iflags & OWNING_GROUP) ==
+ OWNING_GROUP)) && (vntype == VREG ||
+ (vntype == VDIR &&
+ (iflags & ACE_DIRECTORY_INHERIT_ACE))))
+ *need_chmod = B_FALSE;
+
+ aclnode = zfs_acl_node_alloc(ace_size);
+ list_insert_tail(&aclp->z_acl, aclnode);
+ acep = aclnode->z_acldata;
+ zfs_set_ace(aclp, acep, access_mask, type,
+ who, iflags|ACE_INHERITED_ACE);
+
+ /*
+ * Copy special opaque data if any
+ */
+ if ((data1sz = paclp->z_ops.ace_data(pacep,
+ &data1)) != 0) {
+ VERIFY((data2sz = aclp->z_ops.ace_data(acep,
+ &data2)) == data1sz);
+ bcopy(data1, data2, data2sz);
+ }
+ aclp->z_acl_count++;
+ aclnode->z_ace_count++;
+ aclp->z_acl_bytes += aclnode->z_size;
+ newflags = aclp->z_ops.ace_flags_get(acep);
- list_insert_tail(&aclp->z_acl, aclnode);
- acep = aclnode->z_acldata;
- zfs_set_ace(aclp, acep, access_mask, type,
- who, iflags|ACE_INHERITED_ACE);
+ if (vntype == VDIR)
+ aclp->z_hints |= ZFS_INHERIT_ACE;
+
+ if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) ||
+ (vntype != VDIR)) {
+ newflags &= ~ALL_INHERIT;
+ aclp->z_ops.ace_flags_set(acep,
+ newflags|ACE_INHERITED_ACE);
+ zfs_restricted_update(zfsvfs, aclp, acep);
+ continue;
+ }
+
+ ASSERT(vntype == VDIR);
+
+ newflags = aclp->z_ops.ace_flags_get(acep);
+ if ((iflags & (ACE_FILE_INHERIT_ACE |
+ ACE_DIRECTORY_INHERIT_ACE)) !=
+ ACE_FILE_INHERIT_ACE) {
+ aclnode2 = zfs_acl_node_alloc(ace_size);
+ list_insert_tail(&aclp->z_acl, aclnode2);
+ acep2 = aclnode2->z_acldata;
+ zfs_set_ace(aclp, acep2,
+ access_mask, type, who,
+ iflags|ACE_INHERITED_ACE);
+ newflags |= ACE_INHERIT_ONLY_ACE;
+ aclp->z_ops.ace_flags_set(acep, newflags);
+ newflags &= ~ALL_INHERIT;
+ aclp->z_ops.ace_flags_set(acep2,
+ newflags|ACE_INHERITED_ACE);
/*
* Copy special opaque data if any
*/
- if ((data1sz = paclp->z_ops.ace_data(pacep,
+ if ((data1sz = aclp->z_ops.ace_data(acep,
&data1)) != 0) {
VERIFY((data2sz =
- aclp->z_ops.ace_data(acep,
+ aclp->z_ops.ace_data(acep2,
&data2)) == data1sz);
- bcopy(data1, data2, data2sz);
+ bcopy(data1, data2, data1sz);
}
aclp->z_acl_count++;
- aclnode->z_ace_count++;
+ aclnode2->z_ace_count++;
aclp->z_acl_bytes += aclnode->z_size;
- newflags = aclp->z_ops.ace_flags_get(acep);
- if ((iflags &
- ACE_NO_PROPAGATE_INHERIT_ACE) ||
- (ZTOV(zp)->v_type != VDIR)) {
- newflags &= ~ALL_INHERIT;
- aclp->z_ops.ace_flags_set(acep,
- newflags|ACE_INHERITED_ACE);
- zfs_securemode_update(zfsvfs,
- aclp, acep);
- continue;
- }
-
- ASSERT(ZTOV(zp)->v_type == VDIR);
-
- newflags = aclp->z_ops.ace_flags_get(acep);
- if ((iflags & (ACE_FILE_INHERIT_ACE |
- ACE_DIRECTORY_INHERIT_ACE)) !=
- ACE_FILE_INHERIT_ACE) {
- aclnode2 = zfs_acl_node_alloc(ace_size);
- list_insert_tail(&aclp->z_acl,
- aclnode2);
- acep2 = aclnode2->z_acldata;
- zfs_set_ace(aclp, acep2,
- access_mask, type, who,
- iflags|ACE_INHERITED_ACE);
- newflags |= ACE_INHERIT_ONLY_ACE;
- aclp->z_ops.ace_flags_set(acep,
- newflags);
- newflags &= ~ALL_INHERIT;
- aclp->z_ops.ace_flags_set(acep2,
- newflags|ACE_INHERITED_ACE);
-
- /*
- * Copy special opaque data if any
- */
- if ((data1sz =
- aclp->z_ops.ace_data(acep,
- &data1)) != 0) {
- VERIFY((data2sz =
- aclp->z_ops.ace_data(acep2,
- &data2)) == data1sz);
- bcopy(data1, data2, data1sz);
- }
- aclp->z_acl_count++;
- aclnode2->z_ace_count++;
- aclp->z_acl_bytes += aclnode->z_size;
- zfs_securemode_update(zfsvfs,
- aclp, acep2);
- } else {
- newflags |= ACE_INHERIT_ONLY_ACE;
- aclp->z_ops.ace_flags_set(acep,
- newflags|ACE_INHERITED_ACE);
- }
-
+ zfs_restricted_update(zfsvfs, aclp, acep2);
+ } else {
+ newflags |= ACE_INHERIT_ONLY_ACE;
+ aclp->z_ops.ace_flags_set(acep,
+ newflags|ACE_INHERITED_ACE);
}
}
}
@@ -1771,6 +1781,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
zfs_acl_t *paclp;
xvattr_t *xvap = (xvattr_t *)vap;
gid_t gid;
+ boolean_t need_chmod = B_TRUE;
if (setaclp)
aclp = setaclp;
@@ -1837,7 +1848,7 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
mutex_enter(&parent->z_acl_lock);
VERIFY(0 == zfs_acl_node_read(parent, &paclp, B_FALSE));
mutex_exit(&parent->z_acl_lock);
- aclp = zfs_acl_inherit(zp, paclp);
+ aclp = zfs_acl_inherit(zp, paclp, &need_chmod);
zfs_acl_free(paclp);
} else {
aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
@@ -1845,7 +1856,8 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag,
mutex_exit(&parent->z_lock);
mutex_enter(&zp->z_lock);
mutex_enter(&zp->z_acl_lock);
- zfs_acl_chmod(zp, mode, aclp);
+ if (need_chmod)
+ zfs_acl_chmod(zp, mode, aclp);
} else {
mutex_enter(&zp->z_lock);
mutex_enter(&zp->z_acl_lock);