GNU Linux-libre 5.4.257-gnu1
[releases.git] / fs / cifs / sess.c
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         cifs_small_buf_release(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 }