From 8628ae2004665bf278a830f744fcba54eddd5db7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 31 Mar 2015 16:15:59 -0700 Subject: [PATCH] s3: Refactor smbd_smb2_request_process_negprot Breakout smb2_protocol_dialect_match to support future work in fsctl_validate_neg_info. Back port of 6221937acac7017dee397d1c9846236d9fd5f613 written by Ira Cooper and signed off by Stefan Metzmacher Fixes bug #11187 - Mac OS X 10.10.x fails Validate Negotiate Request to 4.1.x https://bugzilla.samba.org/show_bug.cgi?id=11187 Signed-off-by: Jeremy Allison --- source3/smbd/globals.h | 3 ++ source3/smbd/smb2_negprot.c | 114 ++++++++++++++++---------------------------- 2 files changed, 43 insertions(+), 74 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 1286ced2311..0942e46744d 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -258,6 +258,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_negprot.c b/source3/smbd/smb2_negprot.c index 963a5572532..0cf5c8d697a 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -82,6 +82,43 @@ void reply_smb20ff(struct smb_request *req, uint16_t choice) reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF); } +enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn, + const int dialect_count, + uint16_t *dialect) +{ + struct { + enum protocol_types proto; + uint16_t dialect; + } pd[] = { + { PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300 }, + { PROTOCOL_SMB2_24, SMB2_DIALECT_REVISION_224 }, + { PROTOCOL_SMB2_22, SMB2_DIALECT_REVISION_222 }, + { PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210 }, + { PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202 }, + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(pd); i ++) { + size_t c = 0; + + if (lp_srv_maxprotocol() < pd[i].proto) { + continue; + } + if (lp_srv_minprotocol() > pd[i].proto) { + continue; + } + + for (c = 0; c < dialect_count; c++) { + *dialect = SVAL(indyn, c*2); + if (*dialect == pd[i].dialect) { + return pd[i].proto; + } + } + } + + return PROTOCOL_NONE; +} + NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) { NTSTATUS status; @@ -138,80 +175,9 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } indyn = SMBD_SMB2_IN_DYN_PTR(req); - for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { - if (lp_srv_maxprotocol() < PROTOCOL_SMB3_00) { - break; - } - if (lp_srv_minprotocol() > PROTOCOL_SMB3_00) { - break; - } - - dialect = SVAL(indyn, c*2); - if (dialect == SMB3_DIALECT_REVISION_300) { - protocol = PROTOCOL_SMB3_00; - break; - } - } - - for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { - if (lp_srv_maxprotocol() < PROTOCOL_SMB2_24) { - break; - } - if (lp_srv_minprotocol() > PROTOCOL_SMB2_24) { - break; - } - - dialect = SVAL(indyn, c*2); - if (dialect == SMB2_DIALECT_REVISION_224) { - protocol = PROTOCOL_SMB2_24; - break; - } - } - - for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { - if (lp_srv_maxprotocol() < PROTOCOL_SMB2_22) { - break; - } - if (lp_srv_minprotocol() > PROTOCOL_SMB2_22) { - break; - } - - dialect = SVAL(indyn, c*2); - if (dialect == SMB2_DIALECT_REVISION_222) { - protocol = PROTOCOL_SMB2_22; - break; - } - } - - for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { - if (lp_srv_maxprotocol() < PROTOCOL_SMB2_10) { - break; - } - if (lp_srv_minprotocol() > PROTOCOL_SMB2_10) { - break; - } - - dialect = SVAL(indyn, c*2); - if (dialect == SMB2_DIALECT_REVISION_210) { - protocol = PROTOCOL_SMB2_10; - break; - } - } - - for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { - if (lp_srv_maxprotocol() < PROTOCOL_SMB2_02) { - break; - } - if (lp_srv_minprotocol() > PROTOCOL_SMB2_02) { - break; - } - - dialect = SVAL(indyn, c*2); - if (dialect == SMB2_DIALECT_REVISION_202) { - protocol = PROTOCOL_SMB2_02; - break; - } - } + protocol = smbd_smb2_protocol_dialect_match(indyn, + dialect_count, + &dialect); for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) { if (lp_srv_maxprotocol() < PROTOCOL_SMB2_10) { -- 2.11.4.GIT