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

Karolin Seeger kseeger at samba.org
Wed Jan 20 10:28:01 UTC 2021


The branch, v4-13-test has been updated
       via  4e48d658f8d s3: smbd: Add call to conn_setup_case_options() to create_conn_struct_as_root().
       via  d13354f08f5 s3: smbd: Factor out setting up case parameters for a share to a function - conn_setup_case_options().
       via  a6ec2580b4d build: remove smbd_conn private library
       via  810b019db9e libcli/smb: allow unexpected padding in SMB2 IOCTL responses
       via  efb811f6e43 smbd: implement FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 as reproducer for bug 14607
       via  6ae3c220a93 s4:torture/smb2: add samba3.smb2.ioctl.bug14607
       via  26e762a42e2 libcli/smb: split out smb2cli_ioctl_parse_buffer()
       via  5e64e53fe2f libcli/smb: Allow smb2cli_validate_negotiate_info_done() to ignore NT_STATUS_INVALID_PARAMETER.
       via  bb951cd05c2 libcli/smb: Change some checks to SMB_ASSERTS
      from  fdeba394444 vfs_fruit: fix close for fake_fd

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


- Log -----------------------------------------------------------------
commit 4e48d658f8d750c350ebbf33314323a9a9ee1ebc
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jan 12 11:44:44 2021 -0800

    s3: smbd: Add call to conn_setup_case_options() to create_conn_struct_as_root().
    
    Ensures temporary DFS share doesn't leave the case parameters set
    as zero (i.e.:
    
    conn->case sensitive = 0
    conn->share_case_preserve = 0
    and default case is lower
    
    which can cause problems doing a DFS_GET_REFERRALS request).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14612
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>
    
    Autobuild-User(master): Anoop C S <anoopcs at samba.org>
    Autobuild-Date(master): Wed Jan 13 18:14:31 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 39ce73321093a0a5e25f574d0d32d7f88892de46)
    
    Autobuild-User(v4-13-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-13-test): Wed Jan 20 10:27:02 UTC 2021 on sn-devel-184

commit d13354f08f573251f32e532166b3e5808ebdc634
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Jan 12 11:39:51 2021 -0800

    s3: smbd: Factor out setting up case parameters for a share to a function - conn_setup_case_options().
    
    Will allow it to be reused in the msdfs temporary share code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14612
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Anoop C S <anoopcs at samba.org>
    (cherry picked from commit ab7700177c2badbf8ed649985be8029223b6e946)

commit a6ec2580b4dc41bf78cab5bac282f4cd618adcf2
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Sep 27 08:52:58 2020 +0200

    build: remove smbd_conn private library
    
    This is not needed anymore since 6822baa2920f30374ec84363497d97e24f359fab.
    
    Needed here for:
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14612
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 80ac7fa7c4c728bef4f947872c090fec35fb26f0)

commit 810b019db9ed9f5e1ea49db2b1c3e4e5fcae7f5c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 14 17:32:15 2021 +0100

    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
    
    (cherry picked from commit 4c6c71e1378401d66bf2ed230544a75f7b04376f)

commit efb811f6e4390f9f210decb2da9c59b1ca63cfee
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 14 17:39:01 2021 +0100

    smbd: implement FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 as reproducer for bug 14607
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    (cherry picked from commit 39c0d2b666a6ddac7cd3b29fe76be7375690b27b)

commit 6ae3c220a93c2128d6522d02004310ca30380a63
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 14 17:39:18 2021 +0100

    s4:torture/smb2: add samba3.smb2.ioctl.bug14607
    
    FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8 will be used
    to trigger an SMB2 IOCTL response with extra padding.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    (cherry picked from commit 3db566026bcc0bff87acae762211e1c49220dc82)

commit 26e762a42e2191009c7f42bfe7b1131e8af33409
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Jan 14 17:27:21 2021 +0100

    libcli/smb: split out smb2cli_ioctl_parse_buffer()
    
    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>
    (cherry picked from commit 508ed5b42c23f8b3d9730d838bd921cb73c61358)

commit 5e64e53fe2f8b7e8c734e89abdabc85cfa6d4e95
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Jan 6 09:03:05 2021 -0800

    libcli/smb: Allow smb2cli_validate_negotiate_info_done() to ignore NT_STATUS_INVALID_PARAMETER.
    
    This can be returned from NetApp Ontap 7.3.7 SMB server
    implementations. Now we have ensured smb2_signing_check_pdu()
    cannot return NT_STATUS_INVALID_PARAMETER on a signing error
    it's safe to check this error code here. Windows 10
    clients ignore this error from the NetApp.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit 0abb5ca6b96c843909dea56d5594e334547ae90f)

commit bb951cd05c247d24adeb1d929a2b63333771e8d6
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 11 10:01:39 2021 +0100

    libcli/smb: Change some checks to SMB_ASSERTS
    
    If we end up here, it's definitely a programming error in the basic
    parsing layer of the SMB2 packet.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    (cherry picked from commit fdcdfceefdd3186ef0b70bb6e83dddc8f4c073db)

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

Summary of changes:
 libcli/smb/smb2_signing.c         |   9 +-
 libcli/smb/smb2cli_ioctl.c        | 207 +++++++++++++++++++++++---------------
 libcli/smb/smbXcli_base.c         |  25 +++++
 libcli/smb/smb_constants.h        |   2 +
 source3/smbd/conn.c               |  19 ++++
 source3/smbd/msdfs.c              |   2 +
 source3/smbd/proto.h              |   1 +
 source3/smbd/service.c            |  11 +-
 source3/smbd/smb2_ioctl.c         |  41 +++++++-
 source3/smbd/smb2_ioctl_private.h |   1 +
 source3/wscript_build             |   7 +-
 source4/torture/smb2/ioctl.c      |  53 ++++++++++
 12 files changed, 272 insertions(+), 106 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index cc03607d789..230475480c2 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -189,13 +189,8 @@ NTSTATUS smb2_signing_check_pdu(struct smb2_signing_key *signing_key,
 	static const uint8_t zero_sig[16] = { 0, };
 	int i;
 
-	if (count < 2) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
-	if (vector[0].iov_len != SMB2_HDR_BODY) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
+	SMB_ASSERT(count >= 2);
+	SMB_ASSERT(vector[0].iov_len == SMB2_HDR_BODY);
 
 	hdr = (const uint8_t *)vector[0].iov_base;
 
diff --git a/libcli/smb/smb2cli_ioctl.c b/libcli/smb/smb2cli_ioctl.c
index 2b572baeb23..f9abcc57bab 100644
--- a/libcli/smb/smb2cli_ioctl.c
+++ b/libcli/smb/smb2cli_ioctl.c
@@ -160,6 +160,97 @@ 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 =
@@ -169,15 +260,19 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 		tevent_req_data(req,
 		struct smb2cli_ioctl_state);
 	NTSTATUS status;
+	NTSTATUS error;
 	struct iovec *iov;
 	uint8_t *fixed;
-	uint8_t *dyn;
-	size_t dyn_len;
+	DATA_BLOB dyn_buffer = data_blob_null;
 	uint32_t dyn_ofs = SMB2_HDR_BODY + 0x30;
+	uint32_t input_min_offset;
 	uint32_t input_buffer_offset;
 	uint32_t input_buffer_length;
+	uint32_t input_next_offset;
+	uint32_t output_min_offset;
 	uint32_t output_buffer_offset;
 	uint32_t output_buffer_length;
+	uint32_t output_next_offset;
 	static const struct smb2cli_req_expected_response expected[] = {
 	{
 		.status = NT_STATUS_OK,
@@ -247,92 +342,44 @@ static void smb2cli_ioctl_done(struct tevent_req *subreq)
 
 	state->recv_iov = iov;
 	fixed = (uint8_t *)iov[1].iov_base;
-	dyn = (uint8_t *)iov[2].iov_base;
-	dyn_len = iov[2].iov_len;
+	dyn_buffer = data_blob_const((uint8_t *)iov[2].iov_base,
+				     iov[2].iov_len);
 
 	input_buffer_offset = IVAL(fixed, 0x18);
 	input_buffer_length = IVAL(fixed, 0x1C);
 	output_buffer_offset = IVAL(fixed, 0x20);
 	output_buffer_length = IVAL(fixed, 0x24);
 
-	if ((input_buffer_offset > 0) && (input_buffer_length > 0)) {
-		uint32_t ofs;
-
-		if (input_buffer_offset != dyn_ofs) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		ofs = input_buffer_length;
-		ofs = NDR_ROUND(ofs, 8);
-
-		if (state->max_input_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.
-			 */
-			input_buffer_length = 0;
-		}
-
-		if (input_buffer_length > dyn_len) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		if (input_buffer_length > state->max_input_length) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		state->out_input_buffer.data = dyn;
-		state->out_input_buffer.length = input_buffer_length;
-
-		if (ofs > dyn_len) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		dyn_ofs += ofs;
-		dyn += ofs;
-		dyn_len -= ofs;
+	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);
+	if (tevent_req_nterror(req, error)) {
+		return;
 	}
 
-	if ((output_buffer_offset > 0) && (output_buffer_length > 0)) {
-		if (output_buffer_offset != dyn_ofs) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		if (state->max_output_length == 0) {
-			/*
-			 * We do the same logic as for
-			 * max_input_length.
-			 */
-			output_buffer_length = 0;
-		}
-
-		if (output_buffer_length > dyn_len) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		if (output_buffer_length > state->max_output_length) {
-			tevent_req_nterror(
-				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
-			return;
-		}
-
-		state->out_output_buffer.data = dyn;
-		state->out_output_buffer.length = output_buffer_length;
+	/*
+	 * If output data is returned, the output offset MUST be set to
+	 * InputOffset + InputCount rounded up to a multiple of 8.
+	 */
+	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);
+	if (tevent_req_nterror(req, error)) {
+		return;
 	}
 
 	state->out_valid = true;
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 7d2da4b9ebc..4909797543c 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -5420,6 +5420,18 @@ static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
 				    &state->out_input_buffer,
 				    &state->out_output_buffer);
 	TALLOC_FREE(subreq);
+
+	/*
+	 * This response must be signed correctly for
+	 * these "normal" error codes to be processed.
+	 * If the packet wasn't signed correctly we will get
+	 * NT_STATUS_ACCESS_DENIED or NT_STATUS_HMAC_NOT_SUPPORTED,
+	 * or NT_STATUS_INVALID_NETWORK_RESPONSE
+	 * from smb2_signing_check_pdu().
+	 *
+	 * We must never ignore the above errors here.
+	 */
+
 	if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
 		/*
 		 * The response was signed, but not supported
@@ -5465,6 +5477,19 @@ static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
 		tevent_req_done(req);
 		return;
 	}
+	if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+		/*
+		 * The response was signed, but not supported
+		 *
+		 * This might be returned by NetApp Ontap 7.3.7 SMB server
+		 * implementations.
+		 *
+		 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
+		 *
+		 */
+		tevent_req_done(req);
+		return;
+	}
 	if (tevent_req_nterror(req, status)) {
 		return;
 	}
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index b424b13cde4..d2345f094e1 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -589,6 +589,8 @@ enum csc_policy {
 #define FSCTL_SMBTORTURE	0x83840000
 #define FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT \
 	(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)
 
 /*
  * A few values from [MS-FSCC] 2.1.2.1 Reparse Tags
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 547f55db7d8..62cf1237766 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -232,3 +232,22 @@ void conn_free(connection_struct *conn)
 
 	conn_free_internal(conn);
 }
+
+/*
+ * Correctly initialize a share with case options.
+ */
+void conn_setup_case_options(connection_struct *conn)
+{
+	int snum = conn->params->service;
+
+	if (lp_case_sensitive(snum) == Auto) {
+		/* We will be setting this per packet. Set to be case
+		* insensitive for now. */
+		conn->case_sensitive = false;
+	} else {
+		conn->case_sensitive = (bool)lp_case_sensitive(snum);
+	}
+
+	conn->case_preserve = lp_preserve_case(snum);
+	conn->short_case_preserve = lp_short_preserve_case(snum);
+}
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 2c31e2b960a..9e1127c339c 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -318,6 +318,8 @@ static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
 		vfs_user = get_current_username();
 	}
 
+	conn_setup_case_options(conn);
+
 	set_conn_connectpath(conn, connpath);
 
 	/*
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index fea3abfee7d..ae5f82c2de5 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -156,6 +156,7 @@ connection_struct *conn_new(struct smbd_server_connection *sconn);
 bool conn_idle_all(struct smbd_server_connection *sconn, time_t t);
 void conn_clear_vuid_caches(struct smbd_server_connection *sconn, uint64_t vuid);
 void conn_free(connection_struct *conn);
+void conn_setup_case_options(connection_struct *conn);
 void conn_force_tdis(
 	struct smbd_server_connection *sconn,
 	bool (*check_fn)(struct connection_struct *conn,
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index ed38121f292..3802d16179b 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -556,16 +556,7 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 		      ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
 
 	/* Case options for the share. */
-	if (lp_case_sensitive(snum) == Auto) {
-		/* We will be setting this per packet. Set to be case
-		 * insensitive for now. */
-		conn->case_sensitive = False;
-	} else {
-		conn->case_sensitive = (bool)lp_case_sensitive(snum);
-	}
-
-	conn->case_preserve = lp_preserve_case(snum);
-	conn->short_case_preserve = lp_short_preserve_case(snum);
+	conn_setup_case_options(conn);
 
 	conn->encrypt_level = lp_smb_encrypt(snum);
 	if (conn->encrypt_level > SMB_SIGNING_OFF) {
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 01ae6d64ac5..8b65a691638 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -41,6 +41,7 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
 static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
 				     TALLOC_CTX *mem_ctx,
 				     DATA_BLOB *out_output,
+				     uint8_t *body_padding,
 				     bool *disconnect);
 
 static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq);
@@ -195,6 +196,7 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
 	case FSCTL_VALIDATE_NEGOTIATE_INFO:
 	case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
 	case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
+	case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
 		/*
 		 * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
 		 * FSCTL_PIPE_WAIT does not take a file handle.
@@ -284,9 +286,12 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
 	NTSTATUS status;
 	NTSTATUS error; /* transport error */
 	bool disconnect = false;
+	uint16_t body_size;
+	uint8_t body_padding = 0;
 
 	status = smbd_smb2_ioctl_recv(subreq, req,
 				      &out_output_buffer,
+				      &body_padding,
 				      &disconnect);
 
 	DEBUG(10,("smbd_smb2_request_ioctl_done: smbd_smb2_ioctl_recv returned "
@@ -319,10 +324,15 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
 		return;
 	}
 
-	out_input_offset = SMB2_HDR_BODY + 0x30;
-	out_output_offset = SMB2_HDR_BODY + 0x30;
+	/*
+	 * Only FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8
+	 * sets body_padding to a value different from 0.
+	 */
+	body_size = 0x30 + body_padding;
+	out_input_offset = SMB2_HDR_BODY + body_size;
+	out_output_offset = SMB2_HDR_BODY + body_size;
 
-	outbody = smbd_smb2_generate_outbody(req, 0x30);
+	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)) {
@@ -350,6 +360,9 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
 	      out_output_buffer.length);	/* output count */
 	SIVAL(outbody.data, 0x28, 0);		/* flags */
 	SIVAL(outbody.data, 0x2C, 0);		/* reserved */
+	if (body_padding != 0) {
+		memset(outbody.data + 0x30, 0, body_padding);
+	}
 
 	/*
 	 * Note: Windows Vista and 2008 send back also the
@@ -391,6 +404,26 @@ static struct tevent_req *smb2_ioctl_smbtorture(uint32_t ctl_code,
 		tevent_req_done(req);
 		return tevent_req_post(req, ev);
 
+	case FSCTL_SMBTORTURE_IOCTL_RESPONSE_BODY_PADDING8:
+		if (state->in_input.length != 0) {
+			tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+			return tevent_req_post(req, ev);
+		}
+
+		if (state->in_max_output > 0) {
+			uint32_t size = state->in_max_output;
+
+			state->out_output = data_blob_talloc(state, NULL, size);
+			if (tevent_req_nomem(state->out_output.data, req)) {
+				return tevent_req_post(req, ev);
+			}
+			memset(state->out_output.data, 8, size);
+		}
+
+		state->body_padding = 8;
+		tevent_req_done(req);
+		return tevent_req_post(req, ev);
+
 	default:
 		goto not_supported;
 	}
@@ -476,6 +509,7 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
 static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
 				     TALLOC_CTX *mem_ctx,
 				     DATA_BLOB *out_output,
+				     uint8_t *body_padding,
 				     bool *disconnect)
 {
 	NTSTATUS status = NT_STATUS_OK;
@@ -484,6 +518,7 @@ static NTSTATUS smbd_smb2_ioctl_recv(struct tevent_req *req,
 	enum tevent_req_state req_state;
 	uint64_t err;
 
+	*body_padding = state->body_padding;
 	*disconnect = state->disconnect;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list