]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cifs: break out decoding of security blob into separate function
authorJeff Layton <jlayton@redhat.com>
Sun, 26 May 2013 11:00:57 +0000 (07:00 -0400)
committerSteve French <smfrench@gmail.com>
Sun, 9 Jun 2013 21:52:43 +0000 (16:52 -0500)
...cleanup.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Acked-by: Pavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifspdu.h
fs/cifs/cifssmb.c

index e996ff6b26d1886f63a6c162a09a996e80edf32a..4e6135a39fd178421e82356c258c49471b851db3 100644 (file)
@@ -531,7 +531,7 @@ typedef struct lanman_neg_rsp {
 #define READ_RAW_ENABLE 1
 #define WRITE_RAW_ENABLE 2
 #define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE)
-
+#define SMB1_CLIENT_GUID_SIZE (16)
 typedef struct negotiate_rsp {
        struct smb_hdr hdr;     /* wct = 17 */
        __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */
@@ -553,7 +553,7 @@ typedef struct negotiate_rsp {
                /* followed by 16 bytes of server GUID */
                /* then security blob if cap_extended_security negotiated */
                struct {
-                       unsigned char GUID[16];
+                       unsigned char GUID[SMB1_CLIENT_GUID_SIZE];
                        unsigned char SecurityBlob[1];
                } __attribute__((packed)) extended_response;
        } __attribute__((packed)) u;
index c1c2006376a1743e7956a281359ea8b2965b3989..9b4aea85b15c247ecebf9d0a74b11d1a689e55c6 100644 (file)
@@ -367,6 +367,56 @@ vt2_err:
        return -EINVAL;
 }
 
+static int
+decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
+{
+       int     rc = 0;
+       u16     count;
+       char    *guid = pSMBr->u.extended_response.GUID;
+
+       count = get_bcc(&pSMBr->hdr);
+       if (count < SMB1_CLIENT_GUID_SIZE)
+               return -EIO;
+
+       spin_lock(&cifs_tcp_ses_lock);
+       if (server->srv_count > 1) {
+               spin_unlock(&cifs_tcp_ses_lock);
+               if (memcmp(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE) != 0) {
+                       cifs_dbg(FYI, "server UID changed\n");
+                       memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
+               }
+       } else {
+               spin_unlock(&cifs_tcp_ses_lock);
+               memcpy(server->server_GUID, guid, SMB1_CLIENT_GUID_SIZE);
+       }
+
+       if (count == SMB1_CLIENT_GUID_SIZE) {
+               server->secType = RawNTLMSSP;
+       } else {
+               count -= SMB1_CLIENT_GUID_SIZE;
+               rc = decode_negTokenInit(
+                       pSMBr->u.extended_response.SecurityBlob, count, server);
+               if (rc != 1)
+                       return -EINVAL;
+
+               /* Make sure server supports what we want to use */
+               switch(server->secType) {
+               case Kerberos:
+                       if (!server->sec_kerberos && !server->sec_mskerberos)
+                               return -EOPNOTSUPP;
+                       break;
+               case RawNTLMSSP:
+                       if (!server->sec_ntlmssp)
+                               return -EOPNOTSUPP;
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+               }
+       }
+
+       return 0;
+}
+
 int
 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
 {
@@ -568,61 +618,22 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
        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)
                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)) {
-               /* decode security blob */
-               count = get_bcc(&pSMBr->hdr);
-               if (count < 16) {
-                       rc = -EIO;
-                       goto neg_err_exit;
-               }
-               spin_lock(&cifs_tcp_ses_lock);
-               if (server->srv_count > 1) {
-                       spin_unlock(&cifs_tcp_ses_lock);
-                       if (memcmp(server->server_GUID,
-                                  pSMBr->u.extended_response.
-                                  GUID, 16) != 0) {
-                               cifs_dbg(FYI, "server UID changed\n");
-                               memcpy(server->server_GUID,
-                                       pSMBr->u.extended_response.GUID,
-                                       16);
-                       }
-               } else {
-                       spin_unlock(&cifs_tcp_ses_lock);
-                       memcpy(server->server_GUID,
-                              pSMBr->u.extended_response.GUID, 16);
-               }
-
-               if (count == 16) {
-                       server->secType = RawNTLMSSP;
-               } else {
-                       rc = decode_negTokenInit(pSMBr->u.extended_response.
-                                                SecurityBlob, count - 16,
-                                                server);
-                       if (rc == 1)
-                               rc = 0;
-                       else
-                               rc = -EINVAL;
-                       if (server->secType == Kerberos) {
-                               if (!server->sec_kerberos &&
-                                               !server->sec_mskerberos)
-                                       rc = -EOPNOTSUPP;
-                       } else if (server->secType == RawNTLMSSP) {
-                               if (!server->sec_ntlmssp)
-                                       rc = -EOPNOTSUPP;
-                       } else
-                                       rc = -EOPNOTSUPP;
-               }
-       } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
+                               (pSMBr->EncryptionKeyLength == 0))
+               rc = decode_ext_sec_blob(server, pSMBr);
+       else if (server->sec_mode & SECMODE_PW_ENCRYPT)
                rc = -EIO; /* no crypt key only if plain text pwd */
-               goto neg_err_exit;
-       } else
+       else
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
 
+       if (rc)
+               goto neg_err_exit;
+
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 signing_check:
 #endif