Commit 6dffa4c2 authored by Steve French's avatar Steve French

smb3: negotiate current dialect (SMB3.1.1) when version 3 or greater requested

SMB3.1.1 is the newest, and preferred dialect, and is included in
the requested dialect list by default (ie if no vers= is specified
on mount) but it should also be requested if SMB3 or later is requested
(vers=3 instead of a specific dialect: vers=2.1, vers=3.02 or vers=3.0).

Currently specifying "vers=3" only requests smb3.0 and smb3.02 but this
patch fixes it to also request smb3.1.1 dialect, as it is the newest
and most secure dialect and is a "version 3 or later" dialect (the intent
of "vers=3").
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Suggested-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
Reviewed-by: default avatarShyam Prasad N <sprasad@microsoft.com>
Reviewed-by: default avatarPavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent f40ddce8
...@@ -397,7 +397,7 @@ cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3) ...@@ -397,7 +397,7 @@ cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3)
ctx->vals = &smb3any_values; ctx->vals = &smb3any_values;
break; break;
case Smb_default: case Smb_default:
ctx->ops = &smb30_operations; /* currently identical with 3.0 */ ctx->ops = &smb30_operations;
ctx->vals = &smbdefault_values; ctx->vals = &smbdefault_values;
break; break;
default: default:
......
...@@ -814,8 +814,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) ...@@ -814,8 +814,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
SMB3ANY_VERSION_STRING) == 0) { SMB3ANY_VERSION_STRING) == 0) {
req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
req->DialectCount = cpu_to_le16(2); req->Dialects[2] = cpu_to_le16(SMB311_PROT_ID);
total_len += 4; req->DialectCount = cpu_to_le16(3);
total_len += 6;
} else if (strcmp(server->vals->version_string, } else if (strcmp(server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) { SMBDEFAULT_VERSION_STRING) == 0) {
req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
...@@ -848,6 +849,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) ...@@ -848,6 +849,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
memcpy(req->ClientGUID, server->client_guid, memcpy(req->ClientGUID, server->client_guid,
SMB2_CLIENT_GUID_SIZE); SMB2_CLIENT_GUID_SIZE);
if ((server->vals->protocol_id == SMB311_PROT_ID) || if ((server->vals->protocol_id == SMB311_PROT_ID) ||
(strcmp(server->vals->version_string,
SMB3ANY_VERSION_STRING) == 0) ||
(strcmp(server->vals->version_string, (strcmp(server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0)) SMBDEFAULT_VERSION_STRING) == 0))
assemble_neg_contexts(req, server, &total_len); assemble_neg_contexts(req, server, &total_len);
...@@ -883,6 +886,10 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) ...@@ -883,6 +886,10 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
cifs_server_dbg(VFS, cifs_server_dbg(VFS,
"SMB2.1 dialect returned but not requested\n"); "SMB2.1 dialect returned but not requested\n");
return -EIO; return -EIO;
} else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
/* ops set to 3.0 by default for default so update */
server->ops = &smb311_operations;
server->vals = &smb311_values;
} }
} else if (strcmp(server->vals->version_string, } else if (strcmp(server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) { SMBDEFAULT_VERSION_STRING) == 0) {
...@@ -1042,10 +1049,11 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) ...@@ -1042,10 +1049,11 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
SMB3ANY_VERSION_STRING) == 0) { SMB3ANY_VERSION_STRING) == 0) {
pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
pneg_inbuf->DialectCount = cpu_to_le16(2); pneg_inbuf->Dialects[2] = cpu_to_le16(SMB311_PROT_ID);
/* structure is big enough for 3 dialects, sending only 2 */ pneg_inbuf->DialectCount = cpu_to_le16(3);
/* SMB 2.1 not included so subtract one dialect from len */
inbuflen = sizeof(*pneg_inbuf) - inbuflen = sizeof(*pneg_inbuf) -
(2 * sizeof(pneg_inbuf->Dialects[0])); (sizeof(pneg_inbuf->Dialects[0]));
} else if (strcmp(server->vals->version_string, } else if (strcmp(server->vals->version_string,
SMBDEFAULT_VERSION_STRING) == 0) { SMBDEFAULT_VERSION_STRING) == 0) {
pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
...@@ -1053,7 +1061,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) ...@@ -1053,7 +1061,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID); pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
pneg_inbuf->DialectCount = cpu_to_le16(4); pneg_inbuf->DialectCount = cpu_to_le16(4);
/* structure is big enough for 3 dialects */ /* structure is big enough for 4 dialects */
inbuflen = sizeof(*pneg_inbuf); inbuflen = sizeof(*pneg_inbuf);
} else { } else {
/* otherwise specific dialect was requested */ /* otherwise specific dialect was requested */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment