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

Karolin Seeger kseeger at samba.org
Mon Jul 19 07:10:01 UTC 2021


The branch, v4-13-test has been updated
       via  97c6d6fee8a smbd: return correct timestamps for quota fake file
       via  a3dea8a0d08 smbd: handle fake file handles in dos_mode()
       via  7ecf1650661 smbtorture: verify attributes on fake quota file handle
       via  5b58f663724 libcli/smb: allow unexpected padding in SMB2 READ responses
       via  f47e9965c77 libcli/smb: make smb2cli_ioctl_parse_buffer() available as smb2cli_parse_dyn_buffer()
       via  d4d9bc847c5 s3:smbd: implement FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
       via  5d98e2f2960 s3:smbd: introduce a body_size variable in smbd_smb2_request_read_done
       via  e38295a091e s4:torture/smb2: add smb2.read.bug14607 test
      from  6fa28f4eb3a VERSION: Bump version up to Samba 4.13.11...

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


- Log -----------------------------------------------------------------
commit 97c6d6fee8a133c2f647f9c588f863ab9c4e15c9
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jun 7 19:02:56 2021 +0200

    smbd: return correct timestamps for quota fake file
    
    Prior to 572d4e3a56eef00e29f93482daa21647af7310d0 it was sufficient to
    initialize struct timespec to zero to return NTTIME 0 (ie not set) over
    SMB.
    
    This fixes the same problem from bug 14714 where the timestamps in an SMB2 CLOSE
    response.
    
    Windows of course does return *some* timestamps, but as it's neither documented
    nor was I able to figure out where they would be coming from, as well as the
    Windows client apparently doesn't care, I didn't bother with implementing some
    sophisticated heuristic to return some timestamps.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14731
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Jun  9 20:38:02 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 52a421111218d94d2e5cb131648bcdf5411d910b)
    
    Autobuild-User(v4-13-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-13-test): Mon Jul 19 07:09:29 UTC 2021 on sn-devel-184

commit a3dea8a0d088c7624c1a81a81873c96c068bcdbd
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Jun 4 16:58:20 2021 +0200

    smbd: handle fake file handles in dos_mode()
    
    This ensures SMB requests on the quote fake file "$Extend/$Quota" don't hit the
    VFS, where specifically in vfs_gpfs we log an error message if we fail to read
    the DOS attributes for a file with
    
      vfs_gpfs_get_dos_attributes: Getting winattrs failed for $Extend/$Quota
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14731
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 7ecf16506616c7f3071c8c2206cfda17b7743351
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jun 7 19:03:05 2021 +0200

    smbtorture: verify attributes on fake quota file handle
    
    The expected DOS attributes are taken from a Windows 2016 server. The expected
    timestamps are what Samba has returned before commit 572d4e3a56eef00e29f9348:
    NTTIME(0), ie no value.
    
    The upcoming fix will restore this behaviour. Windows of course does
    return *some* timestamps, but as it's neither documented nor was I able to
    figure out where they would be coming from, as well as the Windows client apparently
    doesn't care, I didn't bother with implementing some sophisticated heuristic to
    return some timestamps.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14731
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 1e338d51602a7dca6108e5e8704f5cdde4740713)

commit 5b58f6637241dfee4249d89fab3220fef59c9cfb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 29 15:42:56 2021 +0200

    libcli/smb: allow unexpected padding in SMB2 READ responses
    
    Make use of smb2cli_parse_dyn_buffer() in smb2cli_read_done()
    as it was exactly introduced for a similar problem see:
    
        commit 4c6c71e1378401d66bf2ed230544a75f7b04376f
        Author:     Stefan Metzmacher <metze at samba.org>
        AuthorDate: Thu Jan 14 17:32:15 2021 +0100
        Commit:     Volker Lendecke <vl at samba.org>
        CommitDate: Fri Jan 15 08:36:34 2021 +0000
    
            libcli/smb: allow unexpected padding in SMB2 IOCTL responses
    
            A NetApp Ontap 7.3.7 SMB server add 8 padding bytes to an
            offset that's already 8 byte aligned.
    
            RN: Work around special SMB2 IOCTL response behavior of NetApp Ontap 7.3.7
            BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
            Pair-Programmed-With: Volker Lendecke <vl at samba.org>
    
            Signed-off-by: Stefan Metzmacher <metze at samba.org>
            Signed-off-by: Volker Lendecke <vl at samba.org>
    
            Autobuild-User(master): Volker Lendecke <vl at samba.org>
            Autobuild-Date(master): Fri Jan 15 08:36:34 UTC 2021 on sn-devel-184
    
    RN: Work around special SMB2 READ response behavior of NetApp Ontap 7.3.7
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Jul 15 23:53:55 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 155348cda65b441a6c4db1ed84dbf1682d02973c)

commit f47e9965c77ad4f1936dde71b79dec5e12add12a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jun 29 15:24:13 2021 +0200

    libcli/smb: make smb2cli_ioctl_parse_buffer() available as smb2cli_parse_dyn_buffer()
    
    It will be used in smb2cli_read.c soon...
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 1faf15b3d0f41fa8a94b76d1616a4460ce0c6fa4)

commit d4d9bc847c5a12075a7e7b7c1eb23a637f8670b8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 5 17:49:00 2021 +0200

    s3:smbd: implement FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
    
    This turns the 'smb2.read.bug14607' test from 'skip' into 'xfailure',
    as the 2nd smb2cli_read() function will now return
    NT_STATUS_INVALID_NETWORK_RESPONSE.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit ef57fba5dbf359b204ba952451e1e33ed68f1c91)

commit 5d98e2f29608cf9c6c810f07ca136f375b4dba8e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jul 5 17:49:00 2021 +0200

    s3:smbd: introduce a body_size variable in smbd_smb2_request_read_done
    
    This will simplify the following changes.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 5ecac656fde4e81aa6e51e7b3134ea3fb75f564a)

commit e38295a091ee3e57b6ae68ab36442de04714350d
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 6 16:24:59 2021 +0200

    s4:torture/smb2: add smb2.read.bug14607 test
    
    This test will use a FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
    in order to change the server behavior of READ responses regarding
    the data offset.
    
    It will demonstrate the problem in smb2cli_read*() triggered
    by NetApp Ontap servers.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit b3c9823d907b91632679e6f0ffce1b7192e4b9b6)

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

Summary of changes:
 libcli/smb/smb2cli_ioctl.c    | 123 +++++---------------------------------
 libcli/smb/smb2cli_read.c     |  22 +++++--
 libcli/smb/smbXcli_base.c     |  91 ++++++++++++++++++++++++++++
 libcli/smb/smbXcli_base.h     |   9 +++
 libcli/smb/smb_constants.h    |   2 +
 selftest/knownfail            |   1 +
 source3/smbd/dosmode.c        |  20 +++++++
 source3/smbd/filename.c       |   5 ++
 source3/smbd/globals.h        |   4 ++
 source3/smbd/smb2_ioctl.c     |  10 ++++
 source3/smbd/smb2_read.c      |  14 ++++-
 source4/torture/smb2/create.c |  63 +++++++++++++++++++
 source4/torture/smb2/read.c   | 136 ++++++++++++++++++++++++++++++++++++++++++
 13 files changed, 387 insertions(+), 113 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c
index f9abcc57bab..d638b281678 100644
--- a/libcli/smb/smb2cli_ioctl.c
+++ b/libcli/smb/smb2cli_ioctl.c
@@ -160,97 +160,6 @@ struct tevent_req *smb2cli_ioctl_send(TALLOC_CTX *mem_ctx,
 	return req;
 }
 
-static NTSTATUS smb2cli_ioctl_parse_buffer(uint32_t dyn_offset,
-					   const DATA_BLOB dyn_buffer,
-					   uint32_t min_offset,
-					   uint32_t buffer_offset,
-					   uint32_t buffer_length,
-					   uint32_t max_length,
-					   uint32_t *next_offset,
-					   DATA_BLOB *buffer)
-{
-	uint32_t offset;
-	bool oob;
-
-	*buffer = data_blob_null;
-	*next_offset = dyn_offset;
-
-	if (buffer_offset == 0) {
-		/*
-		 * If the offset is 0, we better ignore
-		 * the buffer_length field.
-		 */
-		return NT_STATUS_OK;
-	}
-
-	if (buffer_length == 0) {
-		/*
-		 * If the length is 0, we better ignore
-		 * the buffer_offset field.
-		 */
-		return NT_STATUS_OK;
-	}
-
-	if ((buffer_offset % 8) != 0) {
-		/*
-		 * The offset needs to be 8 byte aligned.
-		 */
-		return NT_STATUS_INVALID_NETWORK_RESPONSE;
-	}
-
-	/*
-	 * We used to enforce buffer_offset to be
-	 * an exact match of the expected minimum,
-	 * but the NetApp Ontap 7.3.7 SMB server
-	 * gets the padding wrong and aligns the
-	 * input_buffer_offset by a value of 8.
-	 *
-	 * So we just enforce that the offset is
-	 * not lower than the expected value.
-	 */
-	SMB_ASSERT(min_offset >= dyn_offset);
-	if (buffer_offset < min_offset) {
-		return NT_STATUS_INVALID_NETWORK_RESPONSE;
-	}
-
-	/*
-	 * Make [input|output]_buffer_offset relative to "dyn_buffer"
-	 */
-	offset = buffer_offset - dyn_offset;
-	oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
-	if (oob) {
-		return NT_STATUS_INVALID_NETWORK_RESPONSE;
-	}
-
-	/*
-	 * Give the caller a hint what we consumed,
-	 * the caller may need to add possible padding.
-	 */
-	*next_offset = buffer_offset + buffer_length;
-
-	if (max_length == 0) {
-		/*
-		 * If max_input_length is 0 we ignore the
-		 * input_buffer_length, because Windows 2008 echos the
-		 * DCERPC request from the requested input_buffer to
-		 * the response input_buffer.
-		 *
-		 * We just use the same logic also for max_output_length...
-		 */
-		buffer_length = 0;
-	}
-
-	if (buffer_length > max_length) {
-		return NT_STATUS_INVALID_NETWORK_RESPONSE;
-	}
-
-	*buffer = (DATA_BLOB) {
-		.data = dyn_buffer.data + offset,
-		.length = buffer_length,
-	};
-	return NT_STATUS_OK;
-}
-
 static void smb2cli_ioctl_done(struct tevent_req *subreq)
 {
 	struct tevent_req *req =
@@ -352,14 +261,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 
 	input_min_offset = dyn_ofs;
 	input_next_offset = dyn_ofs;
-	error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-					   dyn_buffer,
-					   input_min_offset,
-					   input_buffer_offset,
-					   input_buffer_length,
-					   state->max_input_length,
-					   &input_next_offset,
-					   &state->out_input_buffer);
+	error = smb2cli_parse_dyn_buffer(dyn_ofs,
+					 dyn_buffer,
+					 input_min_offset,
+					 input_buffer_offset,
+					 input_buffer_length,
+					 state->max_input_length,
+					 &input_next_offset,
+					 &state->out_input_buffer);
 	if (tevent_req_nterror(req, error)) {
 		return;
 	}
@@ -370,14 +279,14 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 	 */
 	output_min_offset = NDR_ROUND(input_next_offset, 8);
 	output_next_offset = 0; /* this variable is completely ignored */
-	error = smb2cli_ioctl_parse_buffer(dyn_ofs,
-					   dyn_buffer,
-					   output_min_offset,
-					   output_buffer_offset,
-					   output_buffer_length,
-					   state->max_output_length,
-					   &output_next_offset,
-					   &state->out_output_buffer);
+	error = smb2cli_parse_dyn_buffer(dyn_ofs,
+					 dyn_buffer,
+					 output_min_offset,
+					 output_buffer_offset,
+					 output_buffer_length,
+					 state->max_output_length,
+					 &output_next_offset,
+					 &state->out_output_buffer);
 	if (tevent_req_nterror(req, error)) {
 		return;
 	}
diff --git a/libcli/smb/smb2cli_read.c b/libcli/smb/smb2cli_read.c
index 8110b65d432..c7f48741b87 100644
--- a/libcli/smb/smb2cli_read.c
+++ b/libcli/smb/smb2cli_read.c
@@ -90,8 +90,13 @@ static void smb2cli_read_done(struct tevent_req *subreq)
 		tevent_req_data(req,
 		struct smb2cli_read_state);
 	NTSTATUS status;
+	NTSTATUS error;
 	struct iovec *iov;
+	const uint8_t dyn_ofs = SMB2_HDR_BODY + 0x10;
+	DATA_BLOB dyn_buffer = data_blob_null;
 	uint8_t data_offset;
+	DATA_BLOB data_buffer = data_blob_null;
+	uint32_t next_offset = 0; /* this variable is completely ignored */
 	static const struct smb2cli_req_expected_response expected[] = {
 	{
 		.status = STATUS_BUFFER_OVERFLOW,
@@ -117,14 +122,23 @@ static void smb2cli_read_done(struct tevent_req *subreq)
 	data_offset = CVAL(iov[1].iov_base, 2);
 	state->data_length = IVAL(iov[1].iov_base, 4);
 
-	if ((data_offset != SMB2_HDR_BODY + 16) ||
-	    (state->data_length > iov[2].iov_len)) {
-		tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+	dyn_buffer = data_blob_const((uint8_t *)iov[2].iov_base,
+				     iov[2].iov_len);
+
+	error = smb2cli_parse_dyn_buffer(dyn_ofs,
+					 dyn_buffer,
+					 dyn_ofs, /* min_offset */
+					 data_offset,
+					 state->data_length,
+					 dyn_buffer.length, /* max_length */
+					 &next_offset,
+					 &data_buffer);
+	if (tevent_req_nterror(req, error)) {
 		return;
 	}
 
 	state->recv_iov = iov;
-	state->data = (uint8_t *)iov[2].iov_base;
+	state->data = data_buffer.data;
 
 	state->out_valid = true;
 
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 4909797543c..bcb601dde59 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -6664,3 +6664,94 @@ uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
 {
 	return conn->smb2.mid;
 }
+
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+				  const DATA_BLOB dyn_buffer,
+				  uint32_t min_offset,
+				  uint32_t buffer_offset,
+				  uint32_t buffer_length,
+				  uint32_t max_length,
+				  uint32_t *next_offset,
+				  DATA_BLOB *buffer)
+{
+	uint32_t offset;
+	bool oob;
+
+	*buffer = data_blob_null;
+	*next_offset = dyn_offset;
+
+	if (buffer_offset == 0) {
+		/*
+		 * If the offset is 0, we better ignore
+		 * the buffer_length field.
+		 */
+		return NT_STATUS_OK;
+	}
+
+	if (buffer_length == 0) {
+		/*
+		 * If the length is 0, we better ignore
+		 * the buffer_offset field.
+		 */
+		return NT_STATUS_OK;
+	}
+
+	if ((buffer_offset % 8) != 0) {
+		/*
+		 * The offset needs to be 8 byte aligned.
+		 */
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
+	/*
+	 * We used to enforce buffer_offset to be
+	 * an exact match of the expected minimum,
+	 * but the NetApp Ontap 7.3.7 SMB server
+	 * gets the padding wrong and aligns the
+	 * input_buffer_offset by a value of 8.
+	 *
+	 * So we just enforce that the offset is
+	 * not lower than the expected value.
+	 */
+	SMB_ASSERT(min_offset >= dyn_offset);
+	if (buffer_offset < min_offset) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
+	/*
+	 * Make [input|output]_buffer_offset relative to "dyn_buffer"
+	 */
+	offset = buffer_offset - dyn_offset;
+	oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
+	if (oob) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
+	/*
+	 * Give the caller a hint what we consumed,
+	 * the caller may need to add possible padding.
+	 */
+	*next_offset = buffer_offset + buffer_length;
+
+	if (max_length == 0) {
+		/*
+		 * If max_input_length is 0 we ignore the
+		 * input_buffer_length, because Windows 2008 echos the
+		 * DCERPC request from the requested input_buffer to
+		 * the response input_buffer.
+		 *
+		 * We just use the same logic also for max_output_length...
+		 */
+		buffer_length = 0;
+	}
+
+	if (buffer_length > max_length) {
+		return NT_STATUS_INVALID_NETWORK_RESPONSE;
+	}
+
+	*buffer = (DATA_BLOB) {
+		.data = dyn_buffer.data + offset,
+		.length = buffer_length,
+	};
+	return NT_STATUS_OK;
+}
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 2afc7165cd9..4452cd808ea 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -390,6 +390,15 @@ void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
 void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid);
 uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn);
 
+NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
+				  const DATA_BLOB dyn_buffer,
+				  uint32_t min_offset,
+				  uint32_t buffer_offset,
+				  uint32_t buffer_length,
+				  uint32_t max_length,
+				  uint32_t *next_offset,
+				  DATA_BLOB *buffer);
+
 struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
 				      struct smbXcli_conn *conn,
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index d2345f094e1..af8e7204013 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -591,6 +591,8 @@ enum csc_policy {
 	(FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0000 | FSCTL_METHOD_NEITHER)
 #define FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 \
 	(FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0010 | FSCTL_METHOD_NEITHER)
+#define FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8 \
+	(FSCTL_SMBTORTURE | FSCTL_ACCESS_WRITE | 0x0020 | FSCTL_METHOD_NEITHER)
 
 /*
  * A few values from [MS-FSCC] 2.1.2.1 Reparse Tags
diff --git a/selftest/knownfail b/selftest/knownfail
index 4fe503f4cc1..dab0e64c10b 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -144,6 +144,7 @@
 ^samba4.raw.acls.*.create_owner_file
 ^samba4.smb2.create.*.acldir
 ^samba4.smb2.create.*.impersonation
+^samba4.smb2.create.quota-fake-file\(ad_dc_ntvfs\) # not supported by the NTVFS
 ^samba4.smb2.acls.*.generic
 ^samba4.smb2.acls.*.inheritflags
 ^samba4.smb2.acls.*.owner
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 4012d6e64c9..a6b8f170192 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -27,6 +27,7 @@
 #include "smbd/smbd.h"
 #include "lib/param/loadparm.h"
 #include "lib/util/tevent_ntstatus.h"
+#include "fake_file.h"
 
 static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
 				const struct smb_filename *smb_fname,
@@ -754,6 +755,7 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 {
 	uint32_t result = 0;
 	NTSTATUS status = NT_STATUS_OK;
+	enum FAKE_FILE_TYPE fake_file_type;
 
 	DEBUG(8,("dos_mode: %s\n", smb_fname_str_dbg(smb_fname)));
 
@@ -761,6 +763,24 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
 		return 0;
 	}
 
+	fake_file_type = is_fake_file(smb_fname);
+
+	switch (fake_file_type) {
+	case FAKE_FILE_TYPE_NAMED_PIPE_PROXY:
+	case FAKE_FILE_TYPE_NAMED_PIPE:
+		return FILE_ATTRIBUTE_NORMAL;
+
+	case FAKE_FILE_TYPE_QUOTA:
+		/* From Windows 2016 */
+		return FILE_ATTRIBUTE_HIDDEN
+			| FILE_ATTRIBUTE_SYSTEM
+			| FILE_ATTRIBUTE_DIRECTORY
+			| FILE_ATTRIBUTE_ARCHIVE;
+
+	case FAKE_FILE_TYPE_NONE:
+		break;
+	}
+
 	/* Get the DOS attributes via the VFS if we can */
 	status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 73ea63ffd25..db23fe40587 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1958,6 +1958,11 @@ static NTSTATUS filename_convert_internal(TALLOC_CTX *ctx,
 			return NT_STATUS_NO_MEMORY;
 		}
 		smb_fname->st = (SMB_STRUCT_STAT) { .st_ex_nlink = 1 };
+		smb_fname->st.st_ex_btime = (struct timespec){0, SAMBA_UTIME_OMIT};
+		smb_fname->st.st_ex_atime = (struct timespec){0, SAMBA_UTIME_OMIT};
+		smb_fname->st.st_ex_mtime = (struct timespec){0, SAMBA_UTIME_OMIT};
+		smb_fname->st.st_ex_ctime = (struct timespec){0, SAMBA_UTIME_OMIT};
+
 		*_smb_fname = smb_fname;
 		return NT_STATUS_OK;
 	}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index fcf33a699c6..ae935f413e0 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -534,6 +534,10 @@ struct smbXsrv_connection {
 		struct smbXsrv_preauth preauth;
 
 		struct smbd_smb2_request *requests;
+
+		struct {
+			uint8_t read_body_padding;
+		} smbtorture;
 	} smb2;
 };
 
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 8b65a691638..d29ff5d0303 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -197,6 +197,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
 	case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
 	case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
 	case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
+	case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8:
 		/*
 		 * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
 		 * FSCTL_PIPE_WAIT does not take a file handle.
@@ -424,6 +425,15 @@ static struct tevent_req *smb2_ioctl_smbtorture(uint32_t ctl_code,
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
 
+	case FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8:
+		if (state->in_input.length != 0) {
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return tevent_req_post(req, ev);
+		}
+
+		state->smb2req->xconn->smb2.smbtorture.read_body_padding = 8;
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
 	default:
 		goto not_supported;
 	}
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index cd590a52c95..a846215b0ec 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -116,6 +116,8 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq)
 {
 	struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
 					struct smbd_smb2_request);
+	uint16_t body_size;
+	uint8_t body_padding = req->xconn->smb2.smbtorture.read_body_padding;
 	DATA_BLOB outbody;
 	DATA_BLOB outdyn;
 	uint8_t out_data_offset;
@@ -139,9 +141,14 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq)
 		return;
 	}
 
-	out_data_offset = SMB2_HDR_BODY + 0x10;
+	/*
+	 * Only FSCTL_SMBTORTURE_GLOBAL_READ_RESPONSE_BODY_PADDING8
+	 * sets body_padding to a value different from 0.
+	 */
+	body_size = 0x10 + body_padding;
+	out_data_offset = SMB2_HDR_BODY + body_size;
 
-	outbody = smbd_smb2_generate_outbody(req, 0x10);
+	outbody = smbd_smb2_generate_outbody(req, body_size);
 	if (outbody.data == NULL) {
 		error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
 		if (!NT_STATUS_IS_OK(error)) {
@@ -161,6 +168,9 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq)
 	SIVAL(outbody.data, 0x08,
 	      out_data_remaining);		/* data remaining */
 	SIVAL(outbody.data, 0x0C, 0);		/* reserved */
+	if (body_padding != 0) {
+		memset(outbody.data + 0x10, 0, body_padding);
+	}
 
 	outdyn = out_data_buffer;
 
diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c
index c97dfef16d3..5c559bf2d1d 100644
--- a/source4/torture/smb2/create.c
+++ b/source4/torture/smb2/create.c
@@ -2707,6 +2707,68 @@ done:
 	return ret;
 }
 
+/*
+  test opening quota fakefile handle and returned attributes
+*/
+static bool test_smb2_open_quota_fake_file(struct torture_context *tctx,
+					   struct smb2_tree *tree)
+{
+	const char *fname = "$Extend\\$Quota:$Q:$INDEX_ALLOCATION";
+	struct smb2_create create;
+	struct smb2_handle h = {{0}};
+	NTSTATUS status;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list