</listitem>
</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>
struct smbacl4_vfs_params nfs4_params;
bool zfsacl_map_dacl_protected;
bool zfsacl_denymissingspecial;
+ bool zfsacl_block_special;
};
/* zfs_get_nt_acl()
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;
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
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);
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;
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);