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