[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Mon Jun 23 06:29:03 MDT 2014


The branch, master has been updated
       via  439de09 s3: Fix fsctl_validate_neg_info to pass MS compliance suite.
       via  6221937 s3: Refactor smbd_smb2_request_process_negprot
      from  cad1d0b torture3: Reproducer for bug 10593

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


- Log -----------------------------------------------------------------
commit 439de096ae0e1c1b8812fa202f5eba7a891d7a0a
Author: Ira Cooper <ira at samba.org>
Date:   Fri Jun 20 21:41:19 2014 -0700

    s3: Fix fsctl_validate_neg_info to pass MS compliance suite.
    
    It turns out that all the client and server need to agree on is what
    protocol should have been negotiated.  If they disagree, they should
    disconnect.  The contents of the list of protocols used during
    negotiate and during FSCTL_VALIDATE_NEGOTIATE_INFO do not need to match.
    
    Signed-off-by: Ira Cooper <ira at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Mon Jun 23 14:28:25 CEST 2014 on sn-devel-104

commit 6221937acac7017dee397d1c9846236d9fd5f613
Author: Ira Cooper <ira at samba.org>
Date:   Fri Jun 20 21:29:26 2014 -0700

    s3: Refactor smbd_smb2_request_process_negprot
    
    Breakout smb2_protocol_dialect_match to support future work in
    fsctl_validate_neg_info.
    
    Signed-off-by: Ira Cooper <ira at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 source3/smbd/globals.h               |    3 +
 source3/smbd/smb2_ioctl_network_fs.c |   28 ++++---
 source3/smbd/smb2_negprot.c          |  140 +++++++++++++++++++---------------
 3 files changed, 97 insertions(+), 74 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 28e4f94..d9ca5e3 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -260,6 +260,9 @@ NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
 					size_t expected_body_size);
 
+enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
+		                                     const int dialect_count,
+						     uint16_t *dialect);
 NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_sesssetup(struct smbd_smb2_request *req);
 NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req);
diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c
index 5e0dc10..b2dfb21 100644
--- a/source3/smbd/smb2_ioctl_network_fs.c
+++ b/source3/smbd/smb2_ioctl_network_fs.c
@@ -355,9 +355,10 @@ static NTSTATUS fsctl_validate_neg_info(TALLOC_CTX *mem_ctx,
 	struct GUID in_guid;
 	uint16_t in_security_mode;
 	uint16_t in_num_dialects;
-	uint16_t i;
+	uint16_t dialect;
 	DATA_BLOB out_guid_blob;
 	NTSTATUS status;
+	enum protocol_types protocol = PROTOCOL_NONE;
 
 	if (in_input->length < 0x18) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -381,20 +382,25 @@ static NTSTATUS fsctl_validate_neg_info(TALLOC_CTX *mem_ctx,
 		return status;
 	}
 
-	if (in_num_dialects != conn->smb2.client.num_dialects) {
+	/*
+	 * From: [MS-SMB2]
+	 * 3.3.5.15.12 Handling a Validate Negotiate Info Request
+	 *
+	 * The server MUST determine the greatest common dialect
+	 * between the dialects it implements and the Dialects array
+	 * of the VALIDATE_NEGOTIATE_INFO request. If no dialect is
+	 * matched, or if the value is not equal to Connection.Dialect,
+	 * the server MUST terminate the transport connection
+	 * and free the Connection object.
+	 */
+	protocol = smbd_smb2_protocol_dialect_match(in_input->data + 0x18,
+						    in_num_dialects,
+						    &dialect);
+	if (conn->protocol != protocol) {
 		*disconnect = true;
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	for (i=0; i < in_num_dialects; i++) {
-		uint16_t v = SVAL(in_input->data, 0x18 + i*2);
-
-		if (conn->smb2.client.dialects[i] != v) {
-			*disconnect = true;
-			return NT_STATUS_ACCESS_DENIED;
-		}
-	}
-
 	if (!GUID_equal(&in_guid, &conn->smb2.client.guid)) {
 		*disconnect = true;
 		return NT_STATUS_ACCESS_DENIED;
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 6643464..5fa1fbb 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -82,61 +82,12 @@ void reply_smb20ff(struct smb_request *req, uint16_t choice)
 	reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
 }
 
-NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
+enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
+				const int dialect_count,
+				uint16_t *dialect)
 {
-	NTSTATUS status;
-	const uint8_t *inbody;
-	const uint8_t *indyn = NULL;
-	DATA_BLOB outbody;
-	DATA_BLOB outdyn;
-	DATA_BLOB negprot_spnego_blob;
-	uint16_t security_offset;
-	DATA_BLOB security_buffer;
-	size_t expected_dyn_size = 0;
-	size_t c;
-	uint16_t security_mode;
-	uint16_t dialect_count;
-	uint16_t in_security_mode;
-	uint32_t in_capabilities;
-	DATA_BLOB in_guid_blob;
-	struct GUID in_guid;
-	uint16_t dialect = 0;
-	uint32_t capabilities;
-	DATA_BLOB out_guid_blob;
-	struct GUID out_guid;
+	size_t c = 0;
 	enum protocol_types protocol = PROTOCOL_NONE;
-	uint32_t max_limit;
-	uint32_t max_trans = lp_smb2_max_trans();
-	uint32_t max_read = lp_smb2_max_read();
-	uint32_t max_write = lp_smb2_max_write();
-	NTTIME now = timeval_to_nttime(&req->request_time);
-
-	status = smbd_smb2_request_verify_sizes(req, 0x24);
-	if (!NT_STATUS_IS_OK(status)) {
-		return smbd_smb2_request_error(req, status);
-	}
-	inbody = SMBD_SMB2_IN_BODY_PTR(req);
-
-	dialect_count = SVAL(inbody, 0x02);
-
-	in_security_mode = SVAL(inbody, 0x04);
-	in_capabilities = IVAL(inbody, 0x08);
-	in_guid_blob = data_blob_const(inbody + 0x0C, 16);
-
-	if (dialect_count == 0) {
-		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
-	}
-
-	status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
-	if (!NT_STATUS_IS_OK(status)) {
-		return smbd_smb2_request_error(req, status);
-	}
-
-	expected_dyn_size = dialect_count * 2;
-	if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
-		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
-	}
-	indyn = SMBD_SMB2_IN_DYN_PTR(req);
 
 	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
 		if (lp_server_max_protocol() < PROTOCOL_SMB3_00) {
@@ -146,8 +97,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 			break;
 		}
 
-		dialect = SVAL(indyn, c*2);
-		if (dialect == SMB3_DIALECT_REVISION_300) {
+		*dialect = SVAL(indyn, c*2);
+		if (*dialect == SMB3_DIALECT_REVISION_300) {
 			protocol = PROTOCOL_SMB3_00;
 			break;
 		}
@@ -161,8 +112,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 			break;
 		}
 
-		dialect = SVAL(indyn, c*2);
-		if (dialect == SMB2_DIALECT_REVISION_224) {
+		*dialect = SVAL(indyn, c*2);
+		if (*dialect == SMB2_DIALECT_REVISION_224) {
 			protocol = PROTOCOL_SMB2_24;
 			break;
 		}
@@ -176,8 +127,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 			break;
 		}
 
-		dialect = SVAL(indyn, c*2);
-		if (dialect == SMB2_DIALECT_REVISION_222) {
+		*dialect = SVAL(indyn, c*2);
+		if (*dialect == SMB2_DIALECT_REVISION_222) {
 			protocol = PROTOCOL_SMB2_22;
 			break;
 		}
@@ -191,8 +142,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 			break;
 		}
 
-		dialect = SVAL(indyn, c*2);
-		if (dialect == SMB2_DIALECT_REVISION_210) {
+		*dialect = SVAL(indyn, c*2);
+		if (*dialect == SMB2_DIALECT_REVISION_210) {
 			protocol = PROTOCOL_SMB2_10;
 			break;
 		}
@@ -206,13 +157,76 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 			break;
 		}
 
-		dialect = SVAL(indyn, c*2);
-		if (dialect == SMB2_DIALECT_REVISION_202) {
+		*dialect = SVAL(indyn, c*2);
+		if (*dialect == SMB2_DIALECT_REVISION_202) {
 			protocol = PROTOCOL_SMB2_02;
 			break;
 		}
 	}
 
+	return protocol;
+}
+
+NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
+{
+	NTSTATUS status;
+	const uint8_t *inbody;
+	const uint8_t *indyn = NULL;
+	DATA_BLOB outbody;
+	DATA_BLOB outdyn;
+	DATA_BLOB negprot_spnego_blob;
+	uint16_t security_offset;
+	DATA_BLOB security_buffer;
+	size_t expected_dyn_size = 0;
+	size_t c;
+	uint16_t security_mode;
+	uint16_t dialect_count;
+	uint16_t in_security_mode;
+	uint32_t in_capabilities;
+	DATA_BLOB in_guid_blob;
+	struct GUID in_guid;
+	uint16_t dialect = 0;
+	uint32_t capabilities;
+	DATA_BLOB out_guid_blob;
+	struct GUID out_guid;
+	enum protocol_types protocol = PROTOCOL_NONE;
+	uint32_t max_limit;
+	uint32_t max_trans = lp_smb2_max_trans();
+	uint32_t max_read = lp_smb2_max_read();
+	uint32_t max_write = lp_smb2_max_write();
+	NTTIME now = timeval_to_nttime(&req->request_time);
+
+	status = smbd_smb2_request_verify_sizes(req, 0x24);
+	if (!NT_STATUS_IS_OK(status)) {
+		return smbd_smb2_request_error(req, status);
+	}
+	inbody = SMBD_SMB2_IN_BODY_PTR(req);
+
+	dialect_count = SVAL(inbody, 0x02);
+
+	in_security_mode = SVAL(inbody, 0x04);
+	in_capabilities = IVAL(inbody, 0x08);
+	in_guid_blob = data_blob_const(inbody + 0x0C, 16);
+
+	if (dialect_count == 0) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+
+	status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
+	if (!NT_STATUS_IS_OK(status)) {
+		return smbd_smb2_request_error(req, status);
+	}
+
+	expected_dyn_size = dialect_count * 2;
+	if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
+		return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+	}
+	indyn = SMBD_SMB2_IN_DYN_PTR(req);
+
+	protocol = smbd_smb2_protocol_dialect_match(indyn,
+					dialect_count,
+					&dialect);
+
 	for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
 		if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
 			break;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list