1
2
3
4
5
6
7
8
9
10
11#include "cifspdu.h"
12#include "cifsglob.h"
13#include "cifsproto.h"
14#include "cifs_unicode.h"
15#include "cifs_debug.h"
16#include "ntlmssp.h"
17#include "nterr.h"
18#include <linux/utsname.h>
19#include <linux/slab.h>
20#include "cifs_spnego.h"
21#include "smb2proto.h"
22#include "fs_context.h"
23
24static int
25cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
26 struct cifs_server_iface *iface);
27
28bool
29is_server_using_iface(struct TCP_Server_Info *server,
30 struct cifs_server_iface *iface)
31{
32 struct sockaddr_in *i4 = (struct sockaddr_in *)&iface->sockaddr;
33 struct sockaddr_in6 *i6 = (struct sockaddr_in6 *)&iface->sockaddr;
34 struct sockaddr_in *s4 = (struct sockaddr_in *)&server->dstaddr;
35 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&server->dstaddr;
36
37 if (server->dstaddr.ss_family != iface->sockaddr.ss_family)
38 return false;
39 if (server->dstaddr.ss_family == AF_INET) {
40 if (s4->sin_addr.s_addr != i4->sin_addr.s_addr)
41 return false;
42 } else if (server->dstaddr.ss_family == AF_INET6) {
43 if (memcmp(&s6->sin6_addr, &i6->sin6_addr,
44 sizeof(i6->sin6_addr)) != 0)
45 return false;
46 } else {
47
48 return false;
49 }
50 return true;
51}
52
53bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface)
54{
55 int i;
56
57 for (i = 0; i < ses->chan_count; i++) {
58 if (is_server_using_iface(ses->chans[i].server, iface))
59 return true;
60 }
61 return false;
62}
63
64
65int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
66{
67 int old_chan_count = ses->chan_count;
68 int left = ses->chan_max - ses->chan_count;
69 int i = 0;
70 int rc = 0;
71 int tries = 0;
72 struct cifs_server_iface *ifaces = NULL;
73 size_t iface_count;
74
75 if (left <= 0) {
76 cifs_dbg(FYI,
77 "ses already at max_channels (%zu), nothing to open\n",
78 ses->chan_max);
79 return 0;
80 }
81
82 if (ses->server->dialect < SMB30_PROT_ID) {
83 cifs_dbg(VFS, "multichannel is not supported on this protocol version, use 3.0 or above\n");
84 return 0;
85 }
86
87 if (!(ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
88 cifs_dbg(VFS, "server %s does not support multichannel\n", ses->server->hostname);
89 ses->chan_max = 1;
90 return 0;
91 }
92
93
94
95
96
97
98 spin_lock(&ses->iface_lock);
99 iface_count = ses->iface_count;
100 if (iface_count <= 0) {
101 spin_unlock(&ses->iface_lock);
102 cifs_dbg(VFS, "no iface list available to open channels\n");
103 return 0;
104 }
105 ifaces = kmemdup(ses->iface_list, iface_count*sizeof(*ifaces),
106 GFP_ATOMIC);
107 if (!ifaces) {
108 spin_unlock(&ses->iface_lock);
109 return 0;
110 }
111 spin_unlock(&ses->iface_lock);
112
113
114
115
116
117
118 while (left > 0) {
119 struct cifs_server_iface *iface;
120
121 tries++;
122 if (tries > 3*ses->chan_max) {
123 cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n",
124 left);
125 break;
126 }
127
128 iface = &ifaces[i];
129 if (is_ses_using_iface(ses, iface) && !iface->rss_capable) {
130 i = (i+1) % iface_count;
131 continue;
132 }
133
134 rc = cifs_ses_add_channel(cifs_sb, ses, iface);
135 if (rc) {
136 cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n",
137 i, rc);
138 i = (i+1) % iface_count;
139 continue;
140 }
141
142 cifs_dbg(FYI, "successfully opened new channel on iface#%d\n",
143 i);
144 left--;
145 }
146
147 kfree(ifaces);
148 return ses->chan_count - old_chan_count;
149}
150
151
152
153
154
155struct cifs_chan *
156cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
157{
158 int i;
159
160 for (i = 0; i < ses->chan_count; i++) {
161 if (ses->chans[i].server == server)
162 return &ses->chans[i];
163 }
164 return NULL;
165}
166
167static int
168cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
169 struct cifs_server_iface *iface)
170{
171 struct cifs_chan *chan;
172 struct smb3_fs_context ctx = {NULL};
173 static const char unc_fmt[] = "\\%s\\foo";
174 char unc[sizeof(unc_fmt)+SERVER_NAME_LEN_WITH_NULL] = {0};
175 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
176 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
177 int rc;
178 unsigned int xid = get_xid();
179
180 if (iface->sockaddr.ss_family == AF_INET)
181 cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
182 ses, iface->speed, iface->rdma_capable ? "yes" : "no",
183 &ipv4->sin_addr);
184 else
185 cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI6)\n",
186 ses, iface->speed, iface->rdma_capable ? "yes" : "no",
187 &ipv6->sin6_addr);
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 ctx.nosharesock = true;
203
204
205 ctx.domainauto = ses->domainAuto;
206 ctx.domainname = ses->domainName;
207 ctx.username = ses->user_name;
208 ctx.password = ses->password;
209 ctx.sectype = ses->sectype;
210 ctx.sign = ses->sign;
211
212
213
214 sprintf(unc, unc_fmt, ses->ip_addr);
215 ctx.UNC = unc;
216 ctx.prepath = "";
217
218
219 ctx.vals = ses->server->vals;
220 ctx.ops = ses->server->ops;
221
222 ctx.noblocksnd = ses->server->noblocksnd;
223 ctx.noautotune = ses->server->noautotune;
224 ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
225 ctx.echo_interval = ses->server->echo_interval / HZ;
226 ctx.max_credits = ses->server->max_credits;
227
228
229
230
231
232 ctx.local_nls = cifs_sb->local_nls;
233
234
235 ctx.rdma = iface->rdma_capable;
236 memcpy(&ctx.dstaddr, &iface->sockaddr, sizeof(struct sockaddr_storage));
237
238
239 memcpy(&ctx.client_guid, ses->server->client_guid,
240 SMB2_CLIENT_GUID_SIZE);
241 ctx.use_client_guid = true;
242
243 mutex_lock(&ses->session_mutex);
244
245 chan = ses->binding_chan = &ses->chans[ses->chan_count];
246 chan->server = cifs_get_tcp_session(&ctx);
247 if (IS_ERR(chan->server)) {
248 rc = PTR_ERR(chan->server);
249 chan->server = NULL;
250 goto out;
251 }
252 spin_lock(&cifs_tcp_ses_lock);
253 chan->server->is_channel = true;
254 spin_unlock(&cifs_tcp_ses_lock);
255
256
257
258
259
260
261 rc = smb311_crypto_shash_allocate(chan->server);
262 if (rc) {
263 cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__);
264 goto out;
265 }
266
267 ses->binding = true;
268 rc = cifs_negotiate_protocol(xid, ses);
269 if (rc)
270 goto out;
271
272 rc = cifs_setup_session(xid, ses, cifs_sb->local_nls);
273 if (rc)
274 goto out;
275
276
277
278
279
280
281
282
283
284
285
286 ses->chan_count++;
287 atomic_set(&ses->chan_seq, 0);
288out:
289 ses->binding = false;
290 ses->binding_chan = NULL;
291 mutex_unlock(&ses->session_mutex);
292
293 if (rc && chan->server)
294 cifs_put_tcp_session(chan->server, 0);
295
296 return rc;
297}
298
299static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
300{
301 __u32 capabilities = 0;
302
303
304
305
306
307
308 pSMB->req.AndXCommand = 0xFF;
309 pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
310 CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
311 USHRT_MAX));
312 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
313 pSMB->req.VcNumber = cpu_to_le16(1);
314
315
316
317
318
319
320 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
321 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
322
323 if (ses->server->sign)
324 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
325
326 if (ses->capabilities & CAP_UNICODE) {
327 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
328 capabilities |= CAP_UNICODE;
329 }
330 if (ses->capabilities & CAP_STATUS32) {
331 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
332 capabilities |= CAP_STATUS32;
333 }
334 if (ses->capabilities & CAP_DFS) {
335 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
336 capabilities |= CAP_DFS;
337 }
338 if (ses->capabilities & CAP_UNIX)
339 capabilities |= CAP_UNIX;
340
341 return capabilities;
342}
343
344static void
345unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
346{
347 char *bcc_ptr = *pbcc_area;
348 int bytes_ret = 0;
349
350
351 bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
352 nls_cp);
353 bcc_ptr += 2 * bytes_ret;
354 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
355 32, nls_cp);
356 bcc_ptr += 2 * bytes_ret;
357 bcc_ptr += 2;
358
359 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
360 32, nls_cp);
361 bcc_ptr += 2 * bytes_ret;
362 bcc_ptr += 2;
363
364 *pbcc_area = bcc_ptr;
365}
366
367static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
368 const struct nls_table *nls_cp)
369{
370 char *bcc_ptr = *pbcc_area;
371 int bytes_ret = 0;
372
373
374 if (ses->domainName == NULL) {
375
376
377 *bcc_ptr = 0;
378 *(bcc_ptr+1) = 0;
379 bytes_ret = 0;
380 } else
381 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
382 CIFS_MAX_DOMAINNAME_LEN, nls_cp);
383 bcc_ptr += 2 * bytes_ret;
384 bcc_ptr += 2;
385
386 *pbcc_area = bcc_ptr;
387}
388
389
390static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
391 const struct nls_table *nls_cp)
392{
393 char *bcc_ptr = *pbcc_area;
394 int bytes_ret = 0;
395
396
397
398
399
400
401
402
403
404
405 if (ses->user_name == NULL) {
406
407 *bcc_ptr = 0;
408 *(bcc_ptr+1) = 0;
409 } else {
410 bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
411 CIFS_MAX_USERNAME_LEN, nls_cp);
412 }
413 bcc_ptr += 2 * bytes_ret;
414 bcc_ptr += 2;
415
416 unicode_domain_string(&bcc_ptr, ses, nls_cp);
417 unicode_oslm_strings(&bcc_ptr, nls_cp);
418
419 *pbcc_area = bcc_ptr;
420}
421
422static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
423 const struct nls_table *nls_cp)
424{
425 char *bcc_ptr = *pbcc_area;
426 int len;
427
428
429
430
431 if (ses->user_name != NULL) {
432 len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
433 if (WARN_ON_ONCE(len < 0))
434 len = CIFS_MAX_USERNAME_LEN - 1;
435 bcc_ptr += len;
436 }
437
438 *bcc_ptr = 0;
439 bcc_ptr++;
440
441
442 if (ses->domainName != NULL) {
443 len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
444 if (WARN_ON_ONCE(len < 0))
445 len = CIFS_MAX_DOMAINNAME_LEN - 1;
446 bcc_ptr += len;
447 }
448
449 *bcc_ptr = 0;
450 bcc_ptr++;
451
452
453
454 strcpy(bcc_ptr, "Linux version ");
455 bcc_ptr += strlen("Linux version ");
456 strcpy(bcc_ptr, init_utsname()->release);
457 bcc_ptr += strlen(init_utsname()->release) + 1;
458
459 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
460 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
461
462 *pbcc_area = bcc_ptr;
463}
464
465static void
466decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
467 const struct nls_table *nls_cp)
468{
469 int len;
470 char *data = *pbcc_area;
471
472 cifs_dbg(FYI, "bleft %d\n", bleft);
473
474 kfree(ses->serverOS);
475 ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
476 cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
477 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
478 data += len;
479 bleft -= len;
480 if (bleft <= 0)
481 return;
482
483 kfree(ses->serverNOS);
484 ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
485 cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
486 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
487 data += len;
488 bleft -= len;
489 if (bleft <= 0)
490 return;
491
492 kfree(ses->serverDomain);
493 ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
494 cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
495
496 return;
497}
498
499static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
500 struct cifs_ses *ses,
501 const struct nls_table *nls_cp)
502{
503 int len;
504 char *bcc_ptr = *pbcc_area;
505
506 cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
507
508 len = strnlen(bcc_ptr, bleft);
509 if (len >= bleft)
510 return;
511
512 kfree(ses->serverOS);
513
514 ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
515 if (ses->serverOS) {
516 memcpy(ses->serverOS, bcc_ptr, len);
517 ses->serverOS[len] = 0;
518 if (strncmp(ses->serverOS, "OS/2", 4) == 0)
519 cifs_dbg(FYI, "OS/2 server\n");
520 }
521
522 bcc_ptr += len + 1;
523 bleft -= len + 1;
524
525 len = strnlen(bcc_ptr, bleft);
526 if (len >= bleft)
527 return;
528
529 kfree(ses->serverNOS);
530
531 ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
532 if (ses->serverNOS) {
533 memcpy(ses->serverNOS, bcc_ptr, len);
534 ses->serverNOS[len] = 0;
535 }
536
537 bcc_ptr += len + 1;
538 bleft -= len + 1;
539
540 len = strnlen(bcc_ptr, bleft);
541 if (len > bleft)
542 return;
543
544
545
546
547
548
549 cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
550}
551
552int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
553 struct cifs_ses *ses)
554{
555 unsigned int tioffset;
556 unsigned int tilen;
557
558 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
559
560 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
561 cifs_dbg(VFS, "challenge blob len %d too small\n", blob_len);
562 return -EINVAL;
563 }
564
565 if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
566 cifs_dbg(VFS, "blob signature incorrect %s\n",
567 pblob->Signature);
568 return -EINVAL;
569 }
570 if (pblob->MessageType != NtLmChallenge) {
571 cifs_dbg(VFS, "Incorrect message type %d\n",
572 pblob->MessageType);
573 return -EINVAL;
574 }
575
576 memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
577
578
579
580
581 ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
582 tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
583 tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
584 if (tioffset > blob_len || tioffset + tilen > blob_len) {
585 cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n",
586 tioffset, tilen);
587 return -EINVAL;
588 }
589 if (tilen) {
590 ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
591 GFP_KERNEL);
592 if (!ses->auth_key.response) {
593 cifs_dbg(VFS, "Challenge target info alloc failure\n");
594 return -ENOMEM;
595 }
596 ses->auth_key.len = tilen;
597 }
598
599 return 0;
600}
601
602
603
604
605
606void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
607 struct cifs_ses *ses)
608{
609 struct TCP_Server_Info *server = cifs_ses_server(ses);
610 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
611 __u32 flags;
612
613 memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
614 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
615 sec_blob->MessageType = NtLmNegotiate;
616
617
618 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
619 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
620 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
621 NTLMSSP_NEGOTIATE_SEAL;
622 if (server->sign)
623 flags |= NTLMSSP_NEGOTIATE_SIGN;
624 if (!server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
625 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
626
627 sec_blob->NegotiateFlags = cpu_to_le32(flags);
628
629 sec_blob->WorkstationName.BufferOffset = 0;
630 sec_blob->WorkstationName.Length = 0;
631 sec_blob->WorkstationName.MaximumLength = 0;
632
633
634 sec_blob->DomainName.BufferOffset = 0;
635 sec_blob->DomainName.Length = 0;
636 sec_blob->DomainName.MaximumLength = 0;
637}
638
639static int size_of_ntlmssp_blob(struct cifs_ses *ses)
640{
641 int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
642 - CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
643
644 if (ses->domainName)
645 sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
646 else
647 sz += 2;
648
649 if (ses->user_name)
650 sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
651 else
652 sz += 2;
653
654 return sz;
655}
656
657int build_ntlmssp_auth_blob(unsigned char **pbuffer,
658 u16 *buflen,
659 struct cifs_ses *ses,
660 const struct nls_table *nls_cp)
661{
662 int rc;
663 AUTHENTICATE_MESSAGE *sec_blob;
664 __u32 flags;
665 unsigned char *tmp;
666
667 rc = setup_ntlmv2_rsp(ses, nls_cp);
668 if (rc) {
669 cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
670 *buflen = 0;
671 goto setup_ntlmv2_ret;
672 }
673 *pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
674 if (!*pbuffer) {
675 rc = -ENOMEM;
676 cifs_dbg(VFS, "Error %d during NTLMSSP allocation\n", rc);
677 *buflen = 0;
678 goto setup_ntlmv2_ret;
679 }
680 sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
681
682 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
683 sec_blob->MessageType = NtLmAuthenticate;
684
685 flags = NTLMSSP_NEGOTIATE_56 |
686 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
687 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
688 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC |
689 NTLMSSP_NEGOTIATE_SEAL;
690 if (ses->server->sign)
691 flags |= NTLMSSP_NEGOTIATE_SIGN;
692 if (!ses->server->session_estab || ses->ntlmssp->sesskey_per_smbsess)
693 flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
694
695 tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
696 sec_blob->NegotiateFlags = cpu_to_le32(flags);
697
698 sec_blob->LmChallengeResponse.BufferOffset =
699 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
700 sec_blob->LmChallengeResponse.Length = 0;
701 sec_blob->LmChallengeResponse.MaximumLength = 0;
702
703 sec_blob->NtChallengeResponse.BufferOffset =
704 cpu_to_le32(tmp - *pbuffer);
705 if (ses->user_name != NULL) {
706 memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
707 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
708 tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
709
710 sec_blob->NtChallengeResponse.Length =
711 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
712 sec_blob->NtChallengeResponse.MaximumLength =
713 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
714 } else {
715
716
717
718 sec_blob->NtChallengeResponse.Length = 0;
719 sec_blob->NtChallengeResponse.MaximumLength = 0;
720 }
721
722 if (ses->domainName == NULL) {
723 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
724 sec_blob->DomainName.Length = 0;
725 sec_blob->DomainName.MaximumLength = 0;
726 tmp += 2;
727 } else {
728 int len;
729 len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
730 CIFS_MAX_DOMAINNAME_LEN, nls_cp);
731 len *= 2;
732 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
733 sec_blob->DomainName.Length = cpu_to_le16(len);
734 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
735 tmp += len;
736 }
737
738 if (ses->user_name == NULL) {
739 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
740 sec_blob->UserName.Length = 0;
741 sec_blob->UserName.MaximumLength = 0;
742 tmp += 2;
743 } else {
744 int len;
745 len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
746 CIFS_MAX_USERNAME_LEN, nls_cp);
747 len *= 2;
748 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
749 sec_blob->UserName.Length = cpu_to_le16(len);
750 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
751 tmp += len;
752 }
753
754 sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
755 sec_blob->WorkstationName.Length = 0;
756 sec_blob->WorkstationName.MaximumLength = 0;
757 tmp += 2;
758
759 if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
760 (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
761 && !calc_seckey(ses)) {
762 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
763 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
764 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
765 sec_blob->SessionKey.MaximumLength =
766 cpu_to_le16(CIFS_CPHTXT_SIZE);
767 tmp += CIFS_CPHTXT_SIZE;
768 } else {
769 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
770 sec_blob->SessionKey.Length = 0;
771 sec_blob->SessionKey.MaximumLength = 0;
772 }
773
774 *buflen = tmp - *pbuffer;
775setup_ntlmv2_ret:
776 return rc;
777}
778
779enum securityEnum
780cifs_select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
781{
782 switch (server->negflavor) {
783 case CIFS_NEGFLAVOR_EXTENDED:
784 switch (requested) {
785 case Kerberos:
786 case RawNTLMSSP:
787 return requested;
788 case Unspecified:
789 if (server->sec_ntlmssp &&
790 (global_secflags & CIFSSEC_MAY_NTLMSSP))
791 return RawNTLMSSP;
792 if ((server->sec_kerberos || server->sec_mskerberos) &&
793 (global_secflags & CIFSSEC_MAY_KRB5))
794 return Kerberos;
795 fallthrough;
796 default:
797 return Unspecified;
798 }
799 case CIFS_NEGFLAVOR_UNENCAP:
800 switch (requested) {
801 case NTLMv2:
802 return requested;
803 case Unspecified:
804 if (global_secflags & CIFSSEC_MAY_NTLMV2)
805 return NTLMv2;
806 break;
807 default:
808 break;
809 }
810 fallthrough;
811 default:
812 return Unspecified;
813 }
814}
815
816struct sess_data {
817 unsigned int xid;
818 struct cifs_ses *ses;
819 struct nls_table *nls_cp;
820 void (*func)(struct sess_data *);
821 int result;
822
823
824
825
826
827
828
829
830 int buf0_type;
831 struct kvec iov[3];
832};
833
834static int
835sess_alloc_buffer(struct sess_data *sess_data, int wct)
836{
837 int rc;
838 struct cifs_ses *ses = sess_data->ses;
839 struct smb_hdr *smb_buf;
840
841 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
842 (void **)&smb_buf);
843
844 if (rc)
845 return rc;
846
847 sess_data->iov[0].iov_base = (char *)smb_buf;
848 sess_data->iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
849
850
851
852
853 sess_data->buf0_type = CIFS_SMALL_BUFFER;
854
855
856 sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
857 if (!sess_data->iov[2].iov_base) {
858 rc = -ENOMEM;
859 goto out_free_smb_buf;
860 }
861
862 return 0;
863
864out_free_smb_buf:
865 cifs_small_buf_release(smb_buf);
866 sess_data->iov[0].iov_base = NULL;
867 sess_data->iov[0].iov_len = 0;
868 sess_data->buf0_type = CIFS_NO_BUFFER;
869 return rc;
870}
871
872static void
873sess_free_buffer(struct sess_data *sess_data)
874{
875
876 free_rsp_buf(sess_data->buf0_type, sess_data->iov[0].iov_base);
877 sess_data->buf0_type = CIFS_NO_BUFFER;
878 kfree(sess_data->iov[2].iov_base);
879}
880
881static int
882sess_establish_session(struct sess_data *sess_data)
883{
884 struct cifs_ses *ses = sess_data->ses;
885
886 mutex_lock(&ses->server->srv_mutex);
887 if (!ses->server->session_estab) {
888 if (ses->server->sign) {
889 ses->server->session_key.response =
890 kmemdup(ses->auth_key.response,
891 ses->auth_key.len, GFP_KERNEL);
892 if (!ses->server->session_key.response) {
893 mutex_unlock(&ses->server->srv_mutex);
894 return -ENOMEM;
895 }
896 ses->server->session_key.len =
897 ses->auth_key.len;
898 }
899 ses->server->sequence_number = 0x2;
900 ses->server->session_estab = true;
901 }
902 mutex_unlock(&ses->server->srv_mutex);
903
904 cifs_dbg(FYI, "CIFS session established successfully\n");
905 spin_lock(&GlobalMid_Lock);
906 ses->status = CifsGood;
907 ses->need_reconnect = false;
908 spin_unlock(&GlobalMid_Lock);
909
910 return 0;
911}
912
913static int
914sess_sendreceive(struct sess_data *sess_data)
915{
916 int rc;
917 struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
918 __u16 count;
919 struct kvec rsp_iov = { NULL, 0 };
920
921 count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
922 be32_add_cpu(&smb_buf->smb_buf_length, count);
923 put_bcc(count, smb_buf);
924
925 rc = SendReceive2(sess_data->xid, sess_data->ses,
926 sess_data->iov, 3 ,
927 &sess_data->buf0_type,
928 CIFS_LOG_ERROR, &rsp_iov);
929 cifs_small_buf_release(sess_data->iov[0].iov_base);
930 memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
931
932 return rc;
933}
934
935static void
936sess_auth_ntlmv2(struct sess_data *sess_data)
937{
938 int rc = 0;
939 struct smb_hdr *smb_buf;
940 SESSION_SETUP_ANDX *pSMB;
941 char *bcc_ptr;
942 struct cifs_ses *ses = sess_data->ses;
943 __u32 capabilities;
944 __u16 bytes_remaining;
945
946
947
948 rc = sess_alloc_buffer(sess_data, 13);
949 if (rc)
950 goto out;
951
952 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
953 bcc_ptr = sess_data->iov[2].iov_base;
954 capabilities = cifs_ssetup_hdr(ses, pSMB);
955
956 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
957
958
959 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
960
961 if (ses->user_name != NULL) {
962
963 rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
964 if (rc) {
965 cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
966 goto out;
967 }
968
969 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
970 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
971 bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
972
973
974
975
976 pSMB->req_no_secext.CaseSensitivePasswordLength =
977 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
978 } else {
979 pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
980 }
981
982 if (ses->capabilities & CAP_UNICODE) {
983 if (sess_data->iov[0].iov_len % 2) {
984 *bcc_ptr = 0;
985 bcc_ptr++;
986 }
987 unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
988 } else {
989 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
990 }
991
992
993 sess_data->iov[2].iov_len = (long) bcc_ptr -
994 (long) sess_data->iov[2].iov_base;
995
996 rc = sess_sendreceive(sess_data);
997 if (rc)
998 goto out;
999
1000 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1001 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1002
1003 if (smb_buf->WordCount != 3) {
1004 rc = -EIO;
1005 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1006 goto out;
1007 }
1008
1009 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1010 cifs_dbg(FYI, "Guest login\n");
1011
1012 ses->Suid = smb_buf->Uid;
1013 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1014
1015 bytes_remaining = get_bcc(smb_buf);
1016 bcc_ptr = pByteArea(smb_buf);
1017
1018
1019 if (bytes_remaining == 0) {
1020
1021 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1022
1023 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1024 ++bcc_ptr;
1025 --bytes_remaining;
1026 }
1027 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1028 sess_data->nls_cp);
1029 } else {
1030 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1031 sess_data->nls_cp);
1032 }
1033
1034 rc = sess_establish_session(sess_data);
1035out:
1036 sess_data->result = rc;
1037 sess_data->func = NULL;
1038 sess_free_buffer(sess_data);
1039 kfree(ses->auth_key.response);
1040 ses->auth_key.response = NULL;
1041}
1042
1043#ifdef CONFIG_CIFS_UPCALL
1044static void
1045sess_auth_kerberos(struct sess_data *sess_data)
1046{
1047 int rc = 0;
1048 struct smb_hdr *smb_buf;
1049 SESSION_SETUP_ANDX *pSMB;
1050 char *bcc_ptr;
1051 struct cifs_ses *ses = sess_data->ses;
1052 __u32 capabilities;
1053 __u16 bytes_remaining;
1054 struct key *spnego_key = NULL;
1055 struct cifs_spnego_msg *msg;
1056 u16 blob_len;
1057
1058
1059
1060 rc = sess_alloc_buffer(sess_data, 12);
1061 if (rc)
1062 goto out;
1063
1064 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1065 bcc_ptr = sess_data->iov[2].iov_base;
1066 capabilities = cifs_ssetup_hdr(ses, pSMB);
1067
1068 spnego_key = cifs_get_spnego_key(ses);
1069 if (IS_ERR(spnego_key)) {
1070 rc = PTR_ERR(spnego_key);
1071 spnego_key = NULL;
1072 goto out;
1073 }
1074
1075 msg = spnego_key->payload.data[0];
1076
1077
1078
1079
1080 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1081 cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
1082 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1083 rc = -EKEYREJECTED;
1084 goto out_put_spnego_key;
1085 }
1086
1087 ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1088 GFP_KERNEL);
1089 if (!ses->auth_key.response) {
1090 cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
1091 msg->sesskey_len);
1092 rc = -ENOMEM;
1093 goto out_put_spnego_key;
1094 }
1095 ses->auth_key.len = msg->sesskey_len;
1096
1097 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1098 capabilities |= CAP_EXTENDED_SECURITY;
1099 pSMB->req.Capabilities = cpu_to_le32(capabilities);
1100 sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
1101 sess_data->iov[1].iov_len = msg->secblob_len;
1102 pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
1103
1104 if (ses->capabilities & CAP_UNICODE) {
1105
1106 if ((sess_data->iov[0].iov_len
1107 + sess_data->iov[1].iov_len) % 2) {
1108 *bcc_ptr = 0;
1109 bcc_ptr++;
1110 }
1111 unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1112 unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp);
1113 } else {
1114
1115 ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp);
1116 }
1117
1118 sess_data->iov[2].iov_len = (long) bcc_ptr -
1119 (long) sess_data->iov[2].iov_base;
1120
1121 rc = sess_sendreceive(sess_data);
1122 if (rc)
1123 goto out_put_spnego_key;
1124
1125 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1126 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1127
1128 if (smb_buf->WordCount != 4) {
1129 rc = -EIO;
1130 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1131 goto out_put_spnego_key;
1132 }
1133
1134 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1135 cifs_dbg(FYI, "Guest login\n");
1136
1137 ses->Suid = smb_buf->Uid;
1138 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1139
1140 bytes_remaining = get_bcc(smb_buf);
1141 bcc_ptr = pByteArea(smb_buf);
1142
1143 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1144 if (blob_len > bytes_remaining) {
1145 cifs_dbg(VFS, "bad security blob length %d\n",
1146 blob_len);
1147 rc = -EINVAL;
1148 goto out_put_spnego_key;
1149 }
1150 bcc_ptr += blob_len;
1151 bytes_remaining -= blob_len;
1152
1153
1154 if (bytes_remaining == 0) {
1155
1156 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1157
1158 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1159 ++bcc_ptr;
1160 --bytes_remaining;
1161 }
1162 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1163 sess_data->nls_cp);
1164 } else {
1165 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1166 sess_data->nls_cp);
1167 }
1168
1169 rc = sess_establish_session(sess_data);
1170out_put_spnego_key:
1171 key_invalidate(spnego_key);
1172 key_put(spnego_key);
1173out:
1174 sess_data->result = rc;
1175 sess_data->func = NULL;
1176 sess_free_buffer(sess_data);
1177 kfree(ses->auth_key.response);
1178 ses->auth_key.response = NULL;
1179}
1180
1181#endif
1182
1183
1184
1185
1186
1187static int
1188_sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
1189{
1190 SESSION_SETUP_ANDX *pSMB;
1191 struct cifs_ses *ses = sess_data->ses;
1192 __u32 capabilities;
1193 char *bcc_ptr;
1194
1195 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1196
1197 capabilities = cifs_ssetup_hdr(ses, pSMB);
1198 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
1199 cifs_dbg(VFS, "NTLMSSP requires Unicode support\n");
1200 return -ENOSYS;
1201 }
1202
1203 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
1204 capabilities |= CAP_EXTENDED_SECURITY;
1205 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
1206
1207 bcc_ptr = sess_data->iov[2].iov_base;
1208
1209 if ((sess_data->iov[0].iov_len + sess_data->iov[1].iov_len) % 2) {
1210 *bcc_ptr = 0;
1211 bcc_ptr++;
1212 }
1213 unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
1214
1215 sess_data->iov[2].iov_len = (long) bcc_ptr -
1216 (long) sess_data->iov[2].iov_base;
1217
1218 return 0;
1219}
1220
1221static void
1222sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
1223
1224static void
1225sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
1226{
1227 int rc;
1228 struct smb_hdr *smb_buf;
1229 SESSION_SETUP_ANDX *pSMB;
1230 struct cifs_ses *ses = sess_data->ses;
1231 __u16 bytes_remaining;
1232 char *bcc_ptr;
1233 u16 blob_len;
1234
1235 cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
1236
1237
1238
1239
1240
1241 ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
1242 if (!ses->ntlmssp) {
1243 rc = -ENOMEM;
1244 goto out;
1245 }
1246 ses->ntlmssp->sesskey_per_smbsess = false;
1247
1248
1249 rc = sess_alloc_buffer(sess_data, 12);
1250 if (rc)
1251 goto out;
1252
1253 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1254
1255
1256 build_ntlmssp_negotiate_blob(pSMB->req.SecurityBlob, ses);
1257 sess_data->iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
1258 sess_data->iov[1].iov_base = pSMB->req.SecurityBlob;
1259 pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
1260
1261 rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1262 if (rc)
1263 goto out;
1264
1265 rc = sess_sendreceive(sess_data);
1266
1267 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1268 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1269
1270
1271 if (sess_data->buf0_type != CIFS_NO_BUFFER &&
1272 smb_buf->Status.CifsError ==
1273 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
1274 rc = 0;
1275
1276 if (rc)
1277 goto out;
1278
1279 cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
1280
1281 if (smb_buf->WordCount != 4) {
1282 rc = -EIO;
1283 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1284 goto out;
1285 }
1286
1287 ses->Suid = smb_buf->Uid;
1288 cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
1289
1290 bytes_remaining = get_bcc(smb_buf);
1291 bcc_ptr = pByteArea(smb_buf);
1292
1293 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1294 if (blob_len > bytes_remaining) {
1295 cifs_dbg(VFS, "bad security blob length %d\n",
1296 blob_len);
1297 rc = -EINVAL;
1298 goto out;
1299 }
1300
1301 rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
1302out:
1303 sess_free_buffer(sess_data);
1304
1305 if (!rc) {
1306 sess_data->func = sess_auth_rawntlmssp_authenticate;
1307 return;
1308 }
1309
1310
1311 kfree(ses->auth_key.response);
1312 ses->auth_key.response = NULL;
1313 kfree(ses->ntlmssp);
1314 ses->ntlmssp = NULL;
1315
1316 sess_data->func = NULL;
1317 sess_data->result = rc;
1318}
1319
1320static void
1321sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
1322{
1323 int rc;
1324 struct smb_hdr *smb_buf;
1325 SESSION_SETUP_ANDX *pSMB;
1326 struct cifs_ses *ses = sess_data->ses;
1327 __u16 bytes_remaining;
1328 char *bcc_ptr;
1329 unsigned char *ntlmsspblob = NULL;
1330 u16 blob_len;
1331
1332 cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
1333
1334
1335 rc = sess_alloc_buffer(sess_data, 12);
1336 if (rc)
1337 goto out;
1338
1339
1340 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1341 smb_buf = (struct smb_hdr *)pSMB;
1342 rc = build_ntlmssp_auth_blob(&ntlmsspblob,
1343 &blob_len, ses, sess_data->nls_cp);
1344 if (rc)
1345 goto out_free_ntlmsspblob;
1346 sess_data->iov[1].iov_len = blob_len;
1347 sess_data->iov[1].iov_base = ntlmsspblob;
1348 pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
1349
1350
1351
1352
1353
1354 smb_buf->Uid = ses->Suid;
1355
1356 rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
1357 if (rc)
1358 goto out_free_ntlmsspblob;
1359
1360 rc = sess_sendreceive(sess_data);
1361 if (rc)
1362 goto out_free_ntlmsspblob;
1363
1364 pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
1365 smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
1366 if (smb_buf->WordCount != 4) {
1367 rc = -EIO;
1368 cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
1369 goto out_free_ntlmsspblob;
1370 }
1371
1372 if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
1373 cifs_dbg(FYI, "Guest login\n");
1374
1375 if (ses->Suid != smb_buf->Uid) {
1376 ses->Suid = smb_buf->Uid;
1377 cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
1378 }
1379
1380 bytes_remaining = get_bcc(smb_buf);
1381 bcc_ptr = pByteArea(smb_buf);
1382 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
1383 if (blob_len > bytes_remaining) {
1384 cifs_dbg(VFS, "bad security blob length %d\n",
1385 blob_len);
1386 rc = -EINVAL;
1387 goto out_free_ntlmsspblob;
1388 }
1389 bcc_ptr += blob_len;
1390 bytes_remaining -= blob_len;
1391
1392
1393
1394 if (bytes_remaining == 0) {
1395
1396 } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
1397
1398 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
1399 ++bcc_ptr;
1400 --bytes_remaining;
1401 }
1402 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses,
1403 sess_data->nls_cp);
1404 } else {
1405 decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,
1406 sess_data->nls_cp);
1407 }
1408
1409out_free_ntlmsspblob:
1410 kfree(ntlmsspblob);
1411out:
1412 sess_free_buffer(sess_data);
1413
1414 if (!rc)
1415 rc = sess_establish_session(sess_data);
1416
1417
1418 kfree(ses->auth_key.response);
1419 ses->auth_key.response = NULL;
1420 kfree(ses->ntlmssp);
1421 ses->ntlmssp = NULL;
1422
1423 sess_data->func = NULL;
1424 sess_data->result = rc;
1425}
1426
1427static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
1428{
1429 int type;
1430
1431 type = cifs_select_sectype(ses->server, ses->sectype);
1432 cifs_dbg(FYI, "sess setup type %d\n", type);
1433 if (type == Unspecified) {
1434 cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
1435 return -EINVAL;
1436 }
1437
1438 switch (type) {
1439 case NTLMv2:
1440 sess_data->func = sess_auth_ntlmv2;
1441 break;
1442 case Kerberos:
1443#ifdef CONFIG_CIFS_UPCALL
1444 sess_data->func = sess_auth_kerberos;
1445 break;
1446#else
1447 cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
1448 return -ENOSYS;
1449#endif
1450 case RawNTLMSSP:
1451 sess_data->func = sess_auth_rawntlmssp_negotiate;
1452 break;
1453 default:
1454 cifs_dbg(VFS, "secType %d not supported!\n", type);
1455 return -ENOSYS;
1456 }
1457
1458 return 0;
1459}
1460
1461int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
1462 const struct nls_table *nls_cp)
1463{
1464 int rc = 0;
1465 struct sess_data *sess_data;
1466
1467 if (ses == NULL) {
1468 WARN(1, "%s: ses == NULL!", __func__);
1469 return -EINVAL;
1470 }
1471
1472 sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL);
1473 if (!sess_data)
1474 return -ENOMEM;
1475
1476 rc = select_sec(ses, sess_data);
1477 if (rc)
1478 goto out;
1479
1480 sess_data->xid = xid;
1481 sess_data->ses = ses;
1482 sess_data->buf0_type = CIFS_NO_BUFFER;
1483 sess_data->nls_cp = (struct nls_table *) nls_cp;
1484
1485 while (sess_data->func)
1486 sess_data->func(sess_data);
1487
1488
1489 rc = sess_data->result;
1490
1491out:
1492 kfree(sess_data);
1493 return rc;
1494}
1495