linux/fs/cifs/sess.c
<<
>>
Prefs
   1/*
   2 *   fs/cifs/sess.c
   3 *
   4 *   SMB/CIFS session setup handling routines
   5 *
   6 *   Copyright (c) International Business Machines  Corp., 2006, 2009
   7 *   Author(s): Steve French (sfrench@us.ibm.com)
   8 *
   9 *   This library is free software; you can redistribute it and/or modify
  10 *   it under the terms of the GNU Lesser General Public License as published
  11 *   by the Free Software Foundation; either version 2.1 of the License, or
  12 *   (at your option) any later version.
  13 *
  14 *   This library is distributed in the hope that it will be useful,
  15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  17 *   the GNU Lesser General Public License for more details.
  18 *
  19 *   You should have received a copy of the GNU Lesser General Public License
  20 *   along with this library; if not, write to the Free Software
  21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23
  24#include "cifspdu.h"
  25#include "cifsglob.h"
  26#include "cifsproto.h"
  27#include "cifs_unicode.h"
  28#include "cifs_debug.h"
  29#include "ntlmssp.h"
  30#include "nterr.h"
  31#include <linux/utsname.h>
  32#include <linux/slab.h>
  33#include "cifs_spnego.h"
  34
  35static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
  36{
  37        __u32 capabilities = 0;
  38
  39        /* init fields common to all four types of SessSetup */
  40        /* Note that offsets for first seven fields in req struct are same  */
  41        /*      in CIFS Specs so does not matter which of 3 forms of struct */
  42        /*      that we use in next few lines                               */
  43        /* Note that header is initialized to zero in header_assemble */
  44        pSMB->req.AndXCommand = 0xFF;
  45        pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
  46                                        CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
  47                                        USHRT_MAX));
  48        pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
  49        pSMB->req.VcNumber = cpu_to_le16(1);
  50
  51        /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
  52
  53        /* BB verify whether signing required on neg or just on auth frame
  54           (and NTLM case) */
  55
  56        capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
  57                        CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
  58
  59        if (ses->server->sign)
  60                pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
  61
  62        if (ses->capabilities & CAP_UNICODE) {
  63                pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
  64                capabilities |= CAP_UNICODE;
  65        }
  66        if (ses->capabilities & CAP_STATUS32) {
  67                pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
  68                capabilities |= CAP_STATUS32;
  69        }
  70        if (ses->capabilities & CAP_DFS) {
  71                pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
  72                capabilities |= CAP_DFS;
  73        }
  74        if (ses->capabilities & CAP_UNIX)
  75                capabilities |= CAP_UNIX;
  76
  77        return capabilities;
  78}
  79
  80static void
  81unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
  82{
  83        char *bcc_ptr = *pbcc_area;
  84        int bytes_ret = 0;
  85
  86        /* Copy OS version */
  87        bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
  88                                    nls_cp);
  89        bcc_ptr += 2 * bytes_ret;
  90        bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
  91                                    32, nls_cp);
  92        bcc_ptr += 2 * bytes_ret;
  93        bcc_ptr += 2; /* trailing null */
  94
  95        bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
  96                                    32, nls_cp);
  97        bcc_ptr += 2 * bytes_ret;
  98        bcc_ptr += 2; /* trailing null */
  99
 100        *pbcc_area = bcc_ptr;
 101}
 102
 103static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
 104                                   const struct nls_table *nls_cp)
 105{
 106        char *bcc_ptr = *pbcc_area;
 107        int bytes_ret = 0;
 108
 109        /* copy domain */
 110        if (ses->domainName == NULL) {
 111                /* Sending null domain better than using a bogus domain name (as
 112                we did briefly in 2.6.18) since server will use its default */
 113                *bcc_ptr = 0;
 114                *(bcc_ptr+1) = 0;
 115                bytes_ret = 0;
 116        } else
 117                bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
 118                                            CIFS_MAX_DOMAINNAME_LEN, nls_cp);
 119        bcc_ptr += 2 * bytes_ret;
 120        bcc_ptr += 2;  /* account for null terminator */
 121
 122        *pbcc_area = bcc_ptr;
 123}
 124
 125
 126static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
 127                                   const struct nls_table *nls_cp)
 128{
 129        char *bcc_ptr = *pbcc_area;
 130        int bytes_ret = 0;
 131
 132        /* BB FIXME add check that strings total less
 133        than 335 or will need to send them as arrays */
 134
 135        /* unicode strings, must be word aligned before the call */
 136/*      if ((long) bcc_ptr % 2) {
 137                *bcc_ptr = 0;
 138                bcc_ptr++;
 139        } */
 140        /* copy user */
 141        if (ses->user_name == NULL) {
 142                /* null user mount */
 143                *bcc_ptr = 0;
 144                *(bcc_ptr+1) = 0;
 145        } else {
 146                bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
 147                                            CIFS_MAX_USERNAME_LEN, nls_cp);
 148        }
 149        bcc_ptr += 2 * bytes_ret;
 150        bcc_ptr += 2; /* account for null termination */
 151
 152        unicode_domain_string(&bcc_ptr, ses, nls_cp);
 153        unicode_oslm_strings(&bcc_ptr, nls_cp);
 154
 155        *pbcc_area = bcc_ptr;
 156}
 157
 158static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
 159                                 const struct nls_table *nls_cp)
 160{
 161        char *bcc_ptr = *pbcc_area;
 162        int len;
 163
 164        /* copy user */
 165        /* BB what about null user mounts - check that we do this BB */
 166        /* copy user */
 167        if (ses->user_name != NULL) {
 168                len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
 169                if (WARN_ON_ONCE(len < 0))
 170                        len = CIFS_MAX_USERNAME_LEN - 1;
 171                bcc_ptr += len;
 172        }
 173        /* else null user mount */
 174        *bcc_ptr = 0;
 175        bcc_ptr++; /* account for null termination */
 176
 177        /* copy domain */
 178        if (ses->domainName != NULL) {
 179                len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
 180                if (WARN_ON_ONCE(len < 0))
 181                        len = CIFS_MAX_DOMAINNAME_LEN - 1;
 182                bcc_ptr += len;
 183        } /* else we will send a null domain name
 184             so the server will default to its own domain */
 185        *bcc_ptr = 0;
 186        bcc_ptr++;
 187
 188        /* BB check for overflow here */
 189
 190        strcpy(bcc_ptr, "Linux version ");
 191        bcc_ptr += strlen("Linux version ");
 192        strcpy(bcc_ptr, init_utsname()->release);
 193        bcc_ptr += strlen(init_utsname()->release) + 1;
 194
 195        strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
 196        bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
 197
 198        *pbcc_area = bcc_ptr;
 199}
 200
 201static void
 202decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
 203                      const struct nls_table *nls_cp)
 204{
 205        int len;
 206        char *data = *pbcc_area;
 207
 208        cifs_dbg(FYI, "bleft %d\n", bleft);
 209
 210        kfree(ses->serverOS);
 211        ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 212        cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
 213        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
 214        data += len;
 215        bleft -= len;
 216        if (bleft <= 0)
 217                return;
 218
 219        kfree(ses->serverNOS);
 220        ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 221        cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
 222        len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
 223        data += len;
 224        bleft -= len;
 225        if (bleft <= 0)
 226                return;
 227
 228        kfree(ses->serverDomain);
 229        ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
 230        cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
 231
 232        return;
 233}
 234
 235static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
 236                                struct cifs_ses *ses,
 237                                const struct nls_table *nls_cp)
 238{
 239        int len;
 240        char *bcc_ptr = *pbcc_area;
 241
 242        cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
 243
 244        len = strnlen(bcc_ptr, bleft);
 245        if (len >= bleft)
 246                return;
 247
 248        kfree(ses->serverOS);
 249
 250        ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
 251        if (ses->serverOS) {
 252                memcpy(ses->serverOS, bcc_ptr, len);
 253                ses->serverOS[len] = 0;
 254                if (strncmp(ses->serverOS, "OS/2", 4) == 0)
 255                        cifs_dbg(FYI, "OS/2 server\n");
 256        }
 257
 258        bcc_ptr += len + 1;
 259        bleft -= len + 1;
 260
 261        len = strnlen(bcc_ptr, bleft);
 262        if (len >= bleft)
 263                return;
 264
 265        kfree(ses->serverNOS);
 266
 267        ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
 268        if (ses->serverNOS) {
 269                memcpy(ses->serverNOS, bcc_ptr, len);
 270                ses->serverNOS[len] = 0;
 271        }
 272
 273        bcc_ptr += len + 1;
 274        bleft -= len + 1;
 275
 276        len = strnlen(bcc_ptr, bleft);
 277        if (len > bleft)
 278                return;
 279
 280        /* No domain field in LANMAN case. Domain is
 281           returned by old servers in the SMB negprot response */
 282        /* BB For newer servers which do not support Unicode,
 283           but thus do return domain here we could add parsing
 284           for it later, but it is not very important */
 285        cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
 286}
 287
 288int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
 289                                    struct cifs_ses *ses)
 290{
 291        unsigned int tioffset; /* challenge message target info area */
 292        unsigned int tilen; /* challenge message target info area length  */
 293
 294        CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
 295
 296        if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
 297                cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
 298                return -EINVAL;
 299        }
 300
 301        if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
 302                cifs_dbg(VFS, "blob signature incorrect %s\n",
 303                         pblob->Signature);
 304                return -EINVAL;
 305        }
 306        if (pblob->MessageType != NtLmChallenge) {
 307                cifs_dbg(VFS, "Incorrect message type %d\n",
 308                         pblob->MessageType);
 309                return -EINVAL;
 310        }
 311
 312        memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
 313        /* BB we could decode pblob->NegotiateFlags; some may be useful */
 314        /* In particular we can examine sign flags */
 315        /* BB spec says that if AvId field of MsvAvTimestamp is populated then
 316                we must set the MIC field of the AUTHENTICATE_MESSAGE */
 317        ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
 318        tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
 319        tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
 320        if (tioffset > blob_len || tioffset + tilen > blob_len) {
 321                cifs_dbg(VFS, "tioffset + tilen too high %u + %u",
 322                        tioffset, tilen);
 323                return -EINVAL;
 324        }
 325        if (tilen) {
 326                ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
 327                                                 GFP_KERNEL);
 328                if (!ses->auth_key.response) {
 329                        cifs_dbg(VFS, "Challenge target info alloc failure");
 330                        return -ENOMEM;
 331                }
 332                ses->auth_key.len = tilen;
 333        }
 334
 335        return 0;
 336}
 337
 338/* BB Move to ntlmssp.c eventually */
 339
 340/* We do not malloc the blob, it is passed in pbuffer, because
 341   it is fixed size, and small, making this approach cleaner */
 342void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
 343                                         struct cifs_ses *ses)
 344{
 345        NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
 346        __u32 flags;
 347
 348        memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
 349        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 350        sec_blob->MessageType = NtLmNegotiate;
 351
 352        /* BB is NTLMV2 session security format easier to use here? */
 353        flags = NTLMSSP_NEGOTIATE_56 |  NTLMSSP_REQUEST_TARGET |
 354                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 355                NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
 356                NTLMSSP_NEGOTIATE_SEAL;
 357        if (ses->server->sign)
 358                flags |= NTLMSSP_NEGOTIATE_SIGN;
 359        if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
 360                flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 361
 362        sec_blob->NegotiateFlags = cpu_to_le32(flags);
 363
 364        sec_blob->WorkstationName.BufferOffset = 0;
 365        sec_blob->WorkstationName.Length = 0;
 366        sec_blob->WorkstationName.MaximumLength = 0;
 367
 368        /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
 369        sec_blob->DomainName.BufferOffset = 0;
 370        sec_blob->DomainName.Length = 0;
 371        sec_blob->DomainName.MaximumLength = 0;
 372}
 373
 374static int size_of_ntlmssp_blob(struct cifs_ses *ses)
 375{
 376        int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
 377                - CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
 378
 379        if (ses->domainName)
 380                sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
 381        else
 382                sz += 2;
 383
 384        if (ses->user_name)
 385                sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
 386        else
 387                sz += 2;
 388
 389        return sz;
 390}
 391
 392int build_ntlmssp_auth_blob(unsigned char **pbuffer,
 393                                        u16 *buflen,
 394                                   struct cifs_ses *ses,
 395                                   const struct nls_table *nls_cp)
 396{
 397        int rc;
 398        AUTHENTICATE_MESSAGE *sec_blob;
 399        __u32 flags;
 400        unsigned char *tmp;
 401
 402        rc = setup_ntlmv2_rsp(ses, nls_cp);
 403        if (rc) {
 404                cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
 405                *buflen = 0;
 406                goto setup_ntlmv2_ret;
 407        }
 408        *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
 409        if (!*pbuffer) {
 410                rc = -ENOMEM;
 411                cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
 412                *buflen = 0;
 413                goto setup_ntlmv2_ret;
 414        }
 415        sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
 416
 417        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
 418        sec_blob->MessageType = NtLmAuthenticate;
 419
 420        flags = NTLMSSP_NEGOTIATE_56 |
 421                NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
 422                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
 423                NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
 424                NTLMSSP_NEGOTIATE_SEAL;
 425        if (ses->server->sign)
 426                flags |= NTLMSSP_NEGOTIATE_SIGN;
 427        if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
 428                flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
 429
 430        tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
 431        sec_blob->NegotiateFlags = cpu_to_le32(flags);
 432
 433        sec_blob->LmChallengeResponse.BufferOffset =
 434                                cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
 435        sec_blob->LmChallengeResponse.Length = 0;
 436        sec_blob->LmChallengeResponse.MaximumLength = 0;
 437
 438        sec_blob->NtChallengeResponse.BufferOffset =
 439                                cpu_to_le32(tmp - *pbuffer);
 440        if (ses->user_name != NULL) {
 441                memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
 442                                ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 443                tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
 444
 445                sec_blob->NtChallengeResponse.Length =
 446                                cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 447                sec_blob->NtChallengeResponse.MaximumLength =
 448                                cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 449        } else {
 450                /*
 451                 * don't send an NT Response for anonymous access
 452                 */
 453                sec_blob->NtChallengeResponse.Length = 0;
 454                sec_blob->NtChallengeResponse.MaximumLength = 0;
 455        }
 456
 457        if (ses->domainName == NULL) {
 458                sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 459                sec_blob->DomainName.Length = 0;
 460                sec_blob->DomainName.MaximumLength = 0;
 461                tmp += 2;
 462        } else {
 463                int len;
 464                len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
 465                                      CIFS_MAX_DOMAINNAME_LEN, nls_cp);
 466                len *= 2; /* unicode is 2 bytes each */
 467                sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 468                sec_blob->DomainName.Length = cpu_to_le16(len);
 469                sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
 470                tmp += len;
 471        }
 472
 473        if (ses->user_name == NULL) {
 474                sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 475                sec_blob->UserName.Length = 0;
 476                sec_blob->UserName.MaximumLength = 0;
 477                tmp += 2;
 478        } else {
 479                int len;
 480                len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
 481                                      CIFS_MAX_USERNAME_LEN, nls_cp);
 482                len *= 2; /* unicode is 2 bytes each */
 483                sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 484                sec_blob->UserName.Length = cpu_to_le16(len);
 485                sec_blob->UserName.MaximumLength = cpu_to_le16(len);
 486                tmp += len;
 487        }
 488
 489        sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 490        sec_blob->WorkstationName.Length = 0;
 491        sec_blob->WorkstationName.MaximumLength = 0;
 492        tmp += 2;
 493
 494        if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
 495                (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
 496                        && !calc_seckey(ses)) {
 497                memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
 498                sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 499                sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
 500                sec_blob->SessionKey.MaximumLength =
 501                                cpu_to_le16(CIFS_CPHTXT_SIZE);
 502                tmp += CIFS_CPHTXT_SIZE;
 503        } else {
 504                sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
 505                sec_blob->SessionKey.Length = 0;
 506                sec_blob->SessionKey.MaximumLength = 0;
 507        }
 508
 509        *buflen = tmp - *pbuffer;
 510setup_ntlmv2_ret:
 511        return rc;
 512}
 513
 514enum securityEnum
 515cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
 516{
 517        switch (server->negflavor) {
 518        case CIFS_NEGFLAVOR_EXTENDED:
 519                switch (requested) {
 520                case Kerberos:
 521                case RawNTLMSSP:
 522                        return requested;
 523                case Unspecified:
 524                        if (server->sec_ntlmssp &&
 525                            (global_secflags & CIFSSEC_MAY_NTLMSSP))
 526                                return RawNTLMSSP;
 527                        if ((server->sec_kerberos || server->sec_mskerberos) &&
 528                            (global_secflags & CIFSSEC_MAY_KRB5))
 529                                return Kerberos;
 530                        /* Fallthrough */
 531                default:
 532                        return Unspecified;
 533                }
 534        case CIFS_NEGFLAVOR_UNENCAP:
 535                switch (requested) {
 536                case NTLM:
 537                case NTLMv2:
 538                        return requested;
 539                case Unspecified:
 540                        if (global_secflags & CIFSSEC_MAY_NTLMV2)
 541                                return NTLMv2;
 542                        if (global_secflags & CIFSSEC_MAY_NTLM)
 543                                return NTLM;
 544                default:
 545                        break;
 546                }
 547                /* Fallthrough - to attempt LANMAN authentication next */
 548        case CIFS_NEGFLAVOR_LANMAN:
 549                switch (requested) {
 550                case LANMAN:
 551                        return requested;
 552                case Unspecified:
 553                        if (global_secflags & CIFSSEC_MAY_LANMAN)
 554                                return LANMAN;
 555                        /* Fallthrough */
 556                default:
 557                        return Unspecified;
 558                }
 559        default:
 560                return Unspecified;
 561        }
 562}
 563
 564struct sess_data {
 565        unsigned int xid;
 566        struct cifs_ses *ses;
 567        struct nls_table *nls_cp;
 568        void (*func)(struct sess_data *);
 569        int result;
 570
 571        /* we will send the SMB in three pieces:
 572         * a fixed length beginning part, an optional
 573         * SPNEGO blob (which can be zero length), and a
 574         * last part which will include the strings
 575         * and rest of bcc area. This allows us to avoid
 576         * a large buffer 17K allocation
 577         */
 578        int buf0_type;
 579        struct kvec iov[3];
 580};
 581
 582static int
 583sess_alloc_buffer(struct sess_data *sess_data, int wct)
 584{
 585        int rc;
 586        struct cifs_ses *ses = sess_data->ses;
 587        struct smb_hdr *smb_buf;
 588
 589        rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
 590                                  (void **)&smb_buf);
 591
 592        if (rc)
 593                return rc;
 594
 595        sess_data->iov[0].iov_base = (char *)smb_buf;
 596        sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
 597        /*
 598         * This variable will be used to clear the buffer
 599         * allocated above in case of any error in the calling function.
 600         */
 601        sess_data->buf0_type = CIFS_SMALL_BUFFER;
 602
 603        /* 2000 big enough to fit max user, domain, NOS name etc. */
 604        sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
 605        if (!sess_data->iov[2].iov_base) {
 606                rc = -ENOMEM;
 607                goto out_free_smb_buf;
 608        }
 609
 610        return 0;
 611
 612out_free_smb_buf:
 613        kfree(smb_buf);
 614        sess_data->iov[0].iov_base = NULL;
 615        sess_data->iov[0].iov_len = 0;
 616        sess_data->buf0_type = CIFS_NO_BUFFER;
 617        return rc;
 618}
 619
 620static void
 621sess_free_buffer(struct sess_data *sess_data)
 622{
 623
 624        free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
 625        sess_data->buf0_type = CIFS_NO_BUFFER;
 626        kfree(sess_data->iov[2].iov_base);
 627}
 628
 629static int
 630sess_establish_session(struct sess_data *sess_data)
 631{
 632        struct cifs_ses *ses = sess_data->ses;
 633
 634        mutex_lock(&ses->server->srv_mutex);
 635        if (!ses->server->session_estab) {
 636                if (ses->server->sign) {
 637                        ses->server->session_key.response =
 638                                kmemdup(ses->auth_key.response,
 639                                ses->auth_key.len, GFP_KERNEL);
 640                        if (!ses->server->session_key.response) {
 641                                mutex_unlock(&ses->server->srv_mutex);
 642                                return -ENOMEM;
 643                        }
 644                        ses->server->session_key.len =
 645                                                ses->auth_key.len;
 646                }
 647                ses->server->sequence_number = 0x2;
 648                ses->server->session_estab = true;
 649        }
 650        mutex_unlock(&ses->server->srv_mutex);
 651
 652        cifs_dbg(FYI, "CIFS session established successfully\n");
 653        spin_lock(&GlobalMid_Lock);
 654        ses->status = CifsGood;
 655        ses->need_reconnect = false;
 656        spin_unlock(&GlobalMid_Lock);
 657
 658        return 0;
 659}
 660
 661static int
 662sess_sendreceive(struct sess_data *sess_data)
 663{
 664        int rc;
 665        struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
 666        __u16 count;
 667        struct kvec rsp_iov = { NULL, 0 };
 668
 669        count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
 670        smb_buf->smb_buf_length =
 671                cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
 672        put_bcc(count, smb_buf);
 673
 674        rc = SendReceive2(sess_data->xid, sess_data->ses,
 675                          sess_data->iov, 3 /* num_iovecs */,
 676                          &sess_data->buf0_type,
 677                          CIFS_LOG_ERROR, &rsp_iov);
 678        cifs_small_buf_release(sess_data->iov[0].iov_base);
 679        memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
 680
 681        return rc;
 682}
 683
 684/*
 685 * LANMAN and plaintext are less secure and off by default.
 686 * So we make this explicitly be turned on in kconfig (in the
 687 * build) and turned on at runtime (changed from the default)
 688 * in proc/fs/cifs or via mount parm.  Unfortunately this is
 689 * needed for old Win (e.g. Win95), some obscure NAS and OS/2
 690 */
 691#ifdef CONFIG_CIFS_WEAK_PW_HASH
 692static void
 693sess_auth_lanman(struct sess_data *sess_data)
 694{
 695        int rc = 0;
 696        struct smb_hdr *smb_buf;
 697        SESSION_SETUP_ANDX *pSMB;
 698        char *bcc_ptr;
 699        struct cifs_ses *ses = sess_data->ses;
 700        char lnm_session_key[CIFS_AUTH_RESP_SIZE];
 701        __u16 bytes_remaining;
 702
 703        /* lanman 2 style sessionsetup */
 704        /* wct = 10 */
 705        rc = sess_alloc_buffer(sess_data, 10);
 706        if (rc)
 707                goto out;
 708
 709        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 710        bcc_ptr = sess_data->iov[2].iov_base;
 711        (void)cifs_ssetup_hdr(ses, pSMB);
 712
 713        pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
 714
 715        if (ses->user_name != NULL) {
 716                /* no capabilities flags in old lanman negotiation */
 717                pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
 718
 719                /* Calculate hash with password and copy into bcc_ptr.
 720                 * Encryption Key (stored as in cryptkey) gets used if the
 721                 * security mode bit in Negottiate Protocol response states
 722                 * to use challenge/response method (i.e. Password bit is 1).
 723                 */
 724                rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
 725                                      ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
 726                                      true : false, lnm_session_key);
 727                if (rc)
 728                        goto out;
 729
 730                memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
 731                bcc_ptr += CIFS_AUTH_RESP_SIZE;
 732        } else {
 733                pSMB->old_req.PasswordLength = 0;
 734        }
 735
 736        /*
 737         * can not sign if LANMAN negotiated so no need
 738         * to calculate signing key? but what if server
 739         * changed to do higher than lanman dialect and
 740         * we reconnected would we ever calc signing_key?
 741         */
 742
 743        cifs_dbg(FYI, "Negotiating LANMAN setting up strings\n");
 744        /* Unicode not allowed for LANMAN dialects */
 745        ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
 746
 747        sess_data->iov[2].iov_len = (long) bcc_ptr -
 748                        (long) sess_data->iov[2].iov_base;
 749
 750        rc = sess_sendreceive(sess_data);
 751        if (rc)
 752                goto out;
 753
 754        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 755        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 756
 757        /* lanman response has a word count of 3 */
 758        if (smb_buf->WordCount != 3) {
 759                rc = -EIO;
 760                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 761                goto out;
 762        }
 763
 764        if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
 765                cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
 766
 767        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
 768        cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
 769
 770        bytes_remaining = get_bcc(smb_buf);
 771        bcc_ptr = pByteArea(smb_buf);
 772
 773        /* BB check if Unicode and decode strings */
 774        if (bytes_remaining == 0) {
 775                /* no string area to decode, do nothing */
 776        } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
 777                /* unicode string area must be word-aligned */
 778                if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
 779                        ++bcc_ptr;
 780                        --bytes_remaining;
 781                }
 782                decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
 783                                      sess_data->nls_cp);
 784        } else {
 785                decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
 786                                    sess_data->nls_cp);
 787        }
 788
 789        rc = sess_establish_session(sess_data);
 790out:
 791        sess_data->result = rc;
 792        sess_data->func = NULL;
 793        sess_free_buffer(sess_data);
 794}
 795
 796#endif
 797
 798static void
 799sess_auth_ntlm(struct sess_data *sess_data)
 800{
 801        int rc = 0;
 802        struct smb_hdr *smb_buf;
 803        SESSION_SETUP_ANDX *pSMB;
 804        char *bcc_ptr;
 805        struct cifs_ses *ses = sess_data->ses;
 806        __u32 capabilities;
 807        __u16 bytes_remaining;
 808
 809        /* old style NTLM sessionsetup */
 810        /* wct = 13 */
 811        rc = sess_alloc_buffer(sess_data, 13);
 812        if (rc)
 813                goto out;
 814
 815        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 816        bcc_ptr = sess_data->iov[2].iov_base;
 817        capabilities = cifs_ssetup_hdr(ses, pSMB);
 818
 819        pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
 820        if (ses->user_name != NULL) {
 821                pSMB->req_no_secext.CaseInsensitivePasswordLength =
 822                                cpu_to_le16(CIFS_AUTH_RESP_SIZE);
 823                pSMB->req_no_secext.CaseSensitivePasswordLength =
 824                                cpu_to_le16(CIFS_AUTH_RESP_SIZE);
 825
 826                /* calculate ntlm response and session key */
 827                rc = setup_ntlm_response(ses, sess_data->nls_cp);
 828                if (rc) {
 829                        cifs_dbg(VFS, "Error %d during NTLM authentication\n",
 830                                         rc);
 831                        goto out;
 832                }
 833
 834                /* copy ntlm response */
 835                memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
 836                                CIFS_AUTH_RESP_SIZE);
 837                bcc_ptr += CIFS_AUTH_RESP_SIZE;
 838                memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
 839                                CIFS_AUTH_RESP_SIZE);
 840                bcc_ptr += CIFS_AUTH_RESP_SIZE;
 841        } else {
 842                pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
 843                pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
 844        }
 845
 846        if (ses->capabilities & CAP_UNICODE) {
 847                /* unicode strings must be word aligned */
 848                if (sess_data->iov[0].iov_len % 2) {
 849                        *bcc_ptr = 0;
 850                        bcc_ptr++;
 851                }
 852                unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
 853        } else {
 854                ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
 855        }
 856
 857
 858        sess_data->iov[2].iov_len = (long) bcc_ptr -
 859                        (long) sess_data->iov[2].iov_base;
 860
 861        rc = sess_sendreceive(sess_data);
 862        if (rc)
 863                goto out;
 864
 865        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 866        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 867
 868        if (smb_buf->WordCount != 3) {
 869                rc = -EIO;
 870                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 871                goto out;
 872        }
 873
 874        if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
 875                cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
 876
 877        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
 878        cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
 879
 880        bytes_remaining = get_bcc(smb_buf);
 881        bcc_ptr = pByteArea(smb_buf);
 882
 883        /* BB check if Unicode and decode strings */
 884        if (bytes_remaining == 0) {
 885                /* no string area to decode, do nothing */
 886        } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
 887                /* unicode string area must be word-aligned */
 888                if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
 889                        ++bcc_ptr;
 890                        --bytes_remaining;
 891                }
 892                decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
 893                                      sess_data->nls_cp);
 894        } else {
 895                decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
 896                                    sess_data->nls_cp);
 897        }
 898
 899        rc = sess_establish_session(sess_data);
 900out:
 901        sess_data->result = rc;
 902        sess_data->func = NULL;
 903        sess_free_buffer(sess_data);
 904        kfree(ses->auth_key.response);
 905        ses->auth_key.response = NULL;
 906}
 907
 908static void
 909sess_auth_ntlmv2(struct sess_data *sess_data)
 910{
 911        int rc = 0;
 912        struct smb_hdr *smb_buf;
 913        SESSION_SETUP_ANDX *pSMB;
 914        char *bcc_ptr;
 915        struct cifs_ses *ses = sess_data->ses;
 916        __u32 capabilities;
 917        __u16 bytes_remaining;
 918
 919        /* old style NTLM sessionsetup */
 920        /* wct = 13 */
 921        rc = sess_alloc_buffer(sess_data, 13);
 922        if (rc)
 923                goto out;
 924
 925        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 926        bcc_ptr = sess_data->iov[2].iov_base;
 927        capabilities = cifs_ssetup_hdr(ses, pSMB);
 928
 929        pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
 930
 931        /* LM2 password would be here if we supported it */
 932        pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
 933
 934        if (ses->user_name != NULL) {
 935                /* calculate nlmv2 response and session key */
 936                rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
 937                if (rc) {
 938                        cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
 939                        goto out;
 940                }
 941
 942                memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
 943                                ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 944                bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
 945
 946                /* set case sensitive password length after tilen may get
 947                 * assigned, tilen is 0 otherwise.
 948                 */
 949                pSMB->req_no_secext.CaseSensitivePasswordLength =
 950                        cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
 951        } else {
 952                pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
 953        }
 954
 955        if (ses->capabilities & CAP_UNICODE) {
 956                if (sess_data->iov[0].iov_len % 2) {
 957                        *bcc_ptr = 0;
 958                        bcc_ptr++;
 959                }
 960                unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
 961        } else {
 962                ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
 963        }
 964
 965
 966        sess_data->iov[2].iov_len = (long) bcc_ptr -
 967                        (long) sess_data->iov[2].iov_base;
 968
 969        rc = sess_sendreceive(sess_data);
 970        if (rc)
 971                goto out;
 972
 973        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
 974        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 975
 976        if (smb_buf->WordCount != 3) {
 977                rc = -EIO;
 978                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
 979                goto out;
 980        }
 981
 982        if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
 983                cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
 984
 985        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
 986        cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
 987
 988        bytes_remaining = get_bcc(smb_buf);
 989        bcc_ptr = pByteArea(smb_buf);
 990
 991        /* BB check if Unicode and decode strings */
 992        if (bytes_remaining == 0) {
 993                /* no string area to decode, do nothing */
 994        } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
 995                /* unicode string area must be word-aligned */
 996                if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
 997                        ++bcc_ptr;
 998                        --bytes_remaining;
 999                }
1000                decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1001                                      sess_data->nls_cp);
1002        } else {
1003                decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1004                                    sess_data->nls_cp);
1005        }
1006
1007        rc = sess_establish_session(sess_data);
1008out:
1009        sess_data->result = rc;
1010        sess_data->func = NULL;
1011        sess_free_buffer(sess_data);
1012        kfree(ses->auth_key.response);
1013        ses->auth_key.response = NULL;
1014}
1015
1016#ifdef CONFIG_CIFS_UPCALL
1017static void
1018sess_auth_kerberos(struct sess_data *sess_data)
1019{
1020        int rc = 0;
1021        struct smb_hdr *smb_buf;
1022        SESSION_SETUP_ANDX *pSMB;
1023        char *bcc_ptr;
1024        struct cifs_ses *ses = sess_data->ses;
1025        __u32 capabilities;
1026        __u16 bytes_remaining;
1027        struct key *spnego_key = NULL;
1028        struct cifs_spnego_msg *msg;
1029        u16 blob_len;
1030
1031        /* extended security */
1032        /* wct = 12 */
1033        rc = sess_alloc_buffer(sess_data, 12);
1034        if (rc)
1035                goto out;
1036
1037        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1038        bcc_ptr = sess_data->iov[2].iov_base;
1039        capabilities = cifs_ssetup_hdr(ses, pSMB);
1040
1041        spnego_key = cifs_get_spnego_key(ses);
1042        if (IS_ERR(spnego_key)) {
1043                rc = PTR_ERR(spnego_key);
1044                spnego_key = NULL;
1045                goto out;
1046        }
1047
1048        msg = spnego_key->payload.data[0];
1049        /*
1050         * check version field to make sure that cifs.upcall is
1051         * sending us a response in an expected form
1052         */
1053        if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1054                cifs_dbg(VFS,
1055                  "incorrect version of cifs.upcall (expected %d but got %d)",
1056                              CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1057                rc = -EKEYREJECTED;
1058                goto out_put_spnego_key;
1059        }
1060
1061        ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1062                                         GFP_KERNEL);
1063        if (!ses->auth_key.response) {
1064                cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory",
1065                                msg->sesskey_len);
1066                rc = -ENOMEM;
1067                goto out_put_spnego_key;
1068        }
1069        ses->auth_key.len = msg->sesskey_len;
1070
1071        pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1072        capabilities |= CAP_EXTENDED_SECURITY;
1073        pSMB->req.Capabilities = cpu_to_le32(capabilities);
1074        sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1075        sess_data->iov[1].iov_len = msg->secblob_len;
1076        pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
1077
1078        if (ses->capabilities & CAP_UNICODE) {
1079                /* unicode strings must be word aligned */
1080                if ((sess_data->iov[0].iov_len
1081                        + sess_data->iov[1].iov_len) % 2) {
1082                        *bcc_ptr = 0;
1083                        bcc_ptr++;
1084                }
1085                unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1086                unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
1087        } else {
1088                /* BB: is this right? */
1089                ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1090        }
1091
1092        sess_data->iov[2].iov_len = (long) bcc_ptr -
1093                        (long) sess_data->iov[2].iov_base;
1094
1095        rc = sess_sendreceive(sess_data);
1096        if (rc)
1097                goto out_put_spnego_key;
1098
1099        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1100        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1101
1102        if (smb_buf->WordCount != 4) {
1103                rc = -EIO;
1104                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1105                goto out_put_spnego_key;
1106        }
1107
1108        if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1109                cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1110
1111        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1112        cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1113
1114        bytes_remaining = get_bcc(smb_buf);
1115        bcc_ptr = pByteArea(smb_buf);
1116
1117        blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1118        if (blob_len > bytes_remaining) {
1119                cifs_dbg(VFS, "bad security blob length %d\n",
1120                                blob_len);
1121                rc = -EINVAL;
1122                goto out_put_spnego_key;
1123        }
1124        bcc_ptr += blob_len;
1125        bytes_remaining -= blob_len;
1126
1127        /* BB check if Unicode and decode strings */
1128        if (bytes_remaining == 0) {
1129                /* no string area to decode, do nothing */
1130        } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1131                /* unicode string area must be word-aligned */
1132                if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1133                        ++bcc_ptr;
1134                        --bytes_remaining;
1135                }
1136                decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1137                                      sess_data->nls_cp);
1138        } else {
1139                decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1140                                    sess_data->nls_cp);
1141        }
1142
1143        rc = sess_establish_session(sess_data);
1144out_put_spnego_key:
1145        key_invalidate(spnego_key);
1146        key_put(spnego_key);
1147out:
1148        sess_data->result = rc;
1149        sess_data->func = NULL;
1150        sess_free_buffer(sess_data);
1151        kfree(ses->auth_key.response);
1152        ses->auth_key.response = NULL;
1153}
1154
1155#endif /* ! CONFIG_CIFS_UPCALL */
1156
1157/*
1158 * The required kvec buffers have to be allocated before calling this
1159 * function.
1160 */
1161static int
1162_sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
1163{
1164        SESSION_SETUP_ANDX *pSMB;
1165        struct cifs_ses *ses = sess_data->ses;
1166        __u32 capabilities;
1167        char *bcc_ptr;
1168
1169        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1170
1171        capabilities = cifs_ssetup_hdr(ses, pSMB);
1172        if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
1173                cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
1174                return -ENOSYS;
1175        }
1176
1177        pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1178        capabilities |= CAP_EXTENDED_SECURITY;
1179        pSMB->req.Capabilities |= cpu_to_le32(capabilities);
1180
1181        bcc_ptr = sess_data->iov[2].iov_base;
1182        /* unicode strings must be word aligned */
1183        if ((sess_data->iov[0].iov_len + sess_data->iov[1].iov_len) % 2) {
1184                *bcc_ptr = 0;
1185                bcc_ptr++;
1186        }
1187        unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1188
1189        sess_data->iov[2].iov_len = (long) bcc_ptr -
1190                                        (long) sess_data->iov[2].iov_base;
1191
1192        return 0;
1193}
1194
1195static void
1196sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
1197
1198static void
1199sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
1200{
1201        int rc;
1202        struct smb_hdr *smb_buf;
1203        SESSION_SETUP_ANDX *pSMB;
1204        struct cifs_ses *ses = sess_data->ses;
1205        __u16 bytes_remaining;
1206        char *bcc_ptr;
1207        u16 blob_len;
1208
1209        cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
1210
1211        /*
1212         * if memory allocation is successful, caller of this function
1213         * frees it.
1214         */
1215        ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
1216        if (!ses->ntlmssp) {
1217                rc = -ENOMEM;
1218                goto out;
1219        }
1220        ses->ntlmssp->sesskey_per_smbsess = false;
1221
1222        /* wct = 12 */
1223        rc = sess_alloc_buffer(sess_data, 12);
1224        if (rc)
1225                goto out;
1226
1227        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1228
1229        /* Build security blob before we assemble the request */
1230        build_ntlmssp_negotiate_blob(pSMB->req.SecurityBlob, ses);
1231        sess_data->iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
1232        sess_data->iov[1].iov_base = pSMB->req.SecurityBlob;
1233        pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
1234
1235        rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1236        if (rc)
1237                goto out;
1238
1239        rc = sess_sendreceive(sess_data);
1240
1241        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1242        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1243
1244        /* If true, rc here is expected and not an error */
1245        if (sess_data->buf0_type != CIFS_NO_BUFFER &&
1246            smb_buf->Status.CifsError ==
1247                        cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
1248                rc = 0;
1249
1250        if (rc)
1251                goto out;
1252
1253        cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
1254
1255        if (smb_buf->WordCount != 4) {
1256                rc = -EIO;
1257                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1258                goto out;
1259        }
1260
1261        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1262        cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1263
1264        bytes_remaining = get_bcc(smb_buf);
1265        bcc_ptr = pByteArea(smb_buf);
1266
1267        blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1268        if (blob_len > bytes_remaining) {
1269                cifs_dbg(VFS, "bad security blob length %d\n",
1270                                blob_len);
1271                rc = -EINVAL;
1272                goto out;
1273        }
1274
1275        rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
1276out:
1277        sess_free_buffer(sess_data);
1278
1279        if (!rc) {
1280                sess_data->func = sess_auth_rawntlmssp_authenticate;
1281                return;
1282        }
1283
1284        /* Else error. Cleanup */
1285        kfree(ses->auth_key.response);
1286        ses->auth_key.response = NULL;
1287        kfree(ses->ntlmssp);
1288        ses->ntlmssp = NULL;
1289
1290        sess_data->func = NULL;
1291        sess_data->result = rc;
1292}
1293
1294static void
1295sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
1296{
1297        int rc;
1298        struct smb_hdr *smb_buf;
1299        SESSION_SETUP_ANDX *pSMB;
1300        struct cifs_ses *ses = sess_data->ses;
1301        __u16 bytes_remaining;
1302        char *bcc_ptr;
1303        unsigned char *ntlmsspblob = NULL;
1304        u16 blob_len;
1305
1306        cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
1307
1308        /* wct = 12 */
1309        rc = sess_alloc_buffer(sess_data, 12);
1310        if (rc)
1311                goto out;
1312
1313        /* Build security blob before we assemble the request */
1314        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1315        smb_buf = (struct smb_hdr *)pSMB;
1316        rc = build_ntlmssp_auth_blob(&ntlmsspblob,
1317                                        &blob_len, ses, sess_data->nls_cp);
1318        if (rc)
1319                goto out_free_ntlmsspblob;
1320        sess_data->iov[1].iov_len = blob_len;
1321        sess_data->iov[1].iov_base = ntlmsspblob;
1322        pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1323        /*
1324         * Make sure that we tell the server that we are using
1325         * the uid that it just gave us back on the response
1326         * (challenge)
1327         */
1328        smb_buf->Uid = ses->Suid;
1329
1330        rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1331        if (rc)
1332                goto out_free_ntlmsspblob;
1333
1334        rc = sess_sendreceive(sess_data);
1335        if (rc)
1336                goto out_free_ntlmsspblob;
1337
1338        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1339        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1340        if (smb_buf->WordCount != 4) {
1341                rc = -EIO;
1342                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1343                goto out_free_ntlmsspblob;
1344        }
1345
1346        if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1347                cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1348
1349        if (ses->Suid != smb_buf->Uid) {
1350                ses->Suid = smb_buf->Uid;
1351                cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
1352        }
1353
1354        bytes_remaining = get_bcc(smb_buf);
1355        bcc_ptr = pByteArea(smb_buf);
1356        blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1357        if (blob_len > bytes_remaining) {
1358                cifs_dbg(VFS, "bad security blob length %d\n",
1359                                blob_len);
1360                rc = -EINVAL;
1361                goto out_free_ntlmsspblob;
1362        }
1363        bcc_ptr += blob_len;
1364        bytes_remaining -= blob_len;
1365
1366
1367        /* BB check if Unicode and decode strings */
1368        if (bytes_remaining == 0) {
1369                /* no string area to decode, do nothing */
1370        } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1371                /* unicode string area must be word-aligned */
1372                if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1373                        ++bcc_ptr;
1374                        --bytes_remaining;
1375                }
1376                decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1377                                      sess_data->nls_cp);
1378        } else {
1379                decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1380                                    sess_data->nls_cp);
1381        }
1382
1383out_free_ntlmsspblob:
1384        kfree(ntlmsspblob);
1385out:
1386        sess_free_buffer(sess_data);
1387
1388         if (!rc)
1389                rc = sess_establish_session(sess_data);
1390
1391        /* Cleanup */
1392        kfree(ses->auth_key.response);
1393        ses->auth_key.response = NULL;
1394        kfree(ses->ntlmssp);
1395        ses->ntlmssp = NULL;
1396
1397        sess_data->func = NULL;
1398        sess_data->result = rc;
1399}
1400
1401static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
1402{
1403        int type;
1404
1405        type = cifs_select_sectype(ses->server, ses->sectype);
1406        cifs_dbg(FYI, "sess setup type %d\n", type);
1407        if (type == Unspecified) {
1408                cifs_dbg(VFS,
1409                        "Unable to select appropriate authentication method!");
1410                return -EINVAL;
1411        }
1412
1413        switch (type) {
1414        case LANMAN:
1415                /* LANMAN and plaintext are less secure and off by default.
1416                 * So we make this explicitly be turned on in kconfig (in the
1417                 * build) and turned on at runtime (changed from the default)
1418                 * in proc/fs/cifs or via mount parm.  Unfortunately this is
1419                 * needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
1420#ifdef CONFIG_CIFS_WEAK_PW_HASH
1421                sess_data->func = sess_auth_lanman;
1422                break;
1423#else
1424                return -EOPNOTSUPP;
1425#endif
1426        case NTLM:
1427                sess_data->func = sess_auth_ntlm;
1428                break;
1429        case NTLMv2:
1430                sess_data->func = sess_auth_ntlmv2;
1431                break;
1432        case Kerberos:
1433#ifdef CONFIG_CIFS_UPCALL
1434                sess_data->func = sess_auth_kerberos;
1435                break;
1436#else
1437                cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1438                return -ENOSYS;
1439                break;
1440#endif /* CONFIG_CIFS_UPCALL */
1441        case RawNTLMSSP:
1442                sess_data->func = sess_auth_rawntlmssp_negotiate;
1443                break;
1444        default:
1445                cifs_dbg(VFS, "secType %d not supported!\n", type);
1446                return -ENOSYS;
1447        }
1448
1449        return 0;
1450}
1451
1452int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
1453                    const struct nls_table *nls_cp)
1454{
1455        int rc = 0;
1456        struct sess_data *sess_data;
1457
1458        if (ses == NULL) {
1459                WARN(1, "%s: ses == NULL!", __func__);
1460                return -EINVAL;
1461        }
1462
1463        sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
1464        if (!sess_data)
1465                return -ENOMEM;
1466
1467        rc = select_sec(ses, sess_data);
1468        if (rc)
1469                goto out;
1470
1471        sess_data->xid = xid;
1472        sess_data->ses = ses;
1473        sess_data->buf0_type = CIFS_NO_BUFFER;
1474        sess_data->nls_cp = (struct nls_table *) nls_cp;
1475
1476        while (sess_data->func)
1477                sess_data->func(sess_data);
1478
1479        /* Store result before we free sess_data */
1480        rc = sess_data->result;
1481
1482out:
1483        kfree(sess_data);
1484        return rc;
1485}
1486