[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Wed Dec 1 11:52:02 UTC 2021


The branch, master has been updated
       via  f4d0bb164f0 smb2_server: skip tcon check and chdir_current_service() for FSCTL_QUERY_NETWORK_INTERFACE_INFO
       via  629d161b8f5 s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO should work on noperm share
       via  1744dd8c5bc smb2_server: don't let SMB2_OP_IOCTL force FILE_CLOSED for invalid file ids
       via  fb33f145ff5 s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO gives INVALID_PARAMETER with invalid file ids
       via  aab54050343 smb2_ioctl: return BUFFER_TOO_SMALL in smbd_smb2_request_ioctl_done()
       via  b3212b359ed s4:torture/smb2: test FSCTL_QUERY_NETWORK_INTERFACE_INFO with BUFFER_TOO_SMALL
       via  c850ce96fd3 smb2_server: skip tcon check and chdir_current_service() for FSCTL_VALIDATE_NEGOTIATE_INFO
       via  bd3ba3c96e6 smb2_server: decouple IOCTL check from signing/encryption states
       via  1cd948d8520 smb2_server: make sure in_ctl_code = IVAL(body, 0x04); reads valid bytes
       via  735fc34682c s4:torture/smb2: add smb2.ioctl.bug14788.VALIDATE_NEGOTIATE
       via  04a79139a42 libcli/smb: split out smb2cli_raw_tcon* from smb2cli_tcon*
      from  0991946ab2e heimdal_build: Remove memset_s from roken, already in libreplace

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


- Log -----------------------------------------------------------------
commit f4d0bb164f028da46eab766135bb38175c117deb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 19:29:40 2021 +0200

    smb2_server: skip tcon check and chdir_current_service() for FSCTL_QUERY_NETWORK_INTERFACE_INFO
    
    We should not fail this just because the user doesn't have
    permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Wed Dec  1 11:51:50 UTC 2021 on sn-devel-184

commit 629d161b8f579bc24acfaf3fe02612a5237345b4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 29 19:56:20 2021 +0100

    s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO should work on noperm share
    
    Demonstrate that smbd fails FSCTL_QUERY_NETWORK_INTERFACE_INFO
    only because the user doesn't have permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 1744dd8c5bc342a74e397951506468636275fe45
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 20:27:12 2021 +0200

    smb2_server: don't let SMB2_OP_IOCTL force FILE_CLOSED for invalid file ids
    
    smbd_smb2_request_process_ioctl() already detailed checks for file_ids,
    which not reached before.
    
    .allow_invalid_fileid = true was only used for SMB2_OP_IOCTL.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit fb33f145ff598b03a08098b7f12f3c53491f6c04
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 29 19:56:20 2021 +0100

    s4:torture/smb2: FSCTL_QUERY_NETWORK_INTERFACE_INFO gives INVALID_PARAMETER with invalid file ids
    
    An invalid file id for FSCTL_QUERY_NETWORK_INTERFACE_INFO gives
    INVALID_PARAMETER instead of FILE_CLOSED.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit aab540503434817cc6b2de1d9c507f9d0b3ad980
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 20:26:58 2021 +0200

    smb2_ioctl: return BUFFER_TOO_SMALL in smbd_smb2_request_ioctl_done()
    
    We should not send more data than the client requested.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit b3212b359edb78d4c60fed377fa18478c8e75d9a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Nov 29 19:44:12 2021 +0100

    s4:torture/smb2: test FSCTL_QUERY_NETWORK_INTERFACE_INFO with BUFFER_TOO_SMALL
    
    It seems that we currently don't have BUFFER_TOO_SMALL handling
    for FSCTL/IOCTL calls.
    
    FSCTL_QUERY_NETWORK_INTERFACE_INFO is just an easy example
    to demonstrate it.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit c850ce96fd32ea91d8a31223bb09dd5b8b98d99e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Aug 16 17:28:05 2021 +0200

    smb2_server: skip tcon check and chdir_current_service() for FSCTL_VALIDATE_NEGOTIATE_INFO
    
    We should not fail this just because the user doesn't have permissions
    on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit bd3ba3c96e6ba811afd5898ff5470188557a6e33
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 17:25:53 2021 +0200

    smb2_server: decouple IOCTL check from signing/encryption states
    
    There's no reason to handle FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT
    differently if signing/encryption is used.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 1cd948d8520fd41a4e2f0cc6ee787c1e20211e33
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 17:22:39 2021 +0200

    smb2_server: make sure in_ctl_code = IVAL(body, 0x04); reads valid bytes
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 735fc34682c541056fd912d07c69f299f961983c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Wed Sep 15 18:31:06 2021 +0200

    s4:torture/smb2: add smb2.ioctl.bug14788.VALIDATE_NEGOTIATE
    
    Demonstrate that smbd fails FSCTL_VALIDATE_NEGOTIATE_INFO
    only because the user doesn't have permissions on the share root.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 04a79139a42cfd1b607317dec041618cbf629584
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Sep 16 10:51:43 2021 +0200

    libcli/smb: split out smb2cli_raw_tcon* from smb2cli_tcon*
    
    This will be used in tests in order to separate the tcon from
    validate_negotiate_info.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

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

Summary of changes:
 libcli/smb/smb2cli_tcon.c    | 183 ++++++++++++++++----
 libcli/smb/smbXcli_base.h    |  20 +++
 source3/smbd/smb2_ioctl.c    |  19 +++
 source3/smbd/smb2_server.c   |  30 ++--
 source4/torture/smb2/ioctl.c | 396 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 599 insertions(+), 49 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_tcon.c b/libcli/smb/smb2cli_tcon.c
index 03fb604db5f..d5e4fc30fba 100644
--- a/libcli/smb/smb2cli_tcon.c
+++ b/libcli/smb/smb2cli_tcon.c
@@ -23,42 +23,38 @@
 #include "../libcli/smb/smb_common.h"
 #include "../libcli/smb/smbXcli_base.h"
 
-struct smb2cli_tcon_state {
-	struct tevent_context *ev;
-	struct smbXcli_conn *conn;
-	uint32_t timeout_msec;
+struct smb2cli_raw_tcon_state {
 	struct smbXcli_session *session;
 	struct smbXcli_tcon *tcon;
 	uint8_t fixed[8];
 	uint8_t dyn_pad[1];
 };
 
-static void smb2cli_tcon_done(struct tevent_req *subreq);
-
-struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
-				     struct tevent_context *ev,
-				     struct smbXcli_conn *conn,
-				     uint32_t timeout_msec,
-				     struct smbXcli_session *session,
-				     struct smbXcli_tcon *tcon,
-				     uint16_t flags,
-				     const char *unc)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+					 struct tevent_context *ev,
+					 struct smbXcli_conn *conn,
+					 uint32_t additional_flags,
+					 uint32_t clear_flags,
+					 uint32_t timeout_msec,
+					 struct smbXcli_session *session,
+					 struct smbXcli_tcon *tcon,
+					 uint16_t tcon_flags,
+					 const char *unc)
 {
-	struct tevent_req *req, *subreq;
-	struct smb2cli_tcon_state *state;
-	uint8_t *fixed;
-	uint8_t *dyn;
+	struct tevent_req *req = NULL;
+	struct smb2cli_raw_tcon_state *state = NULL;
+	struct tevent_req *subreq = NULL;
+	uint8_t *fixed = NULL;
+	uint8_t *dyn = NULL;
 	size_t dyn_len;
-	uint32_t additional_flags = 0;
-	uint32_t clear_flags = 0;
 
-	req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+	req = tevent_req_create(mem_ctx, &state,
+				struct smb2cli_raw_tcon_state);
 	if (req == NULL) {
 		return NULL;
 	}
-	state->ev = ev;
-	state->conn = conn;
-	state->timeout_msec = timeout_msec;
 	state->session = session;
 	state->tcon = tcon;
 
@@ -77,7 +73,7 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
 	fixed = state->fixed;
 	SSVAL(fixed, 0, 9);
 	if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
-		SSVAL(fixed, 2, flags);
+		SSVAL(fixed, 2, tcon_flags);
 	} else {
 		SSVAL(fixed, 2, 0); /* Reserved */
 	}
@@ -89,10 +85,6 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
 		dyn_len = sizeof(state->dyn_pad);
 	}
 
-	if (smbXcli_session_is_authenticated(state->session)) {
-		additional_flags |= SMB2_HDR_FLAG_SIGNED;
-	}
-
 	subreq = smb2cli_req_send(state, ev, conn, SMB2_OP_TCON,
 				  additional_flags, clear_flags,
 				  timeout_msec,
@@ -104,19 +96,17 @@ struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
-	tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+	tevent_req_set_callback(subreq, smb2cli_raw_tcon_done, req);
 
 	return req;
 }
 
-static void smb2cli_tcon_validate(struct tevent_req *subreq);
-
-static void smb2cli_tcon_done(struct tevent_req *subreq)
+static void smb2cli_raw_tcon_done(struct tevent_req *subreq)
 {
 	struct tevent_req *req = tevent_req_callback_data(
 		subreq, struct tevent_req);
-	struct smb2cli_tcon_state *state = tevent_req_data(
-		req, struct smb2cli_tcon_state);
+	struct smb2cli_raw_tcon_state *state = tevent_req_data(
+		req, struct smb2cli_raw_tcon_state);
 	NTSTATUS status;
 	struct iovec *iov;
 	uint8_t *body;
@@ -156,6 +146,129 @@ static void smb2cli_tcon_done(struct tevent_req *subreq)
 				share_capabilities,
 				maximal_access);
 
+	tevent_req_done(req);
+}
+
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req)
+{
+	return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+			  uint32_t additional_flags,
+			  uint32_t clear_flags,
+			  uint32_t timeout_msec,
+			  struct smbXcli_session *session,
+			  struct smbXcli_tcon *tcon,
+			  uint16_t tcon_flags,
+			  const char *unc)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct tevent_context *ev;
+	struct tevent_req *req;
+	NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+	if (smbXcli_conn_has_async_calls(conn)) {
+		/*
+		 * Can't use sync call while an async call is in flight
+		 */
+		status = NT_STATUS_INVALID_PARAMETER;
+		goto fail;
+	}
+	ev = samba_tevent_context_init(frame);
+	if (ev == NULL) {
+		goto fail;
+	}
+	req = smb2cli_raw_tcon_send(frame, ev, conn,
+				    additional_flags, clear_flags,
+				    timeout_msec, session, tcon,
+				    tcon_flags, unc);
+	if (req == NULL) {
+		goto fail;
+	}
+	if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+		goto fail;
+	}
+	status = smb2cli_raw_tcon_recv(req);
+ fail:
+	TALLOC_FREE(frame);
+	return status;
+}
+
+struct smb2cli_tcon_state {
+	struct tevent_context *ev;
+	struct smbXcli_conn *conn;
+	uint32_t timeout_msec;
+	struct smbXcli_session *session;
+	struct smbXcli_tcon *tcon;
+	uint8_t fixed[8];
+	uint8_t dyn_pad[1];
+};
+
+static void smb2cli_tcon_done(struct tevent_req *subreq);
+
+struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
+				     struct tevent_context *ev,
+				     struct smbXcli_conn *conn,
+				     uint32_t timeout_msec,
+				     struct smbXcli_session *session,
+				     struct smbXcli_tcon *tcon,
+				     uint16_t flags,
+				     const char *unc)
+{
+	struct tevent_req *req, *subreq;
+	struct smb2cli_tcon_state *state;
+	uint32_t additional_flags = 0;
+	uint32_t clear_flags = 0;
+
+	req = tevent_req_create(mem_ctx, &state, struct smb2cli_tcon_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->conn = conn;
+	state->timeout_msec = timeout_msec;
+	state->session = session;
+	state->tcon = tcon;
+
+	if (smbXcli_session_is_authenticated(state->session)) {
+		additional_flags |= SMB2_HDR_FLAG_SIGNED;
+	}
+
+	subreq = smb2cli_raw_tcon_send(state,
+				       state->ev,
+				       state->conn,
+				       additional_flags,
+				       clear_flags,
+				       state->timeout_msec,
+				       state->session,
+				       state->tcon,
+				       flags,
+				       unc);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+	tevent_req_set_callback(subreq, smb2cli_tcon_done, req);
+
+	return req;
+}
+
+static void smb2cli_tcon_validate(struct tevent_req *subreq);
+
+static void smb2cli_tcon_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct smb2cli_tcon_state *state = tevent_req_data(
+		req, struct smb2cli_tcon_state);
+	NTSTATUS status;
+
+	status = smb2cli_raw_tcon_recv(subreq);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
 	if (!smbXcli_session_is_authenticated(state->session)) {
 		tevent_req_done(req);
 		return;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 136e0e0111a..805a62ce342 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -593,6 +593,26 @@ NTSTATUS smb2cli_logoff(struct smbXcli_conn *conn,
 			uint32_t timeout_msec,
 			struct smbXcli_session *session);
 
+/* smb2cli_raw_tcon* should only be used in tests! */
+struct tevent_req *smb2cli_raw_tcon_send(TALLOC_CTX *mem_ctx,
+					 struct tevent_context *ev,
+					 struct smbXcli_conn *conn,
+					 uint32_t additional_flags,
+					 uint32_t clear_flags,
+					 uint32_t timeout_msec,
+					 struct smbXcli_session *session,
+					 struct smbXcli_tcon *tcon,
+					 uint16_t tcon_flags,
+					 const char *unc);
+NTSTATUS smb2cli_raw_tcon_recv(struct tevent_req *req);
+NTSTATUS smb2cli_raw_tcon(struct smbXcli_conn *conn,
+			  uint32_t additional_flags,
+			  uint32_t clear_flags,
+			  uint32_t timeout_msec,
+			  struct smbXcli_session *session,
+			  struct smbXcli_tcon *tcon,
+			  uint16_t tcon_flags,
+			  const char *unc);
 struct tevent_req *smb2cli_tcon_send(TALLOC_CTX *mem_ctx,
 				     struct tevent_context *ev,
 				     struct smbXcli_conn *conn,
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index 136f9baeda3..e4f8c10e3af 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -296,6 +296,7 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
 	uint32_t in_ctl_code;
 	uint64_t in_file_id_persistent;
 	uint64_t in_file_id_volatile;
+	uint32_t in_max_output_length;
 	uint32_t out_input_offset;
 	uint32_t out_output_offset;
 	DATA_BLOB out_output_buffer = data_blob_null;
@@ -328,6 +329,24 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq)
 	in_ctl_code		= IVAL(inbody, 0x04);
 	in_file_id_persistent	= BVAL(inbody, 0x08);
 	in_file_id_volatile	= BVAL(inbody, 0x10);
+	in_max_output_length	= IVAL(inbody, 0x2C);
+
+	if (out_output_buffer.length > in_max_output_length) {
+		/*
+		 * Return NT_STATUS_BUFFER_TOO_SMALL by
+		 * default if the provided buffer doesn't
+		 * fit.
+		 *
+		 * If someone wants truncated data
+		 * together with STATUS_BUFFER_OVERFLOW
+		 * it needs to be done explicitly in
+		 * the backends. We currently do that
+		 * in:
+		 * - fsctl_dfs_get_refers()
+		 * - smbd_smb2_ioctl_pipe_read_done()
+		 */
+		status = NT_STATUS_BUFFER_TOO_SMALL;
+	}
 
 	if (smbd_smb2_ioctl_is_failure(in_ctl_code, status,
 				       out_output_buffer.length)) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 4f302c35419..042f343b0ca 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -67,7 +67,6 @@ static const struct smbd_smb2_dispatch_table {
 	bool need_tcon;
 	bool as_root;
 	uint16_t fileid_ofs;
-	bool allow_invalid_fileid;
 	bool modify;
 } smbd_smb2_table[] = {
 #define _OP(o) .opcode = o, .name = #o
@@ -132,7 +131,6 @@ static const struct smbd_smb2_dispatch_table {
 		.need_session = true,
 		.need_tcon = true,
 		.fileid_ofs = 0x08,
-		.allow_invalid_fileid = true,
 		.modify = true,
 	},{
 		_OP(SMB2_OP_CANCEL),
@@ -3174,7 +3172,9 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		if (!NT_STATUS_IS_OK(session_status)) {
 			return smbd_smb2_request_error(req, session_status);
 		}
-	} else if (opcode == SMB2_OP_IOCTL) {
+	}
+
+	if (opcode == SMB2_OP_IOCTL) {
 		/*
 		 * Some special IOCTL calls don't require
 		 * file, tcon nor session.
@@ -3194,7 +3194,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
 		size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
 		uint32_t in_ctl_code;
-		size_t needed = 4;
+		size_t needed = 8;
 
 		if (needed > body_size) {
 			return smbd_smb2_request_error(req,
@@ -3209,6 +3209,12 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
 			call = &_root_ioctl_call;
 			break;
+		case FSCTL_VALIDATE_NEGOTIATE_INFO:
+			call = &_root_ioctl_call;
+			break;
+		case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
+			call = &_root_ioctl_call;
+			break;
 		}
 	}
 
@@ -3318,16 +3324,12 @@ skipped_signing:
 				return smbd_smb2_request_error(req,
 						req->compound_create_err);
 			}
-			if (!call->allow_invalid_fileid) {
-				return smbd_smb2_request_error(req,
-						NT_STATUS_FILE_CLOSED);
-			}
-
-			if (file_id_persistent != UINT64_MAX) {
-				return smbd_smb2_request_error(req,
-						NT_STATUS_FILE_CLOSED);
-			}
-			if (file_id_volatile != UINT64_MAX) {
+			/*
+			 * smbd_smb2_request_process_ioctl()
+			 * has more checks in order to return more
+			 * detailed error codes...
+			 */
+			if (opcode != SMB2_OP_IOCTL) {
 				return smbd_smb2_request_error(req,
 						NT_STATUS_FILE_CLOSED);
 			}
diff --git a/source4/torture/smb2/ioctl.c b/source4/torture/smb2/ioctl.c
index 022ea001688..a4d8885fe13 100644
--- a/source4/torture/smb2/ioctl.c
+++ b/source4/torture/smb2/ioctl.c
@@ -27,6 +27,10 @@
 #include "torture/smb2/proto.h"
 #include "../libcli/smb/smbXcli_base.h"
 #include "librpc/gen_ndr/ndr_ioctl.h"
+#include "lib/cmdline/cmdline.h"
+#include "libcli/resolve/resolve.h"
+#include "lib/param/param.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #define FNAME	"testfsctl.dat"
 #define FNAME2	"testfsctl2.dat"
@@ -6923,12 +6927,398 @@ static bool test_ioctl_bug14769(struct torture_context *torture,
 	return ret;
 }
 
+/*
+   basic regression test for BUG 14788,
+   with FSCTL_VALIDATE_NEGOTIATE_INFO
+   https://bugzilla.samba.org/show_bug.cgi?id=14788
+*/
+static bool test_ioctl_bug14788_VALIDATE_NEGOTIATE(struct torture_context *torture,
+				struct smb2_tree *tree0)
+{
+	const char *host = torture_setting_string(torture, "host", NULL);
+	const char *share = torture_setting_string(torture, "share", NULL);
+	const char *noperm_share = torture_setting_string(torture, "noperm_share", "noperm");
+	struct smb2_transport *transport0 = tree0->session->transport;
+	struct smbcli_options options;
+	struct smb2_transport *transport = NULL;
+	struct smb2_tree *tree = NULL;
+	struct smb2_session *session = NULL;
+	uint16_t noperm_flags = 0;
+	const char *noperm_unc = NULL;
+	struct smb2_tree *noperm_tree = NULL;
+	uint32_t timeout_msec;
+	struct tevent_req *subreq = NULL;
+	struct cli_credentials *credentials = samba_cmdline_get_creds();
+	NTSTATUS status;
+
+	if (smbXcli_conn_protocol(transport0->conn) < PROTOCOL_SMB3_00) {
+		torture_skip(torture, "Can't test without SMB 3 support");
+	}
+
+	options = transport0->options;
+	options.client_guid = GUID_random();
+	options.min_protocol = PROTOCOL_SMB3_00;
+	options.max_protocol = PROTOCOL_SMB3_02;
+
+	status = smb2_connect(torture,
+			      host,
+			      lpcfg_smb_ports(torture->lp_ctx),
+			      share,
+			      lpcfg_resolve_context(torture->lp_ctx),
+			      credentials,
+			      &tree,
+			      torture->ev,
+			      &options,
+			      lpcfg_socket_options(torture->lp_ctx),
+			      lpcfg_gensec_settings(torture, torture->lp_ctx)
+			      );
+	torture_assert_ntstatus_ok(torture, status, "smb2_connect options failed");
+	session = tree->session;
+	transport = session->transport;
+
+	timeout_msec = tree->session->transport->options.request_timeout * 1000;
+
+	subreq = smb2cli_validate_negotiate_info_send(torture,
+						      torture->ev,
+						      transport->conn,
+						      timeout_msec,
+						      session->smbXcli,
+						      tree->smbXcli);
+	torture_assert(torture,
+		       tevent_req_poll_ntstatus(subreq, torture->ev, &status),
+		       "tevent_req_poll_ntstatus");
+	status = smb2cli_validate_negotiate_info_recv(subreq);
+	torture_assert_ntstatus_ok(torture, status, "smb2cli_validate_negotiate_info");
+
+	noperm_unc = talloc_asprintf(torture, "\\\\%s\\%s", host, noperm_share);
+	torture_assert(torture, noperm_unc != NULL, "talloc_asprintf");
+
+	noperm_tree = smb2_tree_init(session, torture, false);
+	torture_assert(torture, noperm_tree != NULL, "smb2_tree_init");
+
+	status = smb2cli_raw_tcon(transport->conn,
+				  SMB2_HDR_FLAG_SIGNED,
+				  0, /* clear_flags */
+				  timeout_msec,
+				  session->smbXcli,
+				  noperm_tree->smbXcli,
+				  noperm_flags,
+				  noperm_unc);
+	if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_NETWORK_NAME)) {
+		torture_skip(torture, talloc_asprintf(torture,
+			     "noperm_unc[%s] %s",
+			     noperm_unc, nt_errstr(status)));
+	}
+	torture_assert_ntstatus_ok(torture, status,
+				   talloc_asprintf(torture,
+				   "smb2cli_tcon(%s)",
+				   noperm_unc));
+
+	subreq = smb2cli_validate_negotiate_info_send(torture,
+						      torture->ev,
+						      transport->conn,
+						      timeout_msec,
+						      session->smbXcli,
+						      noperm_tree->smbXcli);
+	torture_assert(torture,
+		       tevent_req_poll_ntstatus(subreq, torture->ev, &status),
+		       "tevent_req_poll_ntstatus");


-- 
Samba Shared Repository



More information about the samba-cvs mailing list