summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walker <awalker@ixsystems.com>2020-09-24 11:42:16 -0400
committerKarolin Seeger <kseeger@samba.org>2020-10-30 13:54:18 +0000
commit1bf997aa2443248b07933dfc2dc5d9f3cadeef4b (patch)
tree2ee434510025d99a0e134da628ec40772f40fe50
parent78d843f43626a876557d3c6738329282adeb4dab (diff)
downloadsamba-1bf997aa2443248b07933dfc2dc5d9f3cadeef4b.tar.gz
vfs_zfsacl: Add new parameter to stop automatic addition of special entries
Prevent ZFS from automatically adding NFSv4 special entries (owner@, group@, everyone@). ZFS will automatically add these these entries when calculating the inherited ACL of new files if the ACL of the parent directory lacks an inheriting special entry. This may result in user confusion and unexpected change in permissions of files and directories as the inherited ACL is generated. Blocking this behavior is achieved by setting an inheriting everyone@ that grants no permissions and not adding the entry to the file's Security Descriptor. This change also updates behavior so that the fd-based syscall facl() is used where possible. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14470 RN: vfs_zfsacl: Add new parameter to stop automatic addition of special entries Signed-off-by: Andrew Walker <awalker@ixsystems.com> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit c10ae30c1185463eb937f69c1fc9914558087167)
-rw-r--r--docs-xml/manpages/vfs_zfsacl.8.xml20
-rw-r--r--source3/modules/vfs_zfsacl.c24
2 files changed, 44 insertions, 0 deletions
diff --git a/docs-xml/manpages/vfs_zfsacl.8.xml b/docs-xml/manpages/vfs_zfsacl.8.xml
index ae583409fe1..1ac954b9429 100644
--- a/docs-xml/manpages/vfs_zfsacl.8.xml
+++ b/docs-xml/manpages/vfs_zfsacl.8.xml
@@ -141,6 +141,26 @@
</varlistentry>
<varlistentry>
+ <term>zfsacl:block_special = [yes|no]</term>
+ <listitem>
+ <para>Prevent ZFS from automatically adding NFSv4 special
+ entries (owner@, group@, everyone@). ZFS will automatically
+ generate these these entries when calculating the inherited ACL
+ of new files if the ACL of the parent directory lacks an
+ inheriting special entry. This may result in user confusion and
+ unexpected change in permissions of files and directories as the
+ inherited ACL is generated. Blocking this behavior is achieved
+ by setting an inheriting everyone@ that grants no permissions
+ and not adding the entry to the file's Security
+ Descriptor</para>
+ <itemizedlist>
+ <listitem><para><command>yes (default)</command></para></listitem>
+ <listitem><para><command>no</command></para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>zfsacl:map_dacl_protected = [yes|no]</term>
<listitem>
<para>If enabled and the ZFS ACL on the underlying filesystem does not contain
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index d3da7257838..f5deeb11cc6 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -40,6 +40,7 @@ struct zfsacl_config_data {
struct smbacl4_vfs_params nfs4_params;
bool zfsacl_map_dacl_protected;
bool zfsacl_denymissingspecial;
+ bool zfsacl_block_special;
};
/* zfs_get_nt_acl()
@@ -57,6 +58,7 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
int i;
struct SMB4ACL_T *pacl;
SMB_STRUCT_STAT sbuf;
+ SMB_ACE4PROP_T blocking_ace;
const SMB_STRUCT_STAT *psbuf = NULL;
int ret;
bool inherited_is_present = false;
@@ -91,6 +93,13 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
aceprop.aceMask = (uint32_t) acebuf[i].a_access_mask;
aceprop.who.id = (uint32_t) acebuf[i].a_who;
+ if (config->zfsacl_block_special &&
+ (aceprop.aceMask == 0) &&
+ (aceprop.aceFlags & ACE_EVERYONE) &&
+ (aceprop.aceFlags & ACE_INHERITED_ACE))
+ {
+ continue;
+ }
/*
* Windows clients expect SYNC on acls to correctly allow
* rename, cf bug #7909. But not on DENY ace entries, cf bug
@@ -147,12 +156,17 @@ static bool zfs_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
struct SMB4ACE_T *smbace;
TALLOC_CTX *mem_ctx;
bool have_special_id = false;
+ bool must_add_empty_ace = false;
struct zfsacl_config_data *config = NULL;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct zfsacl_config_data,
return False);
+ if (config->zfsacl_block_special && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
+ naces++;
+ must_add_empty_ace = true;
+ }
/* allocate the field of ZFS aces */
mem_ctx = talloc_tos();
acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*naces);
@@ -192,6 +206,13 @@ static bool zfs_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
have_special_id = true;
}
}
+ if (must_add_empty_ace) {
+ acebuf[i].a_type = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE;
+ acebuf[i].a_flags = SMB_ACE4_DIRECTORY_INHERIT_ACE| \
+ SMB_ACE4_FILE_INHERIT_ACE|ACE_EVERYONE;
+ acebuf[i].a_access_mask = 0;
+ i++;
+ }
if (!have_special_id && config->zfsacl_denymissingspecial) {
errno = EACCES;
@@ -555,6 +576,9 @@ static int zfsacl_connect(struct vfs_handle_struct *handle,
config->zfsacl_denymissingspecial = lp_parm_bool(SNUM(handle->conn),
"zfsacl", "denymissingspecial", false);
+ config->zfsacl_block_special = lp_parm_bool(SNUM(handle->conn),
+ "zfsacl", "block_special", true);
+
ret = smbacl4_get_vfs_params(handle->conn, &config->nfs4_params);
if (ret < 0) {
TALLOC_FREE(config);