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