diff options
-rw-r--r-- | docs-xml/manpages/vfs_zfsacl.8.xml | 20 | ||||
-rw-r--r-- | source3/modules/vfs_zfsacl.c | 24 |
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); |