From 5f5389fbe69a3a7c13ea54fcd11f6e2f561a2e32 Mon Sep 17 00:00:00 2001 From: Ira Cooper Date: Fri, 20 Jun 2014 21:29:26 -0700 Subject: [PATCH 1/2] s3: Refactor smbd_smb2_request_process_negprot Breakout smb2_protocol_dialect_match to support future work in fsctl_validate_neg_info. --- source3/smbd/globals.h | 3 + source3/smbd/smb2_negprot.c | 140 ++++++++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 63 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index cd99fe7..3548d14 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_negprot.c b/source3/smbd/smb2_negprot.c index 6643464..8b6c93c 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; -- 1.9.3