From: awalker Date: Fri, 30 Aug 2019 19:30:57 +0000 (-0400) Subject: vfs_zfsacl: fix issue with ACL inheritance in zfsacl X-Git-Tag: ldb-2.1.0~147 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30f9e1dd596a0dc4894f17b07a7e2e58dcb75c16;p=thirdparty%2Fsamba.git vfs_zfsacl: fix issue with ACL inheritance in zfsacl Add parameter zfsacl:map_dacl_protected to address issue preventing Windows Clients from disabling inheritance on ACLs. FreeBSD does not currently expose the ACL_PROTECTED NFS4.1 flag, but it does expose ACE4_INHERITED_ACE. When the parameter is enabled, map the absence of ACE4_INHERITED_ACE to SEC_DESC_DACL_PROTECTED. See also the discussion at https://gitlab.com/samba-team/samba/merge_requests/719 Signed-off-by: Andrew Walker Reviewed-by: Ralph Boehme Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Dec 20 23:24:54 UTC 2019 on sn-devel-184 --- diff --git a/docs-xml/manpages/vfs_zfsacl.8.xml b/docs-xml/manpages/vfs_zfsacl.8.xml index 3eb0760dcba..ae583409fe1 100644 --- a/docs-xml/manpages/vfs_zfsacl.8.xml +++ b/docs-xml/manpages/vfs_zfsacl.8.xml @@ -140,6 +140,25 @@ + + zfsacl:map_dacl_protected = [yes|no] + + If enabled and the ZFS ACL on the underlying filesystem does not contain + any inherited access control entires, then set the SEC_DESC_DACL_PROTECTED flag + on the Security Descriptor returned to SMB clients. + This ensures correct Windows client behavior when disabling inheritance on + directories. + + Following is the behaviour of Samba for different values : + + yes - Enable mapping to + SEC_DESC_DACL_PROTECTED + no (default) + + + + + diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index 2fc1714dc86..524881ab4af 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -38,6 +38,7 @@ struct zfsacl_config_data { struct smbacl4_vfs_params nfs4_params; + bool zfsacl_map_dacl_protected; bool zfsacl_denymissingspecial; }; @@ -57,6 +58,7 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn, SMB_STRUCT_STAT sbuf; const SMB_STRUCT_STAT *psbuf = NULL; int ret; + bool inherited_is_present = false; bool is_dir; if (VALID_STAT(smb_fname->st)) { @@ -123,6 +125,11 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn, aceprop.aceMask |= SMB_ACE4_DELETE_CHILD; } +#ifdef ACE_INHERITED_ACE + if (aceprop.aceFlags & ACE_INHERITED_ACE) { + inherited_is_present = true; + } +#endif if(aceprop.aceFlags & ACE_OWNER) { aceprop.flags = SMB_ACE4_ID_SPECIAL; aceprop.who.special_id = SMB_ACE4_WHO_OWNER; @@ -139,6 +146,15 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn, return NT_STATUS_NO_MEMORY; } +#ifdef ACE_INHERITED_ACE + if (!inherited_is_present && config->zfsacl_map_dacl_protected) { + DBG_DEBUG("Setting SEC_DESC_DACL_PROTECTED on [%s]\n", + smb_fname_str_dbg(smb_fname)); + smbacl4_set_controlflags(pacl, + SEC_DESC_DACL_PROTECTED | + SEC_DESC_SELF_RELATIVE); + } +#endif *ppacl = pacl; return NT_STATUS_OK; } @@ -443,6 +459,9 @@ static int zfsacl_connect(struct vfs_handle_struct *handle, return -1; } + config->zfsacl_map_dacl_protected = lp_parm_bool(SNUM(handle->conn), + "zfsacl", "map_dacl_protected", false); + config->zfsacl_denymissingspecial = lp_parm_bool(SNUM(handle->conn), "zfsacl", "denymissingspecial", false);