mirror of https://github.com/openzfs/zfs.git
OpenZFS 742 - Resurrect the ZFS "aclmode" property OpenZFS 664 - Umask masking "deny" ACL entries OpenZFS 279 - Bug in the new ACL (post-PSARC/2010/029) semantics
Porting notes: * Updated zfs_acl_chmod to take 'boolean_t isdir' as first parameter rather than 'zfsvfs_t *zfsvfs' * zfs man pages changes mixed between zfs and new zfsprops man pages Reviewed by: Aram Hvrneanu <aram@nexenta.com> Reviewed by: Gordon Ross <gwr@nexenta.com> Reviewed by: Robert Gordon <rbg@openrbg.com> Reviewed by: Mark.Maybee@oracle.com Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov> Approved by: Garrett D'Amore <garrett@nexenta.com> Ported-by: Paul B. Henson <henson@acm.org> OpenZFS-issue: https://www.illumos.org/issues/742 OpenZFS-issue: https://www.illumos.org/issues/664 OpenZFS-issue: https://www.illumos.org/issues/279 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/a3c49ce110 Closes #10266
This commit is contained in:
parent
d7d4678fe6
commit
a1af567bb6
|
@ -94,6 +94,7 @@ struct zfsvfs {
|
||||||
boolean_t z_fuid_dirty; /* need to sync fuid table ? */
|
boolean_t z_fuid_dirty; /* need to sync fuid table ? */
|
||||||
struct zfs_fuid_info *z_fuid_replay; /* fuid info for replay */
|
struct zfs_fuid_info *z_fuid_replay; /* fuid info for replay */
|
||||||
zilog_t *z_log; /* intent log pointer */
|
zilog_t *z_log; /* intent log pointer */
|
||||||
|
uint_t z_acl_mode; /* acl chmod/mode behavior */
|
||||||
uint_t z_acl_inherit; /* acl inheritance behavior */
|
uint_t z_acl_inherit; /* acl inheritance behavior */
|
||||||
uint_t z_acl_type; /* type of ACL usable on this FS */
|
uint_t z_acl_type; /* type of ACL usable on this FS */
|
||||||
zfs_case_t z_case; /* case-sense */
|
zfs_case_t z_case; /* case-sense */
|
||||||
|
|
|
@ -398,6 +398,7 @@ pool/home/bob readonly off default
|
||||||
pool/home/bob zoned off default
|
pool/home/bob zoned off default
|
||||||
pool/home/bob snapdir hidden default
|
pool/home/bob snapdir hidden default
|
||||||
pool/home/bob acltype off default
|
pool/home/bob acltype off default
|
||||||
|
pool/home/bob aclmode discard default
|
||||||
pool/home/bob aclinherit restricted default
|
pool/home/bob aclinherit restricted default
|
||||||
pool/home/bob canmount on default
|
pool/home/bob canmount on default
|
||||||
pool/home/bob xattr on default
|
pool/home/bob xattr on default
|
||||||
|
|
|
@ -599,23 +599,24 @@ accordance to the requested mode from the application.
|
||||||
The
|
The
|
||||||
.Sy aclinherit
|
.Sy aclinherit
|
||||||
property does not apply to POSIX ACLs.
|
property does not apply to POSIX ACLs.
|
||||||
.It Sy aclmode Ns = Ns Sy discard Ns | Ns Sy groupmask Ns | Ns Sy passthrough
|
.It Xo
|
||||||
.Ns Sy restricted
|
.Sy aclmode Ns = Ns Sy discard Ns | Ns Sy groupmask Ns | Ns
|
||||||
Controls how an
|
.Sy passthrough Ns
|
||||||
.Tn ACL
|
.Xc
|
||||||
is modified during
|
Controls how an ACL is modified during chmod(2) and how inherited ACEs
|
||||||
.Xr chmod 2 .
|
are modified by the file creation mode.
|
||||||
This property is not visible on Linux yet.
|
|
||||||
.Bl -tag -width "passthrough"
|
.Bl -tag -width "passthrough"
|
||||||
.It Sy discard
|
.It Sy discard
|
||||||
default, deletes all
|
default, deletes all
|
||||||
.Tn ACL
|
.Sy ACEs
|
||||||
entries that do not represent the mode of the file.
|
except for those representing
|
||||||
|
the mode of the file or directory requested by
|
||||||
|
.Xr chmod 2 .
|
||||||
.It Sy groupmask
|
.It Sy groupmask
|
||||||
reduces permissions granted in all
|
reduces permissions granted in all
|
||||||
.Em ALLOW
|
.Sy ALLOW
|
||||||
entried found in the
|
entries found in the
|
||||||
.Tn ACL
|
.Sy ACL
|
||||||
such that they are no greater than the group permissions specified by
|
such that they are no greater than the group permissions specified by
|
||||||
.Xr chmod 2 .
|
.Xr chmod 2 .
|
||||||
.It Sy passthrough
|
.It Sy passthrough
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1182,60 +1183,77 @@ zfs_acl_chown_setattr(znode_t *zp)
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
typedef struct trivial_acl {
|
||||||
acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
|
uint32_t allow0; /* allow mask for bits only in owner */
|
||||||
uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone)
|
uint32_t deny1; /* deny mask for bits not in owner */
|
||||||
|
uint32_t deny2; /* deny mask for bits not in group */
|
||||||
|
uint32_t owner; /* allow mask matching mode */
|
||||||
|
uint32_t group; /* allow mask matching mode */
|
||||||
|
uint32_t everyone; /* allow mask matching mode */
|
||||||
|
} trivial_acl_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
acl_trivial_access_masks(mode_t mode, boolean_t isdir, trivial_acl_t *masks)
|
||||||
{
|
{
|
||||||
*deny1 = *deny2 = *allow0 = *group = 0;
|
uint32_t read_mask = ACE_READ_DATA;
|
||||||
|
uint32_t write_mask = ACE_WRITE_DATA|ACE_APPEND_DATA;
|
||||||
|
uint32_t execute_mask = ACE_EXECUTE;
|
||||||
|
|
||||||
|
if (isdir)
|
||||||
|
write_mask |= ACE_DELETE_CHILD;
|
||||||
|
|
||||||
|
masks->deny1 = 0;
|
||||||
|
|
||||||
if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
|
if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
|
||||||
*deny1 |= ACE_READ_DATA;
|
masks->deny1 |= read_mask;
|
||||||
if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
|
if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
|
||||||
*deny1 |= ACE_WRITE_DATA;
|
masks->deny1 |= write_mask;
|
||||||
if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
|
if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
|
||||||
*deny1 |= ACE_EXECUTE;
|
masks->deny1 |= execute_mask;
|
||||||
|
|
||||||
|
masks->deny2 = 0;
|
||||||
if (!(mode & S_IRGRP) && (mode & S_IROTH))
|
if (!(mode & S_IRGRP) && (mode & S_IROTH))
|
||||||
*deny2 = ACE_READ_DATA;
|
masks->deny2 |= read_mask;
|
||||||
if (!(mode & S_IWGRP) && (mode & S_IWOTH))
|
if (!(mode & S_IWGRP) && (mode & S_IWOTH))
|
||||||
*deny2 |= ACE_WRITE_DATA;
|
masks->deny2 |= write_mask;
|
||||||
if (!(mode & S_IXGRP) && (mode & S_IXOTH))
|
if (!(mode & S_IXGRP) && (mode & S_IXOTH))
|
||||||
*deny2 |= ACE_EXECUTE;
|
masks->deny2 |= execute_mask;
|
||||||
|
|
||||||
|
masks->allow0 = 0;
|
||||||
if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
|
if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
|
||||||
*allow0 |= ACE_READ_DATA;
|
masks->allow0 |= read_mask;
|
||||||
if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
|
if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
|
||||||
*allow0 |= ACE_WRITE_DATA;
|
masks->allow0 |= write_mask;
|
||||||
if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
|
if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
|
||||||
*allow0 |= ACE_EXECUTE;
|
masks->allow0 |= execute_mask;
|
||||||
|
|
||||||
*owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
|
masks->owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
|
||||||
ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
|
ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
|
||||||
ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
|
ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
|
||||||
if (mode & S_IRUSR)
|
if (mode & S_IRUSR)
|
||||||
*owner |= ACE_READ_DATA;
|
masks->owner |= read_mask;
|
||||||
if (mode & S_IWUSR)
|
if (mode & S_IWUSR)
|
||||||
*owner |= ACE_WRITE_DATA|ACE_APPEND_DATA;
|
masks->owner |= write_mask;
|
||||||
if (mode & S_IXUSR)
|
if (mode & S_IXUSR)
|
||||||
*owner |= ACE_EXECUTE;
|
masks->owner |= execute_mask;
|
||||||
|
|
||||||
*group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
|
masks->group = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
|
||||||
ACE_SYNCHRONIZE;
|
ACE_SYNCHRONIZE;
|
||||||
if (mode & S_IRGRP)
|
if (mode & S_IRGRP)
|
||||||
*group |= ACE_READ_DATA;
|
masks->group |= read_mask;
|
||||||
if (mode & S_IWGRP)
|
if (mode & S_IWGRP)
|
||||||
*group |= ACE_WRITE_DATA|ACE_APPEND_DATA;
|
masks->group |= write_mask;
|
||||||
if (mode & S_IXGRP)
|
if (mode & S_IXGRP)
|
||||||
*group |= ACE_EXECUTE;
|
masks->group |= execute_mask;
|
||||||
|
|
||||||
*everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
|
masks->everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS|
|
||||||
ACE_SYNCHRONIZE;
|
ACE_SYNCHRONIZE;
|
||||||
if (mode & S_IROTH)
|
if (mode & S_IROTH)
|
||||||
*everyone |= ACE_READ_DATA;
|
masks->everyone |= read_mask;
|
||||||
if (mode & S_IWOTH)
|
if (mode & S_IWOTH)
|
||||||
*everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA;
|
masks->everyone |= write_mask;
|
||||||
if (mode & S_IXOTH)
|
if (mode & S_IXOTH)
|
||||||
*everyone |= ACE_EXECUTE;
|
masks->everyone |= execute_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1247,7 +1265,7 @@ acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
|
||||||
* have read_acl denied, and write_owner/write_acl/write_attributes
|
* have read_acl denied, and write_owner/write_acl/write_attributes
|
||||||
* can only be owner@ entry.
|
* can only be owner@ entry.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
ace_trivial_common(void *acep, int aclcnt,
|
ace_trivial_common(void *acep, int aclcnt,
|
||||||
uint64_t (*walk)(void *, uint64_t, int aclcnt,
|
uint64_t (*walk)(void *, uint64_t, int aclcnt,
|
||||||
uint16_t *, uint16_t *, uint32_t *))
|
uint16_t *, uint16_t *, uint32_t *))
|
||||||
|
@ -1283,10 +1301,17 @@ ace_trivial_common(void *acep, int aclcnt,
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete permissions are never set by default
|
* Delete permission is never set by default
|
||||||
*/
|
*/
|
||||||
if (mask & (ACE_DELETE|ACE_DELETE_CHILD))
|
if (mask & ACE_DELETE)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Child delete permission should be accompanied by write
|
||||||
|
*/
|
||||||
|
if ((mask & ACE_DELETE_CHILD) && !(mask & ACE_WRITE_DATA))
|
||||||
|
return (1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* only allow owner@ to have
|
* only allow owner@ to have
|
||||||
* write_acl/write_owner/write_attributes/write_xattr/
|
* write_acl/write_owner/write_attributes/write_xattr/
|
||||||
|
@ -1462,7 +1487,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
zfs_acl_chmod(boolean_t isdir, uint64_t mode, boolean_t trim, zfs_acl_t *aclp)
|
||||||
{
|
{
|
||||||
void *acep = NULL;
|
void *acep = NULL;
|
||||||
uint64_t who;
|
uint64_t who;
|
||||||
|
@ -1474,31 +1499,29 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||||
zfs_acl_node_t *newnode;
|
zfs_acl_node_t *newnode;
|
||||||
size_t abstract_size = aclp->z_ops->ace_abstract_size();
|
size_t abstract_size = aclp->z_ops->ace_abstract_size();
|
||||||
void *zacep;
|
void *zacep;
|
||||||
uint32_t owner, group, everyone;
|
trivial_acl_t masks;
|
||||||
uint32_t deny1, deny2, allow0;
|
|
||||||
|
|
||||||
new_count = new_bytes = 0;
|
new_count = new_bytes = 0;
|
||||||
|
|
||||||
acl_trivial_access_masks((mode_t)mode, &allow0, &deny1, &deny2,
|
acl_trivial_access_masks((mode_t)mode, isdir, &masks);
|
||||||
&owner, &group, &everyone);
|
|
||||||
|
|
||||||
newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
|
newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
|
||||||
|
|
||||||
zacep = newnode->z_acldata;
|
zacep = newnode->z_acldata;
|
||||||
if (allow0) {
|
if (masks.allow0) {
|
||||||
zfs_set_ace(aclp, zacep, allow0, ALLOW, -1, ACE_OWNER);
|
zfs_set_ace(aclp, zacep, masks.allow0, ALLOW, -1, ACE_OWNER);
|
||||||
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
||||||
new_count++;
|
new_count++;
|
||||||
new_bytes += abstract_size;
|
new_bytes += abstract_size;
|
||||||
}
|
}
|
||||||
if (deny1) {
|
if (masks.deny1) {
|
||||||
zfs_set_ace(aclp, zacep, deny1, DENY, -1, ACE_OWNER);
|
zfs_set_ace(aclp, zacep, masks.deny1, DENY, -1, ACE_OWNER);
|
||||||
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
||||||
new_count++;
|
new_count++;
|
||||||
new_bytes += abstract_size;
|
new_bytes += abstract_size;
|
||||||
}
|
}
|
||||||
if (deny2) {
|
if (masks.deny2) {
|
||||||
zfs_set_ace(aclp, zacep, deny2, DENY, -1, OWNING_GROUP);
|
zfs_set_ace(aclp, zacep, masks.deny2, DENY, -1, OWNING_GROUP);
|
||||||
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
||||||
new_count++;
|
new_count++;
|
||||||
new_bytes += abstract_size;
|
new_bytes += abstract_size;
|
||||||
|
@ -1517,10 +1540,17 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this ACL has any inheritable ACEs, mark that in
|
||||||
|
* the hints (which are later masked into the pflags)
|
||||||
|
* so create knows to do inheritance.
|
||||||
|
*/
|
||||||
|
if (isdir && (inherit_flags &
|
||||||
|
(ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
|
||||||
|
aclp->z_hints |= ZFS_INHERIT_ACE;
|
||||||
|
|
||||||
if ((type != ALLOW && type != DENY) ||
|
if ((type != ALLOW && type != DENY) ||
|
||||||
(inherit_flags & ACE_INHERIT_ONLY_ACE)) {
|
(inherit_flags & ACE_INHERIT_ONLY_ACE)) {
|
||||||
if (inherit_flags)
|
|
||||||
aclp->z_hints |= ZFS_INHERIT_ACE;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
|
case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
|
||||||
case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
|
case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
|
||||||
|
@ -1533,20 +1563,13 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Limit permissions to be no greater than
|
* Limit permissions to be no greater than
|
||||||
* group permissions
|
* group permissions.
|
||||||
|
* The "aclinherit" and "aclmode" properties
|
||||||
|
* affect policy for create and chmod(2),
|
||||||
|
* respectively.
|
||||||
*/
|
*/
|
||||||
if (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) {
|
if ((type == ALLOW) && trim)
|
||||||
if (!(mode & S_IRGRP))
|
access_mask &= masks.group;
|
||||||
access_mask &= ~ACE_READ_DATA;
|
|
||||||
if (!(mode & S_IWGRP))
|
|
||||||
access_mask &=
|
|
||||||
~(ACE_WRITE_DATA|ACE_APPEND_DATA);
|
|
||||||
if (!(mode & S_IXGRP))
|
|
||||||
access_mask &= ~ACE_EXECUTE;
|
|
||||||
access_mask &=
|
|
||||||
~(ACE_WRITE_OWNER|ACE_WRITE_ACL|
|
|
||||||
ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
zfs_set_ace(aclp, zacep, access_mask, type, who, iflags);
|
zfs_set_ace(aclp, zacep, access_mask, type, who, iflags);
|
||||||
ace_size = aclp->z_ops->ace_size(acep);
|
ace_size = aclp->z_ops->ace_size(acep);
|
||||||
|
@ -1554,11 +1577,11 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||||
new_count++;
|
new_count++;
|
||||||
new_bytes += ace_size;
|
new_bytes += ace_size;
|
||||||
}
|
}
|
||||||
zfs_set_ace(aclp, zacep, owner, 0, -1, ACE_OWNER);
|
zfs_set_ace(aclp, zacep, masks.owner, 0, -1, ACE_OWNER);
|
||||||
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
||||||
zfs_set_ace(aclp, zacep, group, 0, -1, OWNING_GROUP);
|
zfs_set_ace(aclp, zacep, masks.group, 0, -1, OWNING_GROUP);
|
||||||
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
zacep = (void *)((uintptr_t)zacep + abstract_size);
|
||||||
zfs_set_ace(aclp, zacep, everyone, 0, -1, ACE_EVERYONE);
|
zfs_set_ace(aclp, zacep, masks.everyone, 0, -1, ACE_EVERYONE);
|
||||||
|
|
||||||
new_count += 3;
|
new_count += 3;
|
||||||
new_bytes += abstract_size * 3;
|
new_bytes += abstract_size * 3;
|
||||||
|
@ -1573,16 +1596,24 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
||||||
int
|
int
|
||||||
zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
|
zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
|
||||||
{
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
mutex_enter(&zp->z_acl_lock);
|
mutex_enter(&zp->z_acl_lock);
|
||||||
mutex_enter(&zp->z_lock);
|
mutex_enter(&zp->z_lock);
|
||||||
*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
|
if (ZTOZSB(zp)->z_acl_mode == ZFS_ACL_DISCARD)
|
||||||
(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
|
*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
|
||||||
zfs_acl_chmod(ZTOZSB(zp), mode, *aclp);
|
else
|
||||||
|
error = zfs_acl_node_read(zp, B_TRUE, aclp, B_TRUE);
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
|
(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
|
||||||
|
zfs_acl_chmod(S_ISDIR(ZTOI(zp)->i_mode), mode,
|
||||||
|
(ZTOZSB(zp)->z_acl_mode == ZFS_ACL_GROUPMASK), *aclp);
|
||||||
|
}
|
||||||
mutex_exit(&zp->z_lock);
|
mutex_exit(&zp->z_lock);
|
||||||
mutex_exit(&zp->z_acl_lock);
|
mutex_exit(&zp->z_acl_lock);
|
||||||
ASSERT(*aclp);
|
|
||||||
|
|
||||||
return (0);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1834,8 +1865,8 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||||
if (acl_ids->z_aclp == NULL) {
|
if (acl_ids->z_aclp == NULL) {
|
||||||
mutex_enter(&dzp->z_acl_lock);
|
mutex_enter(&dzp->z_acl_lock);
|
||||||
mutex_enter(&dzp->z_lock);
|
mutex_enter(&dzp->z_lock);
|
||||||
if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) &&
|
if (!(flag & IS_ROOT_NODE) &&
|
||||||
(dzp->z_pflags & ZFS_INHERIT_ACE)) &&
|
(dzp->z_pflags & ZFS_INHERIT_ACE) &&
|
||||||
!(dzp->z_pflags & ZFS_XATTR)) {
|
!(dzp->z_pflags & ZFS_XATTR)) {
|
||||||
VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
|
VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
|
||||||
&paclp, B_FALSE));
|
&paclp, B_FALSE));
|
||||||
|
@ -1852,7 +1883,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
|
||||||
if (need_chmod) {
|
if (need_chmod) {
|
||||||
acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
|
acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
|
||||||
ZFS_ACL_AUTO_INHERIT : 0;
|
ZFS_ACL_AUTO_INHERIT : 0;
|
||||||
zfs_acl_chmod(zfsvfs, acl_ids->z_mode, acl_ids->z_aclp);
|
zfs_acl_chmod(S_ISDIR(vap->va_mode), acl_ids->z_mode,
|
||||||
|
(zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED),
|
||||||
|
acl_ids->z_aclp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -438,6 +438,14 @@ vscan_changed_cb(void *arg, uint64_t newval)
|
||||||
((zfsvfs_t *)arg)->z_vscan = newval;
|
((zfsvfs_t *)arg)->z_vscan = newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
acl_mode_changed_cb(void *arg, uint64_t newval)
|
||||||
|
{
|
||||||
|
zfsvfs_t *zfsvfs = arg;
|
||||||
|
|
||||||
|
zfsvfs->z_acl_mode = newval;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
acl_inherit_changed_cb(void *arg, uint64_t newval)
|
acl_inherit_changed_cb(void *arg, uint64_t newval)
|
||||||
{
|
{
|
||||||
|
@ -497,6 +505,8 @@ zfs_register_callbacks(vfs_t *vfsp)
|
||||||
zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zfsvfs);
|
zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zfsvfs);
|
||||||
error = error ? error : dsl_prop_register(ds,
|
error = error ? error : dsl_prop_register(ds,
|
||||||
zfs_prop_to_name(ZFS_PROP_ACLTYPE), acltype_changed_cb, zfsvfs);
|
zfs_prop_to_name(ZFS_PROP_ACLTYPE), acltype_changed_cb, zfsvfs);
|
||||||
|
error = error ? error : dsl_prop_register(ds,
|
||||||
|
zfs_prop_to_name(ZFS_PROP_ACLMODE), acl_mode_changed_cb, zfsvfs);
|
||||||
error = error ? error : dsl_prop_register(ds,
|
error = error ? error : dsl_prop_register(ds,
|
||||||
zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb,
|
zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb,
|
||||||
zfsvfs);
|
zfsvfs);
|
||||||
|
|
|
@ -176,6 +176,13 @@ zfs_prop_init(void)
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static zprop_index_t acl_mode_table[] = {
|
||||||
|
{ "discard", ZFS_ACL_DISCARD },
|
||||||
|
{ "groupmask", ZFS_ACL_GROUPMASK },
|
||||||
|
{ "passthrough", ZFS_ACL_PASSTHROUGH },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
static zprop_index_t acl_inherit_table[] = {
|
static zprop_index_t acl_inherit_table[] = {
|
||||||
{ "discard", ZFS_ACL_DISCARD },
|
{ "discard", ZFS_ACL_DISCARD },
|
||||||
{ "noallow", ZFS_ACL_NOALLOW },
|
{ "noallow", ZFS_ACL_NOALLOW },
|
||||||
|
@ -338,16 +345,13 @@ zfs_prop_init(void)
|
||||||
zprop_register_index(ZFS_PROP_SNAPDEV, "snapdev", ZFS_SNAPDEV_HIDDEN,
|
zprop_register_index(ZFS_PROP_SNAPDEV, "snapdev", ZFS_SNAPDEV_HIDDEN,
|
||||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
|
||||||
"hidden | visible", "SNAPDEV", snapdev_table);
|
"hidden | visible", "SNAPDEV", snapdev_table);
|
||||||
#ifdef __FreeBSD__
|
|
||||||
zprop_register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_DISCARD,
|
zprop_register_index(ZFS_PROP_ACLMODE, "aclmode", ZFS_ACL_DISCARD,
|
||||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||||
"discard | groupmask | passthrough | restricted", "ACLMODE",
|
"discard | groupmask | passthrough | restricted", "ACLMODE",
|
||||||
acl_mode_table);
|
acl_mode_table);
|
||||||
#else
|
|
||||||
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype", ZFS_ACLTYPE_OFF,
|
zprop_register_index(ZFS_PROP_ACLTYPE, "acltype", ZFS_ACLTYPE_OFF,
|
||||||
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
||||||
"noacl | posixacl", "ACLTYPE", acltype_table);
|
"noacl | posixacl", "ACLTYPE", acltype_table);
|
||||||
#endif
|
|
||||||
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
|
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
|
||||||
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
||||||
"discard | noallow | restricted | passthrough | passthrough-x",
|
"discard | noallow | restricted | passthrough | passthrough-x",
|
||||||
|
@ -622,11 +626,6 @@ zfs_prop_init(void)
|
||||||
ZFS_ACLTYPE_OFF, NULL, PROP_INHERIT,
|
ZFS_ACLTYPE_OFF, NULL, PROP_INHERIT,
|
||||||
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
|
||||||
"noacl | posixacl", "ACLTYPE", B_FALSE, B_FALSE, acltype_table);
|
"noacl | posixacl", "ACLTYPE", B_FALSE, B_FALSE, acltype_table);
|
||||||
#else
|
|
||||||
zprop_register_impl(ZFS_PROP_ACLMODE, "aclmode", PROP_TYPE_INDEX,
|
|
||||||
ZFS_ACL_DISCARD, NULL, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
|
|
||||||
"discard | groupmask | passthrough | restricted", "ACLMODE",
|
|
||||||
B_FALSE, B_FALSE, acl_mode_table);
|
|
||||||
#endif
|
#endif
|
||||||
zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
|
zprop_register_hidden(ZFS_PROP_REMAPTXG, "remaptxg", PROP_TYPE_NUMBER,
|
||||||
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");
|
PROP_READONLY, ZFS_TYPE_DATASET, "REMAPTXG");
|
||||||
|
|
Loading…
Reference in New Issue