[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon May 10 20:17:01 UTC 2021


The branch, master has been updated
       via  21934c09bdc s3:smbd - support streams larger than 64 KiB
      from  ac78b921daf bootstrap: Add Fedora 34 CI runner

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 21934c09bdcad04633f0e77ad8136b8f2c21b9e5
Author: Andrew Walker <awalker at ixsystems.com>
Date:   Fri May 7 06:37:25 2021 -0400

    s3:smbd - support streams larger than 64 KiB
    
    Add support for streams that are larger than 64 KiB in size. Upper
    and lower bound are controlled by the parameters smbd max_xattr_size.
    Testing against ReFS on Windows (where ADS size is limited in size
    shows the server responding with STATUS_FILESYSTEM_LIMITATION.
    Do the same in samba for this case.
    
    Currently, large xattrs are supported in FreeBSD.
    
    Signed-off-by: Andrew Walker <awalker at ixsystems.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Mon May 10 20:16:21 UTC 2021 on sn-devel-184

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

Summary of changes:
 docs-xml/smbdotconf/misc/smbdmaxxattrsize.xml | 28 +++++++++++++++++++++++++++
 lib/param/loadparm.c                          |  4 ++++
 source3/modules/vfs_streams_xattr.c           | 21 ++++++++++++++++++++
 source3/param/loadparm.c                      |  1 +
 source3/smbd/smb2_write.c                     |  7 ++++++-
 source3/smbd/trans2.c                         | 16 +++++++++++++--
 6 files changed, 74 insertions(+), 3 deletions(-)
 create mode 100644 docs-xml/smbdotconf/misc/smbdmaxxattrsize.xml


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/misc/smbdmaxxattrsize.xml b/docs-xml/smbdotconf/misc/smbdmaxxattrsize.xml
new file mode 100644
index 00000000000..3ae91a37890
--- /dev/null
+++ b/docs-xml/smbdotconf/misc/smbdmaxxattrsize.xml
@@ -0,0 +1,28 @@
+<samba:parameter name="smbd max xattr size"
+                 context="S"
+                 type="integer"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+	<para>
+	  This parameter controls the maximum size of extended attributes
+	  that may be written to the server as EAs or as alternate data
+	  streams if vfs_streams_xattr is enabled. The maximum size of
+	  extended attributes depends on the Samba server's operating system
+	  and the underlying filesystem. The Linux VFS currently sets an
+	  upper boundary of 64 KiB per extended attribute. FreeBSD does not
+	  set a practical upper limit, but since pread() and pwrite() are not
+	  possible via the extattr on FreeBSD, it is not recommended to
+	  increase this value above a few MiB.
+
+	  If a client attempts to write an overly-large alternate datastream,
+	  the Samba server will return STATUS_FILESYSTEM_LIMITATION.
+	  If this error is encountered, users may try increasing the maximum
+	  size supported for xattr writes. If this is not possible, and
+	  writes are from a MacOS client and to an AFP_Resource extended
+	  attribute, the user may enable the vfs_fruit module and configure
+	  to allow stream writes for AFP_Resource to an alternative storage
+	  location. See vfs_fruit documentation for further details.
+	</para>
+</description>
+<value type="default">65536</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index adfba67652e..b674858e706 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2956,6 +2956,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 				  "client protection",
 				  "default");
 
+	lpcfg_do_global_parameter(lp_ctx,
+				  "smbd max xattr size",
+				  "65536");
+
 	for (i = 0; parm_table[i].label; i++) {
 		if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
 			lp_ctx->flags[i] |= FLAG_DEFAULT;
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index cbe82ad6f33..78a2baf40d5 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -957,6 +957,27 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
 		return -1;
 	}
 
+	if ((offset + n) >= lp_smbd_max_xattr_size(SNUM(handle->conn))) {
+		/*
+		 * Requested write is beyond what can be read based on
+		 * samba configuration.
+		 * ReFS returns STATUS_FILESYSTEM_LIMITATION, which causes
+		 * entire file to be skipped by File Explorer. VFAT returns
+		 * NT_STATUS_OBJECT_NAME_COLLISION causes user to be prompted
+		 * to skip writing metadata, but copy data.
+		 */
+		DBG_ERR("Write to xattr [%s] on file [%s] exceeds maximum "
+			"supported extended attribute size. "
+			"Depending on filesystem type and operating system "
+			"(OS) specifics, this value may be increased using "
+			"the value of the parameter: "
+			"smbd max xattr size = <bytes>. Consult OS and "
+			"filesystem manpages prior to increasing this limit.\n",
+			sio->xattr_name, sio->base);
+		errno = EOVERFLOW;
+		return -1;
+	}
+
 	/* Create an smb_filename with stream_name == NULL. */
 	smb_fname_base = synthetic_smb_fname(talloc_tos(),
 					sio->base,
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 55184e9b798..85e578eda9e 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -197,6 +197,7 @@ static const struct loadparm_service _sDefault =
 	.map_hidden = false,
 	.map_archive = true,
 	.store_dos_attributes = true,
+	.smbd_max_xattr_size = 65536,
 	.dmapi_support = false,
 	.locking = true,
 	.strict_locking = Auto,
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index e49e623d796..612c89d59d1 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -193,7 +193,12 @@ static NTSTATUS smb2_write_complete_internal(struct tevent_req *req,
 	files_struct *fsp = state->fsp;
 
 	if (nwritten == -1) {
-		status = map_nt_error_from_unix(err);
+		if (err == EOVERFLOW &&
+		    is_ntfs_stream_smb_fname(fsp->fsp_name)) {
+			status = NT_STATUS_FILE_SYSTEM_LIMITATION;
+		} else {
+			status = map_nt_error_from_unix(err);
+		}
 
 		DEBUG(2, ("smb2_write failed: %s, file %s, "
 			  "length=%lu offset=%lu nwritten=-1: %s\n",
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index de843117581..9aa2495792e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -249,6 +249,7 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
 	size_t attr_size = 256;
 	char *val = NULL;
 	ssize_t sizeret;
+	size_t max_xattr_size = lp_smbd_max_xattr_size(SNUM(conn));
 
  again:
 
@@ -264,8 +265,8 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx,
 				ea_name, val, attr_size);
 	}
 
-	if (sizeret == -1 && errno == ERANGE && attr_size != 65536) {
-		attr_size = 65536;
+	if (sizeret == -1 && errno == ERANGE && attr_size < max_xattr_size) {
+		attr_size = max_xattr_size;
 		goto again;
 	}
 
@@ -501,6 +502,17 @@ static NTSTATUS get_ea_list_from_fsp(TALLOC_CTX *mem_ctx,
 			 */
 			TALLOC_FREE(listp);
 			continue;
+		} else if (listp->ea.value.length > 65536) {
+			/*
+			 * SMB clients may report error with file
+			 * if large EA is presented to them.
+			 */
+			DBG_ERR("EA [%s] on file [%s] exceeds "
+				"maximum permitted EA size of 64KiB: %zu\n.",
+				listp->ea.name, fsp_str_dbg(fsp),
+				listp->ea.value.length);
+			TALLOC_FREE(listp);
+			continue;
 		}
 
 		push_ascii_fstring(dos_ea_name, listp->ea.name);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list