[SCM] Samba Shared Repository - branch v4-12-test updated

Karolin Seeger kseeger at samba.org
Fri Oct 30 15:25:02 UTC 2020


The branch, v4-12-test has been updated
       via  7e955ca5cf9 ctdb-common: Avoid aliasing errors during code optimization
       via  e1f7e422bd5 vfs_zfsacl: only grant DELETE_CHILD if ACL tag is special
       via  e14dfa439e7 vfs_zfsacl: use a helper variable in zfs_get_nt_acl_common()
       via  b260c3003bb vfs_zfsacl: README.Coding fix
       via  1bf997aa244 vfs_zfsacl: Add new parameter to stop automatic addition of special entries
       via  78d843f4362 vfs_zfsacl: use handle based facl() call to query ZFS filesytem ACL
       via  fe842a5412a smb.conf.5: add clarification how configuration changes reflected by Samba
      from  2b4c9b9baca VERSION: Bump version up to 4.12.10.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-12-test


- Log -----------------------------------------------------------------
commit 7e955ca5cf91a3cfdc53132c362de0b6c4ffa64b
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 27 12:51:41 2020 +1000

    ctdb-common: Avoid aliasing errors during code optimization
    
    When compiling with GCC 10.x and -O3 optimization, the IP checksum
    calculation code generates wrong checksum.  The function uint16_checksum
    gets inlined during optimization and ip4pkt->tcp data gets wrongly
    aliased.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14537
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>
    
    Autobuild-User(master): Martin Schwenke <martins at samba.org>
    Autobuild-Date(master): Wed Oct 21 05:52:28 UTC 2020 on sn-devel-184
    
    (cherry picked from commit 6aa396b0cd1f83f45cb76a4f3123d99135e8dd8c)
    
    Autobuild-User(v4-12-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-12-test): Fri Oct 30 15:24:11 UTC 2020 on sn-devel-184

commit e1f7e422bd560196f735c96e6bf6d84524d169a7
Author: Andrew Walker <awalker at ixsystems.com>
Date:   Thu Sep 24 16:04:12 2020 -0400

    vfs_zfsacl: only grant DELETE_CHILD if ACL tag is special
    
    When ZFS aclmode is set to "passthrough" chmod(2)/fchmod(2) will result
    in special entries being modified in a way such that delete, delete_child,
    write_named_attr, write_attribute are stripped from the returned ACL entry,
    and the kernel / ZFS treats this as having rights equivalent to the desired
    POSIX mode. Historically, samba has added delete_child to the NFSv4 ACL, but
    this is only really called for in the case of special entries in this
    particular circumstance.
    
    Alter circumstances in which delete_child is granted so that it only
    is added to special entries. This preserves the intend post-chmod behavior,
    but avoids unnecessarily increasing permissions in cases where it's not
    intended. Further modification of this behavior may be required so that
    we grant a general read or general write permissions set in case of
    POSIX read / POSIX write on special entries.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14471
    RN: vfs_zfsacl: only grant DELETE_CHILD if ACL tag is special
    
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c1a37b4f31d5252ce074d41f69e526aa84b0d3b3)

commit e14dfa439e720719fbb4ff7ab8265e4a59c81278
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Aug 20 16:41:36 2020 +0200

    vfs_zfsacl: use a helper variable in zfs_get_nt_acl_common()
    
    No change in behaviour.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14471
    
    Pair-Programmed-With: Andrew Walker <awalker at ixsystems.com>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 13b4f913b06457d8e1f7cf71c85722bbecabd990)

commit b260c3003bbb0ca9f539ad5cae5364c0fcd5515b
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Aug 20 16:42:17 2020 +0200

    vfs_zfsacl: README.Coding fix
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14471
    
    Pair-Programmed-With: Andrew Walker <awalker at ixsystems.com>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit a182f2e6cdded739812e209430d340097acc0031)

commit 1bf997aa2443248b07933dfc2dc5d9f3cadeef4b
Author: Andrew Walker <awalker at ixsystems.com>
Date:   Thu Sep 24 11:42:16 2020 -0400

    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 at ixsystems.com>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c10ae30c1185463eb937f69c1fc9914558087167)

commit 78d843f43626a876557d3c6738329282adeb4dab
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Aug 20 16:18:35 2020 +0200

    vfs_zfsacl: use handle based facl() call to query ZFS filesytem ACL
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14470
    
    Pair-Programmed-With: Andrew Walker <awalker at ixsystems.com>
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (backported from commit f763b1e43640082af80c855a4a519f7747a6c87c)
    [slow at samba.org: conflict in zfs_get_nt_acl_common() due to *AT changes in 4.13]

commit fe842a5412a914018e773a9a4930523905772ca2
Author: Alexander Bokovoy <ab at samba.org>
Date:   Sat Oct 17 10:58:12 2020 +0300

    smb.conf.5: add clarification how configuration changes reflected by Samba
    
    Users of Linux distributions know to read smb.conf(5) manual page but
    apparently not many of them read smbd(8) and winbindd(8) to understand
    how changes to smb.conf file are reflected in the running processes.
    
    Add a small section that makes it clear where to find relevant
    information. Also correct the information in smbd, nmbd, and winbindd
    manual pages.
    
    The interval at which smbd does check for smb.conf changes was increased
    from 60 seconds to 180 seconds in 1999 with commit 3db52feb1f3b.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14538
    
    Signed-off-by: Alexander Bokovoy <ab at samba.org>
    Reviewed-by: Isaac Boukris <iboukris at samba.org>
    
    Autobuild-User(master): Alexander Bokovoy <ab at samba.org>
    Autobuild-Date(master): Tue Oct 20 08:50:13 UTC 2020 on sn-devel-184
    
    (cherry picked from commit e32846f0692df44b4ee929c5ed6ba1de88ec4bd2)

-----------------------------------------------------------------------

Summary of changes:
 ctdb/common/system_socket.c        |  31 +++---
 docs-xml/manpages/nmbd.8.xml       |  10 +-
 docs-xml/manpages/smb.conf.5.xml   |  30 ++++++
 docs-xml/manpages/smbd.8.xml       |  13 ++-
 docs-xml/manpages/vfs_zfsacl.8.xml |  20 ++++
 docs-xml/manpages/winbindd.8.xml   |   7 +-
 source3/modules/vfs_zfsacl.c       | 203 ++++++++++++++++++++++++++++++-------
 7 files changed, 256 insertions(+), 58 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c
index af297f8608b..bb513508353 100644
--- a/ctdb/common/system_socket.c
+++ b/ctdb/common/system_socket.c
@@ -67,16 +67,19 @@
 /*
   uint16 checksum for n bytes
  */
-static uint32_t uint16_checksum(uint16_t *data, size_t n)
+static uint32_t uint16_checksum(uint8_t *data, size_t n)
 {
 	uint32_t sum=0;
+	uint16_t value;
+
 	while (n>=2) {
-		sum += (uint32_t)ntohs(*data);
-		data++;
+		memcpy(&value, data, 2);
+		sum += (uint32_t)ntohs(value);
+		data += 2;
 		n -= 2;
 	}
 	if (n == 1) {
-		sum += (uint32_t)ntohs(*(uint8_t *)data);
+		sum += (uint32_t)ntohs(*data);
 	}
 	return sum;
 }
@@ -117,13 +120,13 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *_addr)
 /*
  * simple TCP checksum - assumes data is multiple of 2 bytes long
  */
-static uint16_t ip_checksum(uint16_t *data, size_t n, struct ip *ip)
+static uint16_t ip_checksum(uint8_t *data, size_t n, struct ip *ip)
 {
 	uint32_t sum = uint16_checksum(data, n);
 	uint16_t sum2;
 
-	sum += uint16_checksum((uint16_t *)&ip->ip_src, sizeof(ip->ip_src));
-	sum += uint16_checksum((uint16_t *)&ip->ip_dst, sizeof(ip->ip_dst));
+	sum += uint16_checksum((uint8_t *)&ip->ip_src, sizeof(ip->ip_src));
+	sum += uint16_checksum((uint8_t *)&ip->ip_dst, sizeof(ip->ip_dst));
 	sum += ip->ip_p + n;
 	sum = (sum & 0xFFFF) + (sum >> 16);
 	sum = (sum & 0xFFFF) + (sum >> 16);
@@ -135,22 +138,22 @@ static uint16_t ip_checksum(uint16_t *data, size_t n, struct ip *ip)
 	return sum2;
 }
 
-static uint16_t ip6_checksum(uint16_t *data, size_t n, struct ip6_hdr *ip6)
+static uint16_t ip6_checksum(uint8_t *data, size_t n, struct ip6_hdr *ip6)
 {
 	uint16_t phdr[3];
 	uint32_t sum = 0;
 	uint16_t sum2;
 	uint32_t len;
 
-	sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_src, 16);
-	sum += uint16_checksum((uint16_t *)(void *)&ip6->ip6_dst, 16);
+	sum += uint16_checksum((uint8_t *)&ip6->ip6_src, 16);
+	sum += uint16_checksum((uint8_t *)&ip6->ip6_dst, 16);
 
 	len = htonl(n);
 	phdr[0] = len & UINT16_MAX;
 	phdr[1] = (len >> 16) & UINT16_MAX;
 	/* ip6_nxt is only 8 bits, so fits comfortably into a uint16_t */
 	phdr[2] = htons(ip6->ip6_nxt);
-	sum += uint16_checksum(phdr, sizeof(phdr));
+	sum += uint16_checksum((uint8_t *)phdr, sizeof(phdr));
 
 	sum += uint16_checksum(data, n);
 
@@ -316,7 +319,7 @@ static int ip6_na_build(uint8_t *buffer,
 				   sizeof(struct nd_opt_hdr));
 	memcpy(ea, hwaddr, ETH_ALEN);
 
-	nd_na->nd_na_cksum = ip6_checksum((uint16_t *)nd_na,
+	nd_na->nd_na_cksum = ip6_checksum((uint8_t *)nd_na,
 					  ntohs(ip6->ip6_plen),
 					  ip6);
 
@@ -556,7 +559,7 @@ static int tcp4_build(uint8_t *buf,
 	ip4pkt->tcp.th_off   = sizeof(ip4pkt->tcp)/sizeof(uint32_t);
 	/* this makes it easier to spot in a sniffer */
 	ip4pkt->tcp.th_win   = htons(1234);
-	ip4pkt->tcp.th_sum   = ip_checksum((uint16_t *)&ip4pkt->tcp,
+	ip4pkt->tcp.th_sum   = ip_checksum((uint8_t *)&ip4pkt->tcp,
 					   sizeof(ip4pkt->tcp),
 					   &ip4pkt->ip);
 
@@ -609,7 +612,7 @@ static int tcp6_build(uint8_t *buf,
 	ip6pkt->tcp.th_off    = sizeof(ip6pkt->tcp)/sizeof(uint32_t);
 	/* this makes it easier to spot in a sniffer */
 	ip6pkt->tcp.th_win   = htons(1234);
-	ip6pkt->tcp.th_sum   = ip6_checksum((uint16_t *)&ip6pkt->tcp,
+	ip6pkt->tcp.th_sum   = ip6_checksum((uint8_t *)&ip6pkt->tcp,
 					    sizeof(ip6pkt->tcp),
 					    &ip6pkt->ip6);
 
diff --git a/docs-xml/manpages/nmbd.8.xml b/docs-xml/manpages/nmbd.8.xml
index c145e820770..4ece42f3ca6 100644
--- a/docs-xml/manpages/nmbd.8.xml
+++ b/docs-xml/manpages/nmbd.8.xml
@@ -244,7 +244,15 @@
 	directory (or the <filename>var/locks</filename> directory configured
 	under wherever Samba was configured to install itself). This will also
 	cause <command>nmbd</command> to dump out its server database in
-	the <filename>log.nmb</filename> file.</para>
+	the <filename>log.nmb</filename> file. Additionally, the signal will
+	cause reloading <command>nmbd</command> configuration.</para>
+
+        <para>
+        Instead of sending a SIGHUP signal, a request to dump namelists
+        into the file and reload a configuration file may be sent using
+        <citerefentry><refentrytitle>smbcontrol</refentrytitle>
+       <manvolnum>1</manvolnum></citerefentry> program.
+        </para>
 
 	<para>The debug log level of nmbd may be raised or lowered
 	using <citerefentry><refentrytitle>smbcontrol</refentrytitle>
diff --git a/docs-xml/manpages/smb.conf.5.xml b/docs-xml/manpages/smb.conf.5.xml
index f72833c003f..c4387187ecc 100644
--- a/docs-xml/manpages/smb.conf.5.xml
+++ b/docs-xml/manpages/smb.conf.5.xml
@@ -27,6 +27,36 @@
 	</para>
 </refsect1>
 
+<refsect1>
+	<title>HOW CONFIGURATION CHANGES ARE APPLIED</title>
+
+	<para>
+	The Samba suite includes a number of different programs. Some of them operate in a client mode, others are
+	server daemons that provide various services to its clients. The <filename moreinfo="none">smb.conf
+        </filename> file is processed in the following way:
+        </para>
+
+	<itemizedlist>
+		<listitem><para>
+		The Samba suite's client applications read their configuration only once. Any changes made after start aren't
+		reflected in the context of already running client code.
+		</para></listitem>
+
+		<listitem><para>
+		The Samba suite's server daemons reload their configuration when requested. However, already active connections
+		do not change their configuration. More detailed information can be found in
+		<citerefentry><refentrytitle>smbd</refentrytitle><manvolnum>8</manvolnum></citerefentry> and <citerefentry>
+		<refentrytitle>winbindd</refentrytitle><manvolnum>8</manvolnum></citerefentry> manual pages.
+                </para></listitem>
+	</itemizedlist>
+
+	<para>
+	To request Samba server daemons to refresh their configuration, please use
+	<citerefentry><refentrytitle>smbcontrol</refentrytitle><manvolnum>1</manvolnum></citerefentry> utility.
+        </para>
+
+</refsect1>
+
 <refsect1 id="FILEFORMATSECT">
 	<title>FILE FORMAT</title>
 
diff --git a/docs-xml/manpages/smbd.8.xml b/docs-xml/manpages/smbd.8.xml
index deba2cad9e2..73d808c70b7 100644
--- a/docs-xml/manpages/smbd.8.xml
+++ b/docs-xml/manpages/smbd.8.xml
@@ -68,11 +68,18 @@
 	the copy of the server for that client terminates.</para>
 
 	<para>The configuration file, and any files that it includes, 
-	are automatically reloaded every minute, if they change.  You 
-	can force a reload by sending a SIGHUP to the server.  Reloading 
+	are automatically reloaded every three minutes, if they change.
+	One can force a reload by sending a SIGHUP to the server. Reloading
 	the configuration file will not affect connections to any service 
 	that is already established.  Either the user will have to 
-	disconnect from the service, or <command>smbd</command> killed and restarted.</para>
+	disconnect from the service, or <command>smbd</command> killed and restarted.
+        </para>
+
+        <para>Instead of sending a SIGHUP signal, a request to reload configuration
+	file may be sent using <citerefentry><refentrytitle>smbcontrol</refentrytitle>
+	<manvolnum>1</manvolnum></citerefentry> program.
+        </para>
+
 </refsect1>
 
 <refsect1>
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
@@ -140,6 +140,26 @@
 		</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>
diff --git a/docs-xml/manpages/winbindd.8.xml b/docs-xml/manpages/winbindd.8.xml
index 71fb248c204..99c00388c20 100644
--- a/docs-xml/manpages/winbindd.8.xml
+++ b/docs-xml/manpages/winbindd.8.xml
@@ -390,7 +390,12 @@ auth  required    /lib/security/pam_unix.so \
 		apply any parameter changes to the running
 		version of winbindd.  This signal also clears any cached
 		user and group information.  The list of other domains trusted
-		by winbindd is also reloaded.  </para></listitem>
+		by winbindd is also reloaded.
+		</para>
+		<para>Instead of sending a SIGHUP signal, a request to reload configuration
+		file may be sent using <citerefentry><refentrytitle>smbcontrol</refentrytitle>
+		<manvolnum>1</manvolnum></citerefentry> program.
+		</para></listitem>
 		</varlistentry>
 
 		<varlistentry>
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 524881ab4af..9626f21a522 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()
@@ -49,13 +50,15 @@ struct zfsacl_config_data {
 static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
 				      TALLOC_CTX *mem_ctx,
 				      const struct smb_filename *smb_fname,
+				      const ace_t *acebuf,
+				      int naces,
 				      struct SMB4ACL_T **ppacl,
 				      struct zfsacl_config_data *config)
 {
-	int naces, i;
-	ace_t *acebuf;
+	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;
@@ -76,42 +79,28 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
 	}
 	is_dir = S_ISDIR(psbuf->st_ex_mode);
 
-	/* read the number of file aces */
-	if((naces = acl(smb_fname->base_name, ACE_GETACLCNT, 0, NULL)) == -1) {
-		if(errno == ENOSYS) {
-			DEBUG(9, ("acl(ACE_GETACLCNT, %s): Operation is not "
-				  "supported on the filesystem where the file "
-				  "reside\n", smb_fname->base_name));
-		} else {
-			DEBUG(9, ("acl(ACE_GETACLCNT, %s): %s ", smb_fname->base_name,
-					strerror(errno)));
-		}
-		return map_nt_error_from_unix(errno);
-	}
-	/* allocate the field of ZFS aces */
 	mem_ctx = talloc_tos();
-	acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*naces);
-	if(acebuf == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-	/* read the aces into the field */
-	if(acl(smb_fname->base_name, ACE_GETACL, naces, acebuf) < 0) {
-		DEBUG(9, ("acl(ACE_GETACL, %s): %s ", smb_fname->base_name,
-				strerror(errno)));
-		return map_nt_error_from_unix(errno);
-	}
+
 	/* create SMB4ACL data */
 	if((pacl = smb_create_smb4acl(mem_ctx)) == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
 	for(i=0; i<naces; i++) {
 		SMB_ACE4PROP_T aceprop;
+		uint16_t special = 0;
 
 		aceprop.aceType  = (uint32_t) acebuf[i].a_type;
 		aceprop.aceFlags = (uint32_t) acebuf[i].a_flags;
 		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
@@ -121,7 +110,12 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
 			aceprop.aceMask |= SMB_ACE4_SYNCHRONIZE;
 		}
 
-		if (is_dir && (aceprop.aceMask & SMB_ACE4_ADD_FILE)) {
+		special = acebuf[i].a_flags & (ACE_OWNER|ACE_GROUP|ACE_EVERYONE);
+
+		if (is_dir &&
+		    (aceprop.aceMask & SMB_ACE4_ADD_FILE) &&
+		    (special != 0))
+		{
 			aceprop.aceMask |= SMB_ACE4_DELETE_CHILD;
 		}
 
@@ -130,20 +124,25 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
 			inherited_is_present = true;
 		}
 #endif
-		if(aceprop.aceFlags & ACE_OWNER) {
+		switch(special) {
+		case(ACE_OWNER):
 			aceprop.flags = SMB_ACE4_ID_SPECIAL;
 			aceprop.who.special_id = SMB_ACE4_WHO_OWNER;
-		} else if(aceprop.aceFlags & ACE_GROUP) {
+			break;
+		case(ACE_GROUP):
 			aceprop.flags = SMB_ACE4_ID_SPECIAL;
 			aceprop.who.special_id = SMB_ACE4_WHO_GROUP;
-		} else if(aceprop.aceFlags & ACE_EVERYONE) {
+			break;
+		case(ACE_EVERYONE):
 			aceprop.flags = SMB_ACE4_ID_SPECIAL;
 			aceprop.who.special_id = SMB_ACE4_WHO_EVERYONE;
-		} else {
+			break;
+		default:
 			aceprop.flags	= 0;
 		}
-		if(smb_add_ace4(pacl, &aceprop) == NULL)
+		if (smb_add_ace4(pacl, &aceprop) == NULL) {
 			return NT_STATUS_NO_MEMORY;
+		}
 	}
 
 #ifdef ACE_INHERITED_ACE
@@ -163,17 +162,22 @@ static NTSTATUS zfs_get_nt_acl_common(struct connection_struct *conn,
 static bool zfs_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
 			       struct SMB4ACL_T *smbacl)
 {
-	int naces = smb_get_naces(smbacl), i;
+	int naces = smb_get_naces(smbacl), i, rv;
 	ace_t *acebuf;
 	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);
@@ -213,6 +217,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;
@@ -222,7 +233,13 @@ static bool zfs_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
 	SMB_ASSERT(i == naces);
 
 	/* store acl */
-	if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
+	if (fsp->fh->fd != -1) {
+		rv = facl(fsp->fh->fd, ACE_SETACL, naces, acebuf);
+	}
+	else {
+		rv = acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf);
+	}
+	if (rv != 0) {
 		if(errno == ENOSYS) {
 			DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
 				  "supported on the filesystem where the file "
@@ -231,7 +248,7 @@ static bool zfs_process_smbacl(vfs_handle_struct *handle, files_struct *fsp,
 			DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp),
 				  strerror(errno)));
 		}
-		return 0;
+		return false;
 	}
 
 	return True;
@@ -259,6 +276,81 @@ static NTSTATUS zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
 				zfs_process_smbacl);
 }
 
+static int get_zfsacl(TALLOC_CTX *mem_ctx,
+		      const struct smb_filename *smb_fname,
+		      ace_t **outbuf)
+{
+	int naces, rv;
+	ace_t *acebuf = NULL;
+
+	naces = acl(smb_fname->base_name, ACE_GETACLCNT, 0, NULL);
+	if (naces == -1) {
+		int dbg_level = 10;
+
+		if (errno == ENOSYS) {
+			dbg_level = 1;
+		}
+		DEBUG(dbg_level, ("acl(ACE_GETACLCNT, %s): %s ",
+				  smb_fname->base_name, strerror(errno)));
+		return naces;
+	}
+	acebuf = talloc_size(mem_ctx, sizeof(ace_t)*naces);
+	if (acebuf == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	rv = acl(smb_fname->base_name, ACE_GETACL, naces, acebuf);
+	if (rv == -1) {
+		DBG_DEBUG("acl(ACE_GETACL, %s) failed: %s ",
+			  smb_fname->base_name, strerror(errno));
+		return -1;
+	}
+
+	*outbuf = acebuf;
+	return naces;
+}
+
+static int fget_zfsacl(TALLOC_CTX *mem_ctx,
+		       struct files_struct *fsp,
+		       ace_t **outbuf)
+{
+	int naces, rv;
+	ace_t *acebuf = NULL;
+
+	if (fsp->fh->fd == -1) {
+		return get_zfsacl(mem_ctx, fsp->fsp_name, outbuf);
+	}
+
+	naces = facl(fsp->fh->fd, ACE_GETACLCNT, 0, NULL);
+	if (naces == -1) {
+		int dbg_level = 10;
+
+		if (errno == ENOSYS) {
+			dbg_level = 1;
+		}
+		DEBUG(dbg_level, ("facl(ACE_GETACLCNT, %s): %s ",
+				  fsp_str_dbg(fsp), strerror(errno)));
+		return naces;
+	}
+
+	acebuf = talloc_size(mem_ctx, sizeof(ace_t)*naces);
+	if (acebuf == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	rv = facl(fsp->fh->fd, ACE_GETACL, naces, acebuf);
+	if (rv == -1) {
+		DBG_DEBUG("acl(ACE_GETACL, %s): %s ",
+			  fsp_str_dbg(fsp), strerror(errno));
+		return -1;
+	}
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list