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.
Back-port of patch
439de096ae0e1c1b8812fa202f5eba7a891d7a0a written
by Ira Cooper <ira@samba.org> and reviewed by Stefan Metzmacher <metze@samba.org>.
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 <jra@samba.org>
Autobuild-User(v4-1-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-1-test): Wed Apr 8 23:42:50 CEST 2015 on sn-devel-104
struct GUID in_guid;
uint16_t in_security_mode;
uint16_t in_num_dialects;
struct GUID in_guid;
uint16_t in_security_mode;
uint16_t in_num_dialects;
DATA_BLOB out_guid_blob;
NTSTATUS status;
DATA_BLOB out_guid_blob;
NTSTATUS status;
+ enum protocol_types protocol = PROTOCOL_NONE;
if (in_input->length < 0x18) {
return NT_STATUS_INVALID_PARAMETER;
if (in_input->length < 0x18) {
return NT_STATUS_INVALID_PARAMETER;
- 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;
}
*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_compare(&in_guid, &conn->smb2.client.guid) != 0) {
*disconnect = true;
return NT_STATUS_ACCESS_DENIED;
if (GUID_compare(&in_guid, &conn->smb2.client.guid) != 0) {
*disconnect = true;
return NT_STATUS_ACCESS_DENIED;