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