cifs: Correctly set SMB1 SessionKey field in Session Setup Request

[ Upstream commit 89381c72d52094988e11d23ef24a00066a0fa458 ]

[MS-CIFS] specification in section 2.2.4.53.1 where is described
SMB_COM_SESSION_SETUP_ANDX Request, for SessionKey field says:

    The client MUST set this field to be equal to the SessionKey field in
    the SMB_COM_NEGOTIATE Response for this SMB connection.

Linux SMB client currently set this field to zero. This is working fine
against Windows NT SMB servers thanks to [MS-CIFS] product behavior <94>:

    Windows NT Server ignores the client's SessionKey.

For compatibility with [MS-CIFS], set this SessionKey field in Session
Setup Request to value retrieved from Negotiate response.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Pali Rohár
2024-11-02 17:58:31 +01:00
committed by Greg Kroah-Hartman
parent 783cd2c3dc
commit f80fdf48b8
4 changed files with 6 additions and 3 deletions
+1
View File
@@ -739,6 +739,7 @@ struct TCP_Server_Info {
char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
__u32 sequence_number; /* for signing, protected by srv_mutex */ __u32 sequence_number; /* for signing, protected by srv_mutex */
__u32 reconnect_instance; /* incremented on each reconnect */ __u32 reconnect_instance; /* incremented on each reconnect */
__le32 session_key_id; /* retrieved from negotiate response and send in session setup request */
struct session_key session_key; struct session_key session_key;
unsigned long lstrp; /* when we got last response from this server */ unsigned long lstrp; /* when we got last response from this server */
struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
+3 -3
View File
@@ -557,7 +557,7 @@ typedef union smb_com_session_setup_andx {
__le16 MaxBufferSize; __le16 MaxBufferSize;
__le16 MaxMpxCount; __le16 MaxMpxCount;
__le16 VcNumber; __le16 VcNumber;
__u32 SessionKey; __le32 SessionKey;
__le16 SecurityBlobLength; __le16 SecurityBlobLength;
__u32 Reserved; __u32 Reserved;
__le32 Capabilities; /* see below */ __le32 Capabilities; /* see below */
@@ -576,7 +576,7 @@ typedef union smb_com_session_setup_andx {
__le16 MaxBufferSize; __le16 MaxBufferSize;
__le16 MaxMpxCount; __le16 MaxMpxCount;
__le16 VcNumber; __le16 VcNumber;
__u32 SessionKey; __le32 SessionKey;
__le16 CaseInsensitivePasswordLength; /* ASCII password len */ __le16 CaseInsensitivePasswordLength; /* ASCII password len */
__le16 CaseSensitivePasswordLength; /* Unicode password length*/ __le16 CaseSensitivePasswordLength; /* Unicode password length*/
__u32 Reserved; /* see below */ __u32 Reserved; /* see below */
@@ -614,7 +614,7 @@ typedef union smb_com_session_setup_andx {
__le16 MaxBufferSize; __le16 MaxBufferSize;
__le16 MaxMpxCount; __le16 MaxMpxCount;
__le16 VcNumber; __le16 VcNumber;
__u32 SessionKey; __le32 SessionKey;
__le16 PasswordLength; __le16 PasswordLength;
__u32 Reserved; /* encrypt key len and offset */ __u32 Reserved; /* encrypt key len and offset */
__le16 ByteCount; __le16 ByteCount;
+1
View File
@@ -481,6 +481,7 @@ CIFSSMBNegotiate(const unsigned int xid,
server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf); cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf);
server->capabilities = le32_to_cpu(pSMBr->Capabilities); server->capabilities = le32_to_cpu(pSMBr->Capabilities);
server->session_key_id = pSMBr->SessionKey;
server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
server->timeAdj *= 60; server->timeAdj *= 60;
+1
View File
@@ -658,6 +658,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
USHRT_MAX)); USHRT_MAX));
pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq); pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
pSMB->req.VcNumber = cpu_to_le16(1); pSMB->req.VcNumber = cpu_to_le16(1);
pSMB->req.SessionKey = server->session_key_id;
/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */ /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */