Any garbage at the end needs to be ignored.
This fixes the Negotiate_SMB311_ContextID_NetName test from:
https://github.com/microsoft/WindowsProtocolTestSuites/blob/main/TestSuites/FileServer/src/SMB2/TestSuite/Negotiate/Negotiation.cs#L730
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Jul 12 21:25:21 UTC 2021 on sn-devel-184
parse a set of SMB2 create contexts
*/
NTSTATUS smb2_negotiate_context_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
+ uint16_t expected_count,
struct smb2_negotiate_contexts *contexts)
{
const uint8_t *data = buffer.data;
uint32_t remaining = buffer.length;
+ uint16_t idx;
- while (true) {
+ for (idx = 0; idx < expected_count; idx++) {
uint16_t data_length;
uint16_t type;
NTSTATUS status;
return status;
}
+ if (contexts->num_contexts == expected_count) {
+ break;
+ }
+
remaining -= next_offset;
data += next_offset;
data += pad;
}
+ if (contexts->num_contexts != expected_count) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return NT_STATUS_OK;
}
};
struct smb2_negotiate_contexts {
- uint32_t num_contexts;
+ uint16_t num_contexts;
struct smb2_negotiate_context *contexts;
};
parse a set of SMB2 negotiate contexts
*/
NTSTATUS smb2_negotiate_context_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
- struct smb2_negotiate_contexts *contexts);
+ uint16_t expected_count,
+ struct smb2_negotiate_contexts *contexts);
/*
negotiate a buffer of a set of negotiate contexts
negotiate_context_blob.data += ctx_ofs;
negotiate_context_blob.length -= ctx_ofs;
- status = smb2_negotiate_context_parse(state, negotiate_context_blob, &c);
- if (tevent_req_nterror(req, status)) {
- return;
+ status = smb2_negotiate_context_parse(state,
+ negotiate_context_blob,
+ negotiate_context_count,
+ &c);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
}
-
- if (negotiate_context_count != c.num_contexts) {
- tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ if (tevent_req_nterror(req, status)) {
return;
}
in_negotiate_context_blob.length -= ofs;
status = smb2_negotiate_context_parse(req,
- in_negotiate_context_blob, &in_c);
+ in_negotiate_context_blob,
+ in_negotiate_context_count,
+ &in_c);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
-
- if (in_negotiate_context_count != in_c.num_contexts) {
- return smbd_smb2_request_error(req,
- NT_STATUS_INVALID_PARAMETER);
- }
}
if ((dialect != SMB2_DIALECT_REVISION_2FF) &&