Linux-libre 5.3.12-gnu
[librecmc/linux-libre.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         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         __u32 capabilities;
702         __u16 bytes_remaining;
703
704         /* lanman 2 style sessionsetup */
705         /* wct = 10 */
706         rc = sess_alloc_buffer(sess_data, 10);
707         if (rc)
708                 goto out;
709
710         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
711         bcc_ptr = sess_data->iov[2].iov_base;
712         capabilities = cifs_ssetup_hdr(ses, pSMB);
713
714         pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
715
716         if (ses->user_name != NULL) {
717                 /* no capabilities flags in old lanman negotiation */
718                 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
719
720                 /* Calculate hash with password and copy into bcc_ptr.
721                  * Encryption Key (stored as in cryptkey) gets used if the
722                  * security mode bit in Negottiate Protocol response states
723                  * to use challenge/response method (i.e. Password bit is 1).
724                  */
725                 rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
726                                       ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
727                                       true : false, lnm_session_key);
728                 if (rc)
729                         goto out;
730
731                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
732                 bcc_ptr += CIFS_AUTH_RESP_SIZE;
733         } else {
734                 pSMB->old_req.PasswordLength = 0;
735         }
736
737         /*
738          * can not sign if LANMAN negotiated so no need
739          * to calculate signing key? but what if server
740          * changed to do higher than lanman dialect and
741          * we reconnected would we ever calc signing_key?
742          */
743
744         cifs_dbg(FYI, "Negotiating LANMAN setting up strings\n");
745         /* Unicode not allowed for LANMAN dialects */
746         ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
747
748         sess_data->iov[2].iov_len = (long) bcc_ptr -
749                         (long) sess_data->iov[2].iov_base;
750
751         rc = sess_sendreceive(sess_data);
752         if (rc)
753                 goto out;
754
755         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
756         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
757
758         /* lanman response has a word count of 3 */
759         if (smb_buf->WordCount != 3) {
760                 rc = -EIO;
761                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
762                 goto out;
763         }
764
765         if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
766                 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
767
768         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
769         cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
770
771         bytes_remaining = get_bcc(smb_buf);
772         bcc_ptr = pByteArea(smb_buf);
773
774         /* BB check if Unicode and decode strings */
775         if (bytes_remaining == 0) {
776                 /* no string area to decode, do nothing */
777         } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
778                 /* unicode string area must be word-aligned */
779                 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
780                         ++bcc_ptr;
781                         --bytes_remaining;
782                 }
783                 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
784                                       sess_data->nls_cp);
785         } else {
786                 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
787                                     sess_data->nls_cp);
788         }
789
790         rc = sess_establish_session(sess_data);
791 out:
792         sess_data->result = rc;
793         sess_data->func = NULL;
794         sess_free_buffer(sess_data);
795 }
796
797 #endif
798
799 static void
800 sess_auth_ntlm(struct sess_data *sess_data)
801 {
802         int rc = 0;
803         struct smb_hdr *smb_buf;
804         SESSION_SETUP_ANDX *pSMB;
805         char *bcc_ptr;
806         struct cifs_ses *ses = sess_data->ses;
807         __u32 capabilities;
808         __u16 bytes_remaining;
809
810         /* old style NTLM sessionsetup */
811         /* wct = 13 */
812         rc = sess_alloc_buffer(sess_data, 13);
813         if (rc)
814                 goto out;
815
816         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
817         bcc_ptr = sess_data->iov[2].iov_base;
818         capabilities = cifs_ssetup_hdr(ses, pSMB);
819
820         pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
821         if (ses->user_name != NULL) {
822                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
823                                 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
824                 pSMB->req_no_secext.CaseSensitivePasswordLength =
825                                 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
826
827                 /* calculate ntlm response and session key */
828                 rc = setup_ntlm_response(ses, sess_data->nls_cp);
829                 if (rc) {
830                         cifs_dbg(VFS, "Error %d during NTLM authentication\n",
831                                          rc);
832                         goto out;
833                 }
834
835                 /* copy ntlm response */
836                 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
837                                 CIFS_AUTH_RESP_SIZE);
838                 bcc_ptr += CIFS_AUTH_RESP_SIZE;
839                 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
840                                 CIFS_AUTH_RESP_SIZE);
841                 bcc_ptr += CIFS_AUTH_RESP_SIZE;
842         } else {
843                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
844                 pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
845         }
846
847         if (ses->capabilities & CAP_UNICODE) {
848                 /* unicode strings must be word aligned */
849                 if (sess_data->iov[0].iov_len % 2) {
850                         *bcc_ptr = 0;
851                         bcc_ptr++;
852                 }
853                 unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
854         } else {
855                 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
856         }
857
858
859         sess_data->iov[2].iov_len = (long) bcc_ptr -
860                         (long) sess_data->iov[2].iov_base;
861
862         rc = sess_sendreceive(sess_data);
863         if (rc)
864                 goto out;
865
866         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
867         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
868
869         if (smb_buf->WordCount != 3) {
870                 rc = -EIO;
871                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
872                 goto out;
873         }
874
875         if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
876                 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
877
878         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
879         cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
880
881         bytes_remaining = get_bcc(smb_buf);
882         bcc_ptr = pByteArea(smb_buf);
883
884         /* BB check if Unicode and decode strings */
885         if (bytes_remaining == 0) {
886                 /* no string area to decode, do nothing */
887         } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
888                 /* unicode string area must be word-aligned */
889                 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
890                         ++bcc_ptr;
891                         --bytes_remaining;
892                 }
893                 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
894                                       sess_data->nls_cp);
895         } else {
896                 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
897                                     sess_data->nls_cp);
898         }
899
900         rc = sess_establish_session(sess_data);
901 out:
902         sess_data->result = rc;
903         sess_data->func = NULL;
904         sess_free_buffer(sess_data);
905         kfree(ses->auth_key.response);
906         ses->auth_key.response = NULL;
907 }
908
909 static void
910 sess_auth_ntlmv2(struct sess_data *sess_data)
911 {
912         int rc = 0;
913         struct smb_hdr *smb_buf;
914         SESSION_SETUP_ANDX *pSMB;
915         char *bcc_ptr;
916         struct cifs_ses *ses = sess_data->ses;
917         __u32 capabilities;
918         __u16 bytes_remaining;
919
920         /* old style NTLM sessionsetup */
921         /* wct = 13 */
922         rc = sess_alloc_buffer(sess_data, 13);
923         if (rc)
924                 goto out;
925
926         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
927         bcc_ptr = sess_data->iov[2].iov_base;
928         capabilities = cifs_ssetup_hdr(ses, pSMB);
929
930         pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
931
932         /* LM2 password would be here if we supported it */
933         pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
934
935         if (ses->user_name != NULL) {
936                 /* calculate nlmv2 response and session key */
937                 rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
938                 if (rc) {
939                         cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
940                         goto out;
941                 }
942
943                 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
944                                 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
945                 bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
946
947                 /* set case sensitive password length after tilen may get
948                  * assigned, tilen is 0 otherwise.
949                  */
950                 pSMB->req_no_secext.CaseSensitivePasswordLength =
951                         cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
952         } else {
953                 pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
954         }
955
956         if (ses->capabilities & CAP_UNICODE) {
957                 if (sess_data->iov[0].iov_len % 2) {
958                         *bcc_ptr = 0;
959                         bcc_ptr++;
960                 }
961                 unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
962         } else {
963                 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
964         }
965
966
967         sess_data->iov[2].iov_len = (long) bcc_ptr -
968                         (long) sess_data->iov[2].iov_base;
969
970         rc = sess_sendreceive(sess_data);
971         if (rc)
972                 goto out;
973
974         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
975         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
976
977         if (smb_buf->WordCount != 3) {
978                 rc = -EIO;
979                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
980                 goto out;
981         }
982
983         if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
984                 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
985
986         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
987         cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
988
989         bytes_remaining = get_bcc(smb_buf);
990         bcc_ptr = pByteArea(smb_buf);
991
992         /* BB check if Unicode and decode strings */
993         if (bytes_remaining == 0) {
994                 /* no string area to decode, do nothing */
995         } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
996                 /* unicode string area must be word-aligned */
997                 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
998                         ++bcc_ptr;
999                         --bytes_remaining;
1000                 }
1001                 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1002                                       sess_data->nls_cp);
1003         } else {
1004                 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1005                                     sess_data->nls_cp);
1006         }
1007
1008         rc = sess_establish_session(sess_data);
1009 out:
1010         sess_data->result = rc;
1011         sess_data->func = NULL;
1012         sess_free_buffer(sess_data);
1013         kfree(ses->auth_key.response);
1014         ses->auth_key.response = NULL;
1015 }
1016
1017 #ifdef CONFIG_CIFS_UPCALL
1018 static void
1019 sess_auth_kerberos(struct sess_data *sess_data)
1020 {
1021         int rc = 0;
1022         struct smb_hdr *smb_buf;
1023         SESSION_SETUP_ANDX *pSMB;
1024         char *bcc_ptr;
1025         struct cifs_ses *ses = sess_data->ses;
1026         __u32 capabilities;
1027         __u16 bytes_remaining;
1028         struct key *spnego_key = NULL;
1029         struct cifs_spnego_msg *msg;
1030         u16 blob_len;
1031
1032         /* extended security */
1033         /* wct = 12 */
1034         rc = sess_alloc_buffer(sess_data, 12);
1035         if (rc)
1036                 goto out;
1037
1038         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1039         bcc_ptr = sess_data->iov[2].iov_base;
1040         capabilities = cifs_ssetup_hdr(ses, pSMB);
1041
1042         spnego_key = cifs_get_spnego_key(ses);
1043         if (IS_ERR(spnego_key)) {
1044                 rc = PTR_ERR(spnego_key);
1045                 spnego_key = NULL;
1046                 goto out;
1047         }
1048
1049         msg = spnego_key->payload.data[0];
1050         /*
1051          * check version field to make sure that cifs.upcall is
1052          * sending us a response in an expected form
1053          */
1054         if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1055                 cifs_dbg(VFS,
1056                   "incorrect version of cifs.upcall (expected %d but got %d)",
1057                               CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1058                 rc = -EKEYREJECTED;
1059                 goto out_put_spnego_key;
1060         }
1061
1062         ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1063                                          GFP_KERNEL);
1064         if (!ses->auth_key.response) {
1065                 cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory",
1066                                 msg->sesskey_len);
1067                 rc = -ENOMEM;
1068                 goto out_put_spnego_key;
1069         }
1070         ses->auth_key.len = msg->sesskey_len;
1071
1072         pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1073         capabilities |= CAP_EXTENDED_SECURITY;
1074         pSMB->req.Capabilities = cpu_to_le32(capabilities);
1075         sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1076         sess_data->iov[1].iov_len = msg->secblob_len;
1077         pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
1078
1079         if (ses->capabilities & CAP_UNICODE) {
1080                 /* unicode strings must be word aligned */
1081                 if ((sess_data->iov[0].iov_len
1082                         + sess_data->iov[1].iov_len) % 2) {
1083                         *bcc_ptr = 0;
1084                         bcc_ptr++;
1085                 }
1086                 unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1087                 unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
1088         } else {
1089                 /* BB: is this right? */
1090                 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1091         }
1092
1093         sess_data->iov[2].iov_len = (long) bcc_ptr -
1094                         (long) sess_data->iov[2].iov_base;
1095
1096         rc = sess_sendreceive(sess_data);
1097         if (rc)
1098                 goto out_put_spnego_key;
1099
1100         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1101         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1102
1103         if (smb_buf->WordCount != 4) {
1104                 rc = -EIO;
1105                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1106                 goto out_put_spnego_key;
1107         }
1108
1109         if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1110                 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1111
1112         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1113         cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1114
1115         bytes_remaining = get_bcc(smb_buf);
1116         bcc_ptr = pByteArea(smb_buf);
1117
1118         blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1119         if (blob_len > bytes_remaining) {
1120                 cifs_dbg(VFS, "bad security blob length %d\n",
1121                                 blob_len);
1122                 rc = -EINVAL;
1123                 goto out_put_spnego_key;
1124         }
1125         bcc_ptr += blob_len;
1126         bytes_remaining -= blob_len;
1127
1128         /* BB check if Unicode and decode strings */
1129         if (bytes_remaining == 0) {
1130                 /* no string area to decode, do nothing */
1131         } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1132                 /* unicode string area must be word-aligned */
1133                 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1134                         ++bcc_ptr;
1135                         --bytes_remaining;
1136                 }
1137                 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1138                                       sess_data->nls_cp);
1139         } else {
1140                 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1141                                     sess_data->nls_cp);
1142         }
1143
1144         rc = sess_establish_session(sess_data);
1145 out_put_spnego_key:
1146         key_invalidate(spnego_key);
1147         key_put(spnego_key);
1148 out:
1149         sess_data->result = rc;
1150         sess_data->func = NULL;
1151         sess_free_buffer(sess_data);
1152         kfree(ses->auth_key.response);
1153         ses->auth_key.response = NULL;
1154 }
1155
1156 #endif /* ! CONFIG_CIFS_UPCALL */
1157
1158 /*
1159  * The required kvec buffers have to be allocated before calling this
1160  * function.
1161  */
1162 static int
1163 _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
1164 {
1165         SESSION_SETUP_ANDX *pSMB;
1166         struct cifs_ses *ses = sess_data->ses;
1167         __u32 capabilities;
1168         char *bcc_ptr;
1169
1170         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1171
1172         capabilities = cifs_ssetup_hdr(ses, pSMB);
1173         if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
1174                 cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
1175                 return -ENOSYS;
1176         }
1177
1178         pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1179         capabilities |= CAP_EXTENDED_SECURITY;
1180         pSMB->req.Capabilities |= cpu_to_le32(capabilities);
1181
1182         bcc_ptr = sess_data->iov[2].iov_base;
1183         /* unicode strings must be word aligned */
1184         if ((sess_data->iov[0].iov_len + sess_data->iov[1].iov_len) % 2) {
1185                 *bcc_ptr = 0;
1186                 bcc_ptr++;
1187         }
1188         unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1189
1190         sess_data->iov[2].iov_len = (long) bcc_ptr -
1191                                         (long) sess_data->iov[2].iov_base;
1192
1193         return 0;
1194 }
1195
1196 static void
1197 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
1198
1199 static void
1200 sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
1201 {
1202         int rc;
1203         struct smb_hdr *smb_buf;
1204         SESSION_SETUP_ANDX *pSMB;
1205         struct cifs_ses *ses = sess_data->ses;
1206         __u16 bytes_remaining;
1207         char *bcc_ptr;
1208         u16 blob_len;
1209
1210         cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
1211
1212         /*
1213          * if memory allocation is successful, caller of this function
1214          * frees it.
1215          */
1216         ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
1217         if (!ses->ntlmssp) {
1218                 rc = -ENOMEM;
1219                 goto out;
1220         }
1221         ses->ntlmssp->sesskey_per_smbsess = false;
1222
1223         /* wct = 12 */
1224         rc = sess_alloc_buffer(sess_data, 12);
1225         if (rc)
1226                 goto out;
1227
1228         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1229
1230         /* Build security blob before we assemble the request */
1231         build_ntlmssp_negotiate_blob(pSMB->req.SecurityBlob, ses);
1232         sess_data->iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
1233         sess_data->iov[1].iov_base = pSMB->req.SecurityBlob;
1234         pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
1235
1236         rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1237         if (rc)
1238                 goto out;
1239
1240         rc = sess_sendreceive(sess_data);
1241
1242         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1243         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1244
1245         /* If true, rc here is expected and not an error */
1246         if (sess_data->buf0_type != CIFS_NO_BUFFER &&
1247             smb_buf->Status.CifsError ==
1248                         cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
1249                 rc = 0;
1250
1251         if (rc)
1252                 goto out;
1253
1254         cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
1255
1256         if (smb_buf->WordCount != 4) {
1257                 rc = -EIO;
1258                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1259                 goto out;
1260         }
1261
1262         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
1263         cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1264
1265         bytes_remaining = get_bcc(smb_buf);
1266         bcc_ptr = pByteArea(smb_buf);
1267
1268         blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1269         if (blob_len > bytes_remaining) {
1270                 cifs_dbg(VFS, "bad security blob length %d\n",
1271                                 blob_len);
1272                 rc = -EINVAL;
1273                 goto out;
1274         }
1275
1276         rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
1277 out:
1278         sess_free_buffer(sess_data);
1279
1280         if (!rc) {
1281                 sess_data->func = sess_auth_rawntlmssp_authenticate;
1282                 return;
1283         }
1284
1285         /* Else error. Cleanup */
1286         kfree(ses->auth_key.response);
1287         ses->auth_key.response = NULL;
1288         kfree(ses->ntlmssp);
1289         ses->ntlmssp = NULL;
1290
1291         sess_data->func = NULL;
1292         sess_data->result = rc;
1293 }
1294
1295 static void
1296 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
1297 {
1298         int rc;
1299         struct smb_hdr *smb_buf;
1300         SESSION_SETUP_ANDX *pSMB;
1301         struct cifs_ses *ses = sess_data->ses;
1302         __u16 bytes_remaining;
1303         char *bcc_ptr;
1304         unsigned char *ntlmsspblob = NULL;
1305         u16 blob_len;
1306
1307         cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
1308
1309         /* wct = 12 */
1310         rc = sess_alloc_buffer(sess_data, 12);
1311         if (rc)
1312                 goto out;
1313
1314         /* Build security blob before we assemble the request */
1315         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1316         smb_buf = (struct smb_hdr *)pSMB;
1317         rc = build_ntlmssp_auth_blob(&ntlmsspblob,
1318                                         &blob_len, ses, sess_data->nls_cp);
1319         if (rc)
1320                 goto out_free_ntlmsspblob;
1321         sess_data->iov[1].iov_len = blob_len;
1322         sess_data->iov[1].iov_base = ntlmsspblob;
1323         pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1324         /*
1325          * Make sure that we tell the server that we are using
1326          * the uid that it just gave us back on the response
1327          * (challenge)
1328          */
1329         smb_buf->Uid = ses->Suid;
1330
1331         rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1332         if (rc)
1333                 goto out_free_ntlmsspblob;
1334
1335         rc = sess_sendreceive(sess_data);
1336         if (rc)
1337                 goto out_free_ntlmsspblob;
1338
1339         pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1340         smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1341         if (smb_buf->WordCount != 4) {
1342                 rc = -EIO;
1343                 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1344                 goto out_free_ntlmsspblob;
1345         }
1346
1347         if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1348                 cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
1349
1350         if (ses->Suid != smb_buf->Uid) {
1351                 ses->Suid = smb_buf->Uid;
1352                 cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
1353         }
1354
1355         bytes_remaining = get_bcc(smb_buf);
1356         bcc_ptr = pByteArea(smb_buf);
1357         blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1358         if (blob_len > bytes_remaining) {
1359                 cifs_dbg(VFS, "bad security blob length %d\n",
1360                                 blob_len);
1361                 rc = -EINVAL;
1362                 goto out_free_ntlmsspblob;
1363         }
1364         bcc_ptr += blob_len;
1365         bytes_remaining -= blob_len;
1366
1367
1368         /* BB check if Unicode and decode strings */
1369         if (bytes_remaining == 0) {
1370                 /* no string area to decode, do nothing */
1371         } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1372                 /* unicode string area must be word-aligned */
1373                 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1374                         ++bcc_ptr;
1375                         --bytes_remaining;
1376                 }
1377                 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1378                                       sess_data->nls_cp);
1379         } else {
1380                 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1381                                     sess_data->nls_cp);
1382         }
1383
1384 out_free_ntlmsspblob:
1385         kfree(ntlmsspblob);
1386 out:
1387         sess_free_buffer(sess_data);
1388
1389          if (!rc)
1390                 rc = sess_establish_session(sess_data);
1391
1392         /* Cleanup */
1393         kfree(ses->auth_key.response);
1394         ses->auth_key.response = NULL;
1395         kfree(ses->ntlmssp);
1396         ses->ntlmssp = NULL;
1397
1398         sess_data->func = NULL;
1399         sess_data->result = rc;
1400 }
1401
1402 static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
1403 {
1404         int type;
1405
1406         type = cifs_select_sectype(ses->server, ses->sectype);
1407         cifs_dbg(FYI, "sess setup type %d\n", type);
1408         if (type == Unspecified) {
1409                 cifs_dbg(VFS,
1410                         "Unable to select appropriate authentication method!");
1411                 return -EINVAL;
1412         }
1413
1414         switch (type) {
1415         case LANMAN:
1416                 /* LANMAN and plaintext are less secure and off by default.
1417                  * So we make this explicitly be turned on in kconfig (in the
1418                  * build) and turned on at runtime (changed from the default)
1419                  * in proc/fs/cifs or via mount parm.  Unfortunately this is
1420                  * needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
1421 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1422                 sess_data->func = sess_auth_lanman;
1423                 break;
1424 #else
1425                 return -EOPNOTSUPP;
1426 #endif
1427         case NTLM:
1428                 sess_data->func = sess_auth_ntlm;
1429                 break;
1430         case NTLMv2:
1431                 sess_data->func = sess_auth_ntlmv2;
1432                 break;
1433         case Kerberos:
1434 #ifdef CONFIG_CIFS_UPCALL
1435                 sess_data->func = sess_auth_kerberos;
1436                 break;
1437 #else
1438                 cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1439                 return -ENOSYS;
1440                 break;
1441 #endif /* CONFIG_CIFS_UPCALL */
1442         case RawNTLMSSP:
1443                 sess_data->func = sess_auth_rawntlmssp_negotiate;
1444                 break;
1445         default:
1446                 cifs_dbg(VFS, "secType %d not supported!\n", type);
1447                 return -ENOSYS;
1448         }
1449
1450         return 0;
1451 }
1452
1453 int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
1454                     const struct nls_table *nls_cp)
1455 {
1456         int rc = 0;
1457         struct sess_data *sess_data;
1458
1459         if (ses == NULL) {
1460                 WARN(1, "%s: ses == NULL!", __func__);
1461                 return -EINVAL;
1462         }
1463
1464         sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
1465         if (!sess_data)
1466                 return -ENOMEM;
1467
1468         rc = select_sec(ses, sess_data);
1469         if (rc)
1470                 goto out;
1471
1472         sess_data->xid = xid;
1473         sess_data->ses = ses;
1474         sess_data->buf0_type = CIFS_NO_BUFFER;
1475         sess_data->nls_cp = (struct nls_table *) nls_cp;
1476
1477         while (sess_data->func)
1478                 sess_data->func(sess_data);
1479
1480         /* Store result before we free sess_data */
1481         rc = sess_data->result;
1482
1483 out:
1484         kfree(sess_data);
1485         return rc;
1486 }