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) {
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;
}
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;
}
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;
}
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;
}
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;