cifs: break out lanman NEGOTIATE handling into separate function
authorJeff Layton <jlayton@redhat.com>
Sun, 26 May 2013 11:00:57 +0000 (07:00 -0400)
committerSteve French <smfrench@gmail.com>
Mon, 24 Jun 2013 06:56:41 +0000 (01:56 -0500)
...this also gets rid of some #ifdef ugliness too.

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/cifssmb.c

index 9b4aea8..5dd4f8a 100644 (file)
@@ -417,6 +417,96 @@ decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
        return 0;
 }
 
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+static int
+decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
+                         unsigned int secFlags)
+{
+       __s16 tmp;
+       struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
+
+       if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
+               return -EOPNOTSUPP;
+
+       if ((secFlags & CIFSSEC_MAY_LANMAN) || (secFlags & CIFSSEC_MAY_PLNTXT))
+               server->secType = LANMAN;
+       else {
+               cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
+               return -EOPNOTSUPP;
+       }
+       server->sec_mode = le16_to_cpu(rsp->SecurityMode);
+       server->maxReq = min_t(unsigned int,
+                              le16_to_cpu(rsp->MaxMpxCount),
+                              cifs_max_pending);
+       set_credits(server, server->maxReq);
+       server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
+       server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
+       /* even though we do not use raw we might as well set this
+       accurately, in case we ever find a need for it */
+       if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
+               server->max_rw = 0xFF00;
+               server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
+       } else {
+               server->max_rw = 0;/* do not need to use raw anyway */
+               server->capabilities = CAP_MPX_MODE;
+       }
+       tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
+       if (tmp == -1) {
+               /* OS/2 often does not set timezone therefore
+                * we must use server time to calc time zone.
+                * Could deviate slightly from the right zone.
+                * Smallest defined timezone difference is 15 minutes
+                * (i.e. Nepal).  Rounding up/down is done to match
+                * this requirement.
+                */
+               int val, seconds, remain, result;
+               struct timespec ts, utc;
+               utc = CURRENT_TIME;
+               ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
+                                   rsp->SrvTime.Time, 0);
+               cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
+                        (int)ts.tv_sec, (int)utc.tv_sec,
+                        (int)(utc.tv_sec - ts.tv_sec));
+               val = (int)(utc.tv_sec - ts.tv_sec);
+               seconds = abs(val);
+               result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
+               remain = seconds % MIN_TZ_ADJ;
+               if (remain >= (MIN_TZ_ADJ / 2))
+                       result += MIN_TZ_ADJ;
+               if (val < 0)
+                       result = -result;
+               server->timeAdj = result;
+       } else {
+               server->timeAdj = (int)tmp;
+               server->timeAdj *= 60; /* also in seconds */
+       }
+       cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
+
+
+       /* BB get server time for time conversions and add
+       code to use it and timezone since this is not UTC */
+
+       if (rsp->EncryptionKeyLength ==
+                       cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
+               memcpy(server->cryptkey, rsp->EncryptionKey,
+                       CIFS_CRYPTO_KEY_SIZE);
+       } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
+               return -EIO; /* need cryptkey unless plain text */
+       }
+
+       cifs_dbg(FYI, "LANMAN negotiated\n");
+       return 0;
+}
+#else
+static inline int
+decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
+                         unsigned int secFlags)
+{
+       cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
+       return -EOPNOTSUPP;
+}
+#endif
+
 int
 CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
 {
@@ -485,98 +575,19 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
                could not negotiate a common dialect */
                rc = -EOPNOTSUPP;
                goto neg_err_exit;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-       } else if ((pSMBr->hdr.WordCount == 13)
-                       && ((server->dialect == LANMAN_PROT)
-                               || (server->dialect == LANMAN2_PROT))) {
-               __s16 tmp;
-               struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
-
-               if ((secFlags & CIFSSEC_MAY_LANMAN) ||
-                       (secFlags & CIFSSEC_MAY_PLNTXT))
-                       server->secType = LANMAN;
-               else {
-                       cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
-                       rc = -EOPNOTSUPP;
-                       goto neg_err_exit;
-               }
-               server->sec_mode = le16_to_cpu(rsp->SecurityMode);
-               server->maxReq = min_t(unsigned int,
-                                      le16_to_cpu(rsp->MaxMpxCount),
-                                      cifs_max_pending);
-               set_credits(server, server->maxReq);
-               server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
-               server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
-               /* even though we do not use raw we might as well set this
-               accurately, in case we ever find a need for it */
-               if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
-                       server->max_rw = 0xFF00;
-                       server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
-               } else {
-                       server->max_rw = 0;/* do not need to use raw anyway */
-                       server->capabilities = CAP_MPX_MODE;
-               }
-               tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
-               if (tmp == -1) {
-                       /* OS/2 often does not set timezone therefore
-                        * we must use server time to calc time zone.
-                        * Could deviate slightly from the right zone.
-                        * Smallest defined timezone difference is 15 minutes
-                        * (i.e. Nepal).  Rounding up/down is done to match
-                        * this requirement.
-                        */
-                       int val, seconds, remain, result;
-                       struct timespec ts, utc;
-                       utc = CURRENT_TIME;
-                       ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
-                                           rsp->SrvTime.Time, 0);
-                       cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
-                                (int)ts.tv_sec, (int)utc.tv_sec,
-                                (int)(utc.tv_sec - ts.tv_sec));
-                       val = (int)(utc.tv_sec - ts.tv_sec);
-                       seconds = abs(val);
-                       result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
-                       remain = seconds % MIN_TZ_ADJ;
-                       if (remain >= (MIN_TZ_ADJ / 2))
-                               result += MIN_TZ_ADJ;
-                       if (val < 0)
-                               result = -result;
-                       server->timeAdj = result;
-               } else {
-                       server->timeAdj = (int)tmp;
-                       server->timeAdj *= 60; /* also in seconds */
-               }
-               cifs_dbg(FYI, "server->timeAdj: %d seconds\n", server->timeAdj);
-
-
-               /* BB get server time for time conversions and add
-               code to use it and timezone since this is not UTC */
-
-               if (rsp->EncryptionKeyLength ==
-                               cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
-                       memcpy(ses->server->cryptkey, rsp->EncryptionKey,
-                               CIFS_CRYPTO_KEY_SIZE);
-               } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
-                       rc = -EIO; /* need cryptkey unless plain text */
-                       goto neg_err_exit;
-               }
-
-               cifs_dbg(FYI, "LANMAN negotiated\n");
-               /* we will not end up setting signing flags - as no signing
-               was in LANMAN and server did not return the flags on */
-               goto signing_check;
-#else /* weak security disabled */
        } else if (pSMBr->hdr.WordCount == 13) {
-               cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
-               rc = -EOPNOTSUPP;
-#endif /* WEAK_PW_HASH */
-               goto neg_err_exit;
+               rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags);
+               if (!rc)
+                       goto signing_check;
+               else
+                       goto neg_err_exit;
        } else if (pSMBr->hdr.WordCount != 17) {
                /* unknown wct */
                rc = -EOPNOTSUPP;
                goto neg_err_exit;
        }
-       /* else wct == 17 NTLM */
+       /* else wct == 17, NTLM or better */
+
        server->sec_mode = pSMBr->SecurityMode;
        if ((server->sec_mode & SECMODE_USER) == 0)
                cifs_dbg(FYI, "share mode security\n");
@@ -634,9 +645,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
        if (rc)
                goto neg_err_exit;
 
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
 signing_check:
-#endif
        if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
                /* MUST_SIGN already includes the MAY_SIGN FLAG
                   so if this is zero it means that signing is disabled */