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

Jule Anger janger at samba.org
Mon Dec 13 09:45:01 UTC 2021


The branch, v4-14-test has been updated
       via  08eb470b9c5 smb2_server: don't let SMB2_OP_IOCTL force FILE_CLOSED for invalid file ids
       via  25c97fc3a0f smb2_ioctl: return BUFFER_TOO_SMALL in smbd_smb2_request_ioctl_done()
       via  016d9c40bca smb2_server: skip tcon check and chdir_current_service() for FSCTL_VALIDATE_NEGOTIATE_INFO
       via  fd82e1e4bad smb2_server: decouple IOCTL check from signing/encryption states
       via  ea6db15c314 smb2_server: make sure in_ctl_code = IVAL(body, 0x04); reads valid bytes
       via  8eb06f10a12 s4:torture/smb2: add smb2.ioctl.bug14788.VALIDATE_NEGOTIATE
       via  fd8864ef4fe libcli/smb: split out smb2cli_raw_tcon* from smb2cli_tcon*
       via  4d2d5a3c66a s3:smbd: remove dead code from smbd_smb2_request_dispatch()
      from  3d35397e103 smbd: s3-dsgetdcname: handle num_ips == 0

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


- Log -----------------------------------------------------------------
commit 08eb470b9c580d3353c64dad34ba1c1109e1c042
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>
    (cherry picked from commit 1744dd8c5bc342a74e397951506468636275fe45)
    
    Autobuild-User(v4-14-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-14-test): Mon Dec 13 09:44:15 UTC 2021 on sn-devel-184

commit 25c97fc3a0f13515ad6910814dc8f19fc862e329
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>
    (cherry picked from commit aab540503434817cc6b2de1d9c507f9d0b3ad980)

commit 016d9c40bcafa7c654b56ec432ec23000a9cf4f0
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>
    (cherry picked from commit c850ce96fd32ea91d8a31223bb09dd5b8b98d99e)

commit fd82e1e4bad25696b62b4b308f2cc81b131e06a8
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>
    (cherry picked from commit bd3ba3c96e6ba811afd5898ff5470188557a6e33)

commit ea6db15c31460e4ec07b70a5139960552632a8ba
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>
    (cherry picked from commit 1cd948d8520fd41a4e2f0cc6ee787c1e20211e33)

commit 8eb06f10a12d0c6e787b354085d5b8e4378cf12d
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>
    (cherry picked from commit 735fc34682c541056fd912d07c69f299f961983c)

commit fd8864ef4fed6674d6f4f9ffedbe9366dd97a648
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>
    (cherry picked from commit 04a79139a42cfd1b607317dec041618cbf629584)

commit 4d2d5a3c66af111700191d384a6afac0fc759928
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Jul 13 16:37:42 2021 +0200

    s3:smbd: remove dead code from smbd_smb2_request_dispatch()
    
    We have '} else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {'
    before...
    
    Use 'git show -U52' to see the whole story...
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit f8f4a9faf099eb768eaa25f1e1a7d126b75291d0)
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14788

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

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   |  39 +++------
 source4/torture/smb2/ioctl.c | 111 ++++++++++++++++++++++++++
 5 files changed, 311 insertions(+), 61 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_tcon.c b/libcli/smb/smb2cli_tcon.c
index 8863bae0764..7bbae8ea3b3 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_10) {
-		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 ac382b2ae6a..75e758f5a84 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -589,6 +589,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 3d65a96368c..7ca15a23320 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 1322cf3ba08..b5a831f6df0 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -64,7 +64,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
@@ -129,7 +128,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),
@@ -2717,9 +2715,6 @@ static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
 		/* Unencrypted packet, can be signed */
 		if (req->do_signing) {
 			sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
-		} else if (opcode == SMB2_OP_CANCEL) {
-			/* Cancel requests are allowed to skip signing */
-			sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
 		}
 	}
 
@@ -3080,9 +3075,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_CANCEL) {
-		/* Cancel requests are allowed to skip the signing */
-	} else if (opcode == SMB2_OP_IOCTL) {
+	}
+
+	if (opcode == SMB2_OP_IOCTL) {
 		/*
 		 * Some special IOCTL calls don't require
 		 * file, tcon nor session.
@@ -3102,7 +3097,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,
@@ -3117,14 +3112,10 @@ 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;
 		}
-	} else if (signing_required) {
-		/*
-		 * If signing is required we try to sign
-		 * a possible error response
-		 */
-		req->do_signing = true;
-		return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
 	}
 
 	if (flags & SMB2_HDR_FLAG_CHAINED) {
@@ -3225,16 +3216,12 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 
 		fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
 		if (fsp == NULL) {
-			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 1de5179e336..84b5e092705 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/popt_common.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"
@@ -6845,12 +6849,115 @@ static bool test_ioctl_bug14607(struct torture_context *torture,
 	return true;
 }
 
+/*
+   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 = popt_get_cmdline_credentials();
+	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,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list