1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
36
37
38
39
40static bool is_first_ses_reconnect(struct cifs_ses *ses)
41{
42 struct list_head *tmp;
43 struct cifs_ses *tmp_ses;
44
45 list_for_each(tmp, &ses->server->smb_ses_list) {
46 tmp_ses = list_entry(tmp, struct cifs_ses,
47 smb_ses_list);
48 if (tmp_ses->need_reconnect == false)
49 return false;
50 }
51
52
53 return true;
54}
55
56
57
58
59
60
61
62
63
64static __le16 get_next_vcnum(struct cifs_ses *ses)
65{
66 __u16 vcnum = 0;
67 struct list_head *tmp;
68 struct cifs_ses *tmp_ses;
69 __u16 max_vcs = ses->server->max_vcs;
70 __u16 i;
71 int free_vc_found = 0;
72
73
74
75
76
77 if (max_vcs < 2)
78 max_vcs = 0xFFFF;
79
80 spin_lock(&cifs_tcp_ses_lock);
81 if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
82 goto get_vc_num_exit;
83 for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
84 if (i == 0)
85 break;
86
87 free_vc_found = 1;
88
89 list_for_each(tmp, &ses->server->smb_ses_list) {
90 tmp_ses = list_entry(tmp, struct cifs_ses,
91 smb_ses_list);
92 if (tmp_ses->vcnum == i) {
93 free_vc_found = 0;
94 break;
95 }
96 }
97 if (free_vc_found)
98 break;
99 }
100
101 if (i == 0)
102 vcnum = 0;
103
104
105 else if (free_vc_found == 0)
106 vcnum = 1;
107
108 else
109 vcnum = i;
110 ses->vcnum = vcnum;
111get_vc_num_exit:
112 spin_unlock(&cifs_tcp_ses_lock);
113
114 return cpu_to_le16(vcnum);
115}
116
117static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
118{
119 __u32 capabilities = 0;
120
121
122
123
124
125
126 pSMB->req.AndXCommand = 0xFF;
127 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
128 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
129 pSMB->req.VcNumber = get_next_vcnum(ses);
130
131
132
133
134
135
136 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
137 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
138
139 if (ses->server->sec_mode &
140 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
141 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
142
143 if (ses->capabilities & CAP_UNICODE) {
144 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
145 capabilities |= CAP_UNICODE;
146 }
147 if (ses->capabilities & CAP_STATUS32) {
148 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
149 capabilities |= CAP_STATUS32;
150 }
151 if (ses->capabilities & CAP_DFS) {
152 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
153 capabilities |= CAP_DFS;
154 }
155 if (ses->capabilities & CAP_UNIX)
156 capabilities |= CAP_UNIX;
157
158 return capabilities;
159}
160
161static void
162unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
163{
164 char *bcc_ptr = *pbcc_area;
165 int bytes_ret = 0;
166
167
168 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
169 nls_cp);
170 bcc_ptr += 2 * bytes_ret;
171 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
172 32, nls_cp);
173 bcc_ptr += 2 * bytes_ret;
174 bcc_ptr += 2;
175
176 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
177 32, nls_cp);
178 bcc_ptr += 2 * bytes_ret;
179 bcc_ptr += 2;
180
181 *pbcc_area = bcc_ptr;
182}
183
184static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
185 const struct nls_table *nls_cp)
186{
187 char *bcc_ptr = *pbcc_area;
188 int bytes_ret = 0;
189
190
191 if (ses->domainName == NULL) {
192
193
194 *bcc_ptr = 0;
195 *(bcc_ptr+1) = 0;
196 bytes_ret = 0;
197 } else
198 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
199 256, nls_cp);
200 bcc_ptr += 2 * bytes_ret;
201 bcc_ptr += 2;
202
203 *pbcc_area = bcc_ptr;
204}
205
206
207static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
208 const struct nls_table *nls_cp)
209{
210 char *bcc_ptr = *pbcc_area;
211 int bytes_ret = 0;
212
213
214
215
216
217
218
219
220
221
222 if (ses->user_name == NULL) {
223
224 *bcc_ptr = 0;
225 *(bcc_ptr+1) = 0;
226 } else {
227 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->user_name,
228 MAX_USERNAME_SIZE, nls_cp);
229 }
230 bcc_ptr += 2 * bytes_ret;
231 bcc_ptr += 2;
232
233 unicode_domain_string(&bcc_ptr, ses, nls_cp);
234 unicode_oslm_strings(&bcc_ptr, nls_cp);
235
236 *pbcc_area = bcc_ptr;
237}
238
239static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
240 const struct nls_table *nls_cp)
241{
242 char *bcc_ptr = *pbcc_area;
243
244
245
246
247 if (ses->user_name != NULL)
248 strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
249
250
251 bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
252 *bcc_ptr = 0;
253 bcc_ptr++;
254
255
256
257 if (ses->domainName != NULL) {
258 strncpy(bcc_ptr, ses->domainName, 256);
259 bcc_ptr += strnlen(ses->domainName, 256);
260 }
261
262 *bcc_ptr = 0;
263 bcc_ptr++;
264
265
266
267 strcpy(bcc_ptr, "Linux version ");
268 bcc_ptr += strlen("Linux version ");
269 strcpy(bcc_ptr, init_utsname()->release);
270 bcc_ptr += strlen(init_utsname()->release) + 1;
271
272 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
273 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
274
275 *pbcc_area = bcc_ptr;
276}
277
278static void
279decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
280 const struct nls_table *nls_cp)
281{
282 int len;
283 char *data = *pbcc_area;
284
285 cFYI(1, "bleft %d", bleft);
286
287 kfree(ses->serverOS);
288 ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
289 cFYI(1, "serverOS=%s", ses->serverOS);
290 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
291 data += len;
292 bleft -= len;
293 if (bleft <= 0)
294 return;
295
296 kfree(ses->serverNOS);
297 ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
298 cFYI(1, "serverNOS=%s", ses->serverNOS);
299 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
300 data += len;
301 bleft -= len;
302 if (bleft <= 0)
303 return;
304
305 kfree(ses->serverDomain);
306 ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
307 cFYI(1, "serverDomain=%s", ses->serverDomain);
308
309 return;
310}
311
312static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
313 struct cifs_ses *ses,
314 const struct nls_table *nls_cp)
315{
316 int rc = 0;
317 int len;
318 char *bcc_ptr = *pbcc_area;
319
320 cFYI(1, "decode sessetup ascii. bleft %d", bleft);
321
322 len = strnlen(bcc_ptr, bleft);
323 if (len >= bleft)
324 return rc;
325
326 kfree(ses->serverOS);
327
328 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
329 if (ses->serverOS)
330 strncpy(ses->serverOS, bcc_ptr, len);
331 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
332 cFYI(1, "OS/2 server");
333 ses->flags |= CIFS_SES_OS2;
334 }
335
336 bcc_ptr += len + 1;
337 bleft -= len + 1;
338
339 len = strnlen(bcc_ptr, bleft);
340 if (len >= bleft)
341 return rc;
342
343 kfree(ses->serverNOS);
344
345 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
346 if (ses->serverNOS)
347 strncpy(ses->serverNOS, bcc_ptr, len);
348
349 bcc_ptr += len + 1;
350 bleft -= len + 1;
351
352 len = strnlen(bcc_ptr, bleft);
353 if (len > bleft)
354 return rc;
355
356
357
358
359
360
361 cFYI(1, "ascii: bytes left %d", bleft);
362
363 return rc;
364}
365
366static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
367 struct cifs_ses *ses)
368{
369 unsigned int tioffset;
370 unsigned int tilen;
371
372 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
373
374 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
375 cERROR(1, "challenge blob len %d too small", blob_len);
376 return -EINVAL;
377 }
378
379 if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
380 cERROR(1, "blob signature incorrect %s", pblob->Signature);
381 return -EINVAL;
382 }
383 if (pblob->MessageType != NtLmChallenge) {
384 cERROR(1, "Incorrect message type %d", pblob->MessageType);
385 return -EINVAL;
386 }
387
388 memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
389
390
391
392
393 ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
394 tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
395 tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
396 if (tilen) {
397 ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
398 if (!ses->auth_key.response) {
399 cERROR(1, "Challenge target info allocation failure");
400 return -ENOMEM;
401 }
402 memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen);
403 ses->auth_key.len = tilen;
404 }
405
406 return 0;
407}
408
409
410
411
412
413static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
414 struct cifs_ses *ses)
415{
416 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
417 __u32 flags;
418
419 memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
420 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
421 sec_blob->MessageType = NtLmNegotiate;
422
423
424 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
425 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
426 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
427 if (ses->server->sec_mode &
428 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
429 flags |= NTLMSSP_NEGOTIATE_SIGN;
430 if (!ses->server->session_estab)
431 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
432 }
433
434 sec_blob->NegotiateFlags = cpu_to_le32(flags);
435
436 sec_blob->WorkstationName.BufferOffset = 0;
437 sec_blob->WorkstationName.Length = 0;
438 sec_blob->WorkstationName.MaximumLength = 0;
439
440
441 sec_blob->DomainName.BufferOffset = 0;
442 sec_blob->DomainName.Length = 0;
443 sec_blob->DomainName.MaximumLength = 0;
444}
445
446
447
448
449static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
450 u16 *buflen,
451 struct cifs_ses *ses,
452 const struct nls_table *nls_cp)
453{
454 int rc;
455 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
456 __u32 flags;
457 unsigned char *tmp;
458
459 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
460 sec_blob->MessageType = NtLmAuthenticate;
461
462 flags = NTLMSSP_NEGOTIATE_56 |
463 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
464 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
465 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
466 if (ses->server->sec_mode &
467 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
468 flags |= NTLMSSP_NEGOTIATE_SIGN;
469 if (!ses->server->session_estab)
470 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
471 }
472
473 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
474 sec_blob->NegotiateFlags = cpu_to_le32(flags);
475
476 sec_blob->LmChallengeResponse.BufferOffset =
477 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
478 sec_blob->LmChallengeResponse.Length = 0;
479 sec_blob->LmChallengeResponse.MaximumLength = 0;
480
481 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
482 rc = setup_ntlmv2_rsp(ses, nls_cp);
483 if (rc) {
484 cERROR(1, "Error %d during NTLMSSP authentication", rc);
485 goto setup_ntlmv2_ret;
486 }
487 memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
488 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
489 tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
490
491 sec_blob->NtChallengeResponse.Length =
492 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
493 sec_blob->NtChallengeResponse.MaximumLength =
494 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
495
496 if (ses->domainName == NULL) {
497 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
498 sec_blob->DomainName.Length = 0;
499 sec_blob->DomainName.MaximumLength = 0;
500 tmp += 2;
501 } else {
502 int len;
503 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
504 MAX_USERNAME_SIZE, nls_cp);
505 len *= 2;
506 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
507 sec_blob->DomainName.Length = cpu_to_le16(len);
508 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
509 tmp += len;
510 }
511
512 if (ses->user_name == NULL) {
513 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
514 sec_blob->UserName.Length = 0;
515 sec_blob->UserName.MaximumLength = 0;
516 tmp += 2;
517 } else {
518 int len;
519 len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
520 MAX_USERNAME_SIZE, nls_cp);
521 len *= 2;
522 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
523 sec_blob->UserName.Length = cpu_to_le16(len);
524 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
525 tmp += len;
526 }
527
528 sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
529 sec_blob->WorkstationName.Length = 0;
530 sec_blob->WorkstationName.MaximumLength = 0;
531 tmp += 2;
532
533 if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
534 (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
535 && !calc_seckey(ses)) {
536 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
537 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
538 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
539 sec_blob->SessionKey.MaximumLength =
540 cpu_to_le16(CIFS_CPHTXT_SIZE);
541 tmp += CIFS_CPHTXT_SIZE;
542 } else {
543 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
544 sec_blob->SessionKey.Length = 0;
545 sec_blob->SessionKey.MaximumLength = 0;
546 }
547
548setup_ntlmv2_ret:
549 *buflen = tmp - pbuffer;
550 return rc;
551}
552
553int
554CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
555 const struct nls_table *nls_cp)
556{
557 int rc = 0;
558 int wct;
559 struct smb_hdr *smb_buf;
560 char *bcc_ptr;
561 char *str_area;
562 SESSION_SETUP_ANDX *pSMB;
563 __u32 capabilities;
564 __u16 count;
565 int resp_buf_type;
566 struct kvec iov[3];
567 enum securityEnum type;
568 __u16 action, bytes_remaining;
569 struct key *spnego_key = NULL;
570 __le32 phase = NtLmNegotiate;
571 u16 blob_len;
572 char *ntlmsspblob = NULL;
573
574 if (ses == NULL)
575 return -EINVAL;
576
577 type = ses->server->secType;
578 cFYI(1, "sess setup type %d", type);
579 if (type == RawNTLMSSP) {
580
581
582
583 ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
584 if (!ses->ntlmssp)
585 return -ENOMEM;
586 }
587
588ssetup_ntlmssp_authenticate:
589 if (phase == NtLmChallenge)
590 phase = NtLmAuthenticate;
591
592 if (type == LANMAN) {
593#ifndef CONFIG_CIFS_WEAK_PW_HASH
594
595
596
597
598
599 return -EOPNOTSUPP;
600#endif
601 wct = 10;
602 } else if ((type == NTLM) || (type == NTLMv2)) {
603
604 wct = 13;
605 } else
606 wct = 12;
607
608 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
609 (void **)&smb_buf);
610 if (rc)
611 return rc;
612
613 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
614
615 capabilities = cifs_ssetup_hdr(ses, pSMB);
616
617
618
619
620
621
622
623 iov[0].iov_base = (char *)pSMB;
624 iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
625
626
627
628 resp_buf_type = CIFS_SMALL_BUFFER;
629
630
631 str_area = kmalloc(2000, GFP_KERNEL);
632 if (str_area == NULL) {
633 rc = -ENOMEM;
634 goto ssetup_exit;
635 }
636 bcc_ptr = str_area;
637
638 ses->flags &= ~CIFS_SES_LANMAN;
639
640 iov[1].iov_base = NULL;
641 iov[1].iov_len = 0;
642
643 if (type == LANMAN) {
644#ifdef CONFIG_CIFS_WEAK_PW_HASH
645 char lnm_session_key[CIFS_AUTH_RESP_SIZE];
646
647 pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
648
649
650
651 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
652
653
654
655
656
657
658
659 rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
660 ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
661 true : false, lnm_session_key);
662
663 ses->flags |= CIFS_SES_LANMAN;
664 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
665 bcc_ptr += CIFS_AUTH_RESP_SIZE;
666
667
668
669
670
671
672 cFYI(1, "Negotiating LANMAN setting up strings");
673
674 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
675#endif
676 } else if (type == NTLM) {
677 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
678 pSMB->req_no_secext.CaseInsensitivePasswordLength =
679 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
680 pSMB->req_no_secext.CaseSensitivePasswordLength =
681 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
682
683
684 rc = setup_ntlm_response(ses);
685 if (rc) {
686 cERROR(1, "Error %d during NTLM authentication", rc);
687 goto ssetup_exit;
688 }
689
690
691 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
692 CIFS_AUTH_RESP_SIZE);
693 bcc_ptr += CIFS_AUTH_RESP_SIZE;
694 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
695 CIFS_AUTH_RESP_SIZE);
696 bcc_ptr += CIFS_AUTH_RESP_SIZE;
697
698 if (ses->capabilities & CAP_UNICODE) {
699
700 if (iov[0].iov_len % 2) {
701 *bcc_ptr = 0;
702 bcc_ptr++;
703 }
704 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
705 } else
706 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
707 } else if (type == NTLMv2) {
708 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
709
710
711 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
712
713
714 rc = setup_ntlmv2_rsp(ses, nls_cp);
715 if (rc) {
716 cERROR(1, "Error %d during NTLMv2 authentication", rc);
717 goto ssetup_exit;
718 }
719 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
720 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
721 bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
722
723
724
725
726 pSMB->req_no_secext.CaseSensitivePasswordLength =
727 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
728
729 if (ses->capabilities & CAP_UNICODE) {
730 if (iov[0].iov_len % 2) {
731 *bcc_ptr = 0;
732 bcc_ptr++;
733 }
734 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
735 } else
736 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
737 } else if (type == Kerberos) {
738#ifdef CONFIG_CIFS_UPCALL
739 struct cifs_spnego_msg *msg;
740
741 spnego_key = cifs_get_spnego_key(ses);
742 if (IS_ERR(spnego_key)) {
743 rc = PTR_ERR(spnego_key);
744 spnego_key = NULL;
745 goto ssetup_exit;
746 }
747
748 msg = spnego_key->payload.data;
749
750
751 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
752 cERROR(1, "incorrect version of cifs.upcall (expected"
753 " %d but got %d)",
754 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
755 rc = -EKEYREJECTED;
756 goto ssetup_exit;
757 }
758
759 ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL);
760 if (!ses->auth_key.response) {
761 cERROR(1, "Kerberos can't allocate (%u bytes) memory",
762 msg->sesskey_len);
763 rc = -ENOMEM;
764 goto ssetup_exit;
765 }
766 memcpy(ses->auth_key.response, msg->data, msg->sesskey_len);
767 ses->auth_key.len = msg->sesskey_len;
768
769 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
770 capabilities |= CAP_EXTENDED_SECURITY;
771 pSMB->req.Capabilities = cpu_to_le32(capabilities);
772 iov[1].iov_base = msg->data + msg->sesskey_len;
773 iov[1].iov_len = msg->secblob_len;
774 pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
775
776 if (ses->capabilities & CAP_UNICODE) {
777
778 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
779 *bcc_ptr = 0;
780 bcc_ptr++;
781 }
782 unicode_oslm_strings(&bcc_ptr, nls_cp);
783 unicode_domain_string(&bcc_ptr, ses, nls_cp);
784 } else
785
786 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
787#else
788 cERROR(1, "Kerberos negotiated but upcall support disabled!");
789 rc = -ENOSYS;
790 goto ssetup_exit;
791#endif
792 } else if (type == RawNTLMSSP) {
793 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
794 cERROR(1, "NTLMSSP requires Unicode support");
795 rc = -ENOSYS;
796 goto ssetup_exit;
797 }
798
799 cFYI(1, "ntlmssp session setup phase %d", phase);
800 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
801 capabilities |= CAP_EXTENDED_SECURITY;
802 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
803 switch(phase) {
804 case NtLmNegotiate:
805 build_ntlmssp_negotiate_blob(
806 pSMB->req.SecurityBlob, ses);
807 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
808 iov[1].iov_base = pSMB->req.SecurityBlob;
809 pSMB->req.SecurityBlobLength =
810 cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
811 break;
812 case NtLmAuthenticate:
813
814
815
816
817
818 ntlmsspblob = kzalloc(
819 5*sizeof(struct _AUTHENTICATE_MESSAGE),
820 GFP_KERNEL);
821 if (!ntlmsspblob) {
822 cERROR(1, "Can't allocate NTLMSSP blob");
823 rc = -ENOMEM;
824 goto ssetup_exit;
825 }
826
827 rc = build_ntlmssp_auth_blob(ntlmsspblob,
828 &blob_len, ses, nls_cp);
829 if (rc)
830 goto ssetup_exit;
831 iov[1].iov_len = blob_len;
832 iov[1].iov_base = ntlmsspblob;
833 pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
834
835
836
837
838
839 smb_buf->Uid = ses->Suid;
840 break;
841 default:
842 cERROR(1, "invalid phase %d", phase);
843 rc = -ENOSYS;
844 goto ssetup_exit;
845 }
846
847 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
848 *bcc_ptr = 0;
849 bcc_ptr++;
850 }
851 unicode_oslm_strings(&bcc_ptr, nls_cp);
852 } else {
853 cERROR(1, "secType %d not supported!", type);
854 rc = -ENOSYS;
855 goto ssetup_exit;
856 }
857
858 iov[2].iov_base = str_area;
859 iov[2].iov_len = (long) bcc_ptr - (long) str_area;
860
861 count = iov[1].iov_len + iov[2].iov_len;
862 smb_buf->smb_buf_length =
863 cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
864
865 put_bcc(count, smb_buf);
866
867 rc = SendReceive2(xid, ses, iov, 3 , &resp_buf_type,
868 CIFS_LOG_ERROR);
869
870
871 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
872 smb_buf = (struct smb_hdr *)iov[0].iov_base;
873
874 if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
875 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
876 if (phase != NtLmNegotiate) {
877 cERROR(1, "Unexpected more processing error");
878 goto ssetup_exit;
879 }
880
881 phase = NtLmChallenge;
882 rc = 0;
883 }
884 if (rc)
885 goto ssetup_exit;
886
887 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
888 rc = -EIO;
889 cERROR(1, "bad word count %d", smb_buf->WordCount);
890 goto ssetup_exit;
891 }
892 action = le16_to_cpu(pSMB->resp.Action);
893 if (action & GUEST_LOGIN)
894 cFYI(1, "Guest login");
895 ses->Suid = smb_buf->Uid;
896 cFYI(1, "UID = %d ", ses->Suid);
897
898
899 bytes_remaining = get_bcc(smb_buf);
900 bcc_ptr = pByteArea(smb_buf);
901
902 if (smb_buf->WordCount == 4) {
903 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
904 if (blob_len > bytes_remaining) {
905 cERROR(1, "bad security blob length %d", blob_len);
906 rc = -EINVAL;
907 goto ssetup_exit;
908 }
909 if (phase == NtLmChallenge) {
910 rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
911
912 if (rc)
913 goto ssetup_exit;
914 }
915 bcc_ptr += blob_len;
916 bytes_remaining -= blob_len;
917 }
918
919
920 if (bytes_remaining == 0) {
921
922 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
923
924 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
925 ++bcc_ptr;
926 --bytes_remaining;
927 }
928 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
929 } else {
930 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
931 ses, nls_cp);
932 }
933
934ssetup_exit:
935 if (spnego_key) {
936 key_revoke(spnego_key);
937 key_put(spnego_key);
938 }
939 kfree(str_area);
940 kfree(ntlmsspblob);
941 ntlmsspblob = NULL;
942 if (resp_buf_type == CIFS_SMALL_BUFFER) {
943 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
944 cifs_small_buf_release(iov[0].iov_base);
945 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
946 cifs_buf_release(iov[0].iov_base);
947
948
949 if ((phase == NtLmChallenge) && (rc == 0))
950 goto ssetup_ntlmssp_authenticate;
951
952 return rc;
953}
954