From 9284caed280d6dce063c37170bd06a5b3bbf39b2 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sun, 26 May 2013 07:00:59 -0400 Subject: [PATCH] cifs: track the flavor of the NEGOTIATE reponse Track what sort of NEGOTIATE response we get from the server, as that will govern what sort of authentication types this socket will support. There are three possibilities: LANMAN: server sent legacy LANMAN-type response UNENCAP: server sent a newer-style response, but extended security bit wasn't set. This socket will only support unencapsulated auth types. EXTENDED: server sent a newer-style response with the extended security bit set. This is necessary to support krb5 and ntlmssp auth types. Signed-off-by: Jeff Layton Reviewed-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/cifsglob.h | 4 ++++ fs/cifs/cifssmb.c | 15 ++++++++++----- fs/cifs/smb2pdu.c | 2 ++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 9f8dc3da5f3b..82ba4b974894 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -541,6 +541,10 @@ struct TCP_Server_Info { struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ +#define CIFS_NEGFLAVOR_LANMAN 0 /* wct == 13, LANMAN */ +#define CIFS_NEGFLAVOR_UNENCAP 1 /* wct == 17, but no ext_sec */ +#define CIFS_NEGFLAVOR_EXTENDED 2 /* wct == 17, ext_sec bit set */ + char negflavor; /* NEGOTIATE response flavor */ /* extended security flavors that server supports */ bool sec_ntlmssp; /* supports NTLMSSP */ bool sec_kerberosu2u; /* supports U2U Kerberos */ diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index e63961086752..80ca6886a816 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -615,6 +615,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) rc = -EOPNOTSUPP; goto neg_err_exit; } else if (pSMBr->hdr.WordCount == 13) { + server->negflavor = CIFS_NEGFLAVOR_LANMAN; rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags); goto signing_check; } else if (pSMBr->hdr.WordCount != 17) { @@ -666,17 +667,21 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); server->timeAdj *= 60; - if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) + if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { + server->negflavor = CIFS_NEGFLAVOR_UNENCAP; memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); - else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || + } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC || server->capabilities & CAP_EXTENDED_SECURITY) && - (pSMBr->EncryptionKeyLength == 0)) + (pSMBr->EncryptionKeyLength == 0)) { + server->negflavor = CIFS_NEGFLAVOR_EXTENDED; rc = decode_ext_sec_blob(server, pSMBr); - else if (server->sec_mode & SECMODE_PW_ENCRYPT) + } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { rc = -EIO; /* no crypt key only if plain text pwd */ - else + } else { + server->negflavor = CIFS_NEGFLAVOR_UNENCAP; server->capabilities &= ~CAP_EXTENDED_SECURITY; + } signing_check: if (!rc) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index ebb97b484ab1..1609699e7bec 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -405,6 +405,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) } server->dialect = le16_to_cpu(rsp->DialectRevision); + /* SMB2 only has an extended negflavor */ + server->negflavor = CIFS_NEGFLAVOR_EXTENDED; server->maxBuf = le32_to_cpu(rsp->MaxTransactSize); server->max_read = le32_to_cpu(rsp->MaxReadSize); server->max_write = le32_to_cpu(rsp->MaxWriteSize); -- 2.39.5