root/fs/cifs/sess.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cifs_ssetup_hdr
  2. unicode_oslm_strings
  3. unicode_domain_string
  4. unicode_ssetup_strings
  5. ascii_ssetup_strings
  6. decode_unicode_ssetup
  7. decode_ascii_ssetup
  8. decode_ntlmssp_challenge
  9. build_ntlmssp_negotiate_blob
  10. size_of_ntlmssp_blob
  11. build_ntlmssp_auth_blob
  12. cifs_select_sectype
  13. sess_alloc_buffer
  14. sess_free_buffer
  15. sess_establish_session
  16. sess_sendreceive
  17. sess_auth_lanman
  18. sess_auth_ntlm
  19. sess_auth_ntlmv2
  20. sess_auth_kerberos
  21. _sess_auth_rawntlmssp_assemble_req
  22. sess_auth_rawntlmssp_negotiate
  23. sess_auth_rawntlmssp_authenticate
  24. select_sec
  25. CIFS_SessSetup

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

/* [<][>][^][v][top][bottom][index][help] */