Re: [PATCH 08/19] cifs: break out lanman NEGOTIATE handling into separate function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2013/5/23 Jeff Layton <jlayton@xxxxxxxxxx>:
> ...this also gets rid of some #ifdef ugliness too.
>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  fs/cifs/cifssmb.c | 185 ++++++++++++++++++++++++++++--------------------------
>  1 file changed, 97 insertions(+), 88 deletions(-)
>
> diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
> index 9b4aea8..5dd4f8a 100644
> --- a/fs/cifs/cifssmb.c
> +++ b/fs/cifs/cifssmb.c
> @@ -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 */
> --
> 1.8.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Good cleanup. Acked-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>

--
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux