]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/sess.c
Merge branch 'for-linus' of git://android.git.kernel.org/kernel/tegra
[net-next-2.6.git] / fs / cifs / sess.c
CommitLineData
3979877e
SF
1/*
2 * fs/cifs/sess.c
3 *
4 * SMB/CIFS session setup handling routines
5 *
d185cda7 6 * Copyright (c) International Business Machines Corp., 2006, 2009
3979877e
SF
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"
9c53588e 31#include <linux/utsname.h>
5a0e3ad6 32#include <linux/slab.h>
2442421b 33#include "cifs_spnego.h"
3979877e 34
3979877e 35extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
790fe579 36 unsigned char *p24);
3979877e 37
ebe6aa5a
JL
38/*
39 * Checks if this is the first smb session to be reconnected after
40 * the socket has been reestablished (so we know whether to use vc 0).
41 * Called while holding the cifs_tcp_ses_lock, so do not block
42 */
eca6acf9
SF
43static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
44{
45 struct list_head *tmp;
46 struct cifsSesInfo *tmp_ses;
47
48 list_for_each(tmp, &ses->server->smb_ses_list) {
49 tmp_ses = list_entry(tmp, struct cifsSesInfo,
50 smb_ses_list);
51 if (tmp_ses->need_reconnect == false)
52 return false;
53 }
54 /* could not find a session that was already connected,
55 this must be the first one we are reconnecting */
56 return true;
57}
58
59/*
60 * vc number 0 is treated specially by some servers, and should be the
61 * first one we request. After that we can use vcnumbers up to maxvcs,
62 * one for each smb session (some Windows versions set maxvcs incorrectly
63 * so maxvc=1 can be ignored). If we have too many vcs, we can reuse
64 * any vc but zero (some servers reset the connection on vcnum zero)
65 *
66 */
67static __le16 get_next_vcnum(struct cifsSesInfo *ses)
68{
69 __u16 vcnum = 0;
70 struct list_head *tmp;
71 struct cifsSesInfo *tmp_ses;
72 __u16 max_vcs = ses->server->max_vcs;
73 __u16 i;
74 int free_vc_found = 0;
75
76 /* Quoting the MS-SMB specification: "Windows-based SMB servers set this
77 field to one but do not enforce this limit, which allows an SMB client
78 to establish more virtual circuits than allowed by this value ... but
79 other server implementations can enforce this limit." */
80 if (max_vcs < 2)
81 max_vcs = 0xFFFF;
82
83 write_lock(&cifs_tcp_ses_lock);
84 if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
85 goto get_vc_num_exit; /* vcnum will be zero */
86 for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
87 if (i == 0) /* this is the only connection, use vc 0 */
88 break;
89
90 free_vc_found = 1;
91
92 list_for_each(tmp, &ses->server->smb_ses_list) {
93 tmp_ses = list_entry(tmp, struct cifsSesInfo,
94 smb_ses_list);
95 if (tmp_ses->vcnum == i) {
96 free_vc_found = 0;
97 break; /* found duplicate, try next vcnum */
98 }
99 }
100 if (free_vc_found)
101 break; /* we found a vcnumber that will work - use it */
102 }
103
104 if (i == 0)
105 vcnum = 0; /* for most common case, ie if one smb session, use
106 vc zero. Also for case when no free vcnum, zero
107 is safest to send (some clients only send zero) */
108 else if (free_vc_found == 0)
109 vcnum = 1; /* we can not reuse vc=0 safely, since some servers
110 reset all uids on that, but 1 is ok. */
111 else
112 vcnum = i;
113 ses->vcnum = vcnum;
114get_vc_num_exit:
115 write_unlock(&cifs_tcp_ses_lock);
116
051a2a0d 117 return cpu_to_le16(vcnum);
eca6acf9
SF
118}
119
3979877e
SF
120static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
121{
122 __u32 capabilities = 0;
123
124 /* init fields common to all four types of SessSetup */
eca6acf9
SF
125 /* Note that offsets for first seven fields in req struct are same */
126 /* in CIFS Specs so does not matter which of 3 forms of struct */
127 /* that we use in next few lines */
128 /* Note that header is initialized to zero in header_assemble */
3979877e
SF
129 pSMB->req.AndXCommand = 0xFF;
130 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
131 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
eca6acf9 132 pSMB->req.VcNumber = get_next_vcnum(ses);
3979877e
SF
133
134 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
135
790fe579 136 /* BB verify whether signing required on neg or just on auth frame
3979877e
SF
137 (and NTLM case) */
138
139 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
140 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
141
790fe579
SF
142 if (ses->server->secMode &
143 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3979877e
SF
144 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
145
146 if (ses->capabilities & CAP_UNICODE) {
147 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
148 capabilities |= CAP_UNICODE;
149 }
150 if (ses->capabilities & CAP_STATUS32) {
151 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
152 capabilities |= CAP_STATUS32;
153 }
154 if (ses->capabilities & CAP_DFS) {
155 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
156 capabilities |= CAP_DFS;
157 }
26f57364 158 if (ses->capabilities & CAP_UNIX)
3979877e 159 capabilities |= CAP_UNIX;
3979877e 160
3979877e
SF
161 return capabilities;
162}
163
0d3a01fa
JL
164static void
165unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
166{
167 char *bcc_ptr = *pbcc_area;
168 int bytes_ret = 0;
169
170 /* Copy OS version */
171 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
172 nls_cp);
173 bcc_ptr += 2 * bytes_ret;
174 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
175 32, nls_cp);
176 bcc_ptr += 2 * bytes_ret;
177 bcc_ptr += 2; /* trailing null */
178
179 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
180 32, nls_cp);
181 bcc_ptr += 2 * bytes_ret;
182 bcc_ptr += 2; /* trailing null */
183
184 *pbcc_area = bcc_ptr;
185}
186
187static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
188 const struct nls_table *nls_cp)
189{
190 char *bcc_ptr = *pbcc_area;
191 int bytes_ret = 0;
192
193 /* copy domain */
194 if (ses->domainName == NULL) {
195 /* Sending null domain better than using a bogus domain name (as
196 we did briefly in 2.6.18) since server will use its default */
197 *bcc_ptr = 0;
198 *(bcc_ptr+1) = 0;
199 bytes_ret = 0;
200 } else
201 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
202 256, nls_cp);
203 bcc_ptr += 2 * bytes_ret;
204 bcc_ptr += 2; /* account for null terminator */
205
206 *pbcc_area = bcc_ptr;
207}
208
209
3870253e 210static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 211 const struct nls_table *nls_cp)
3979877e 212{
790fe579 213 char *bcc_ptr = *pbcc_area;
3979877e
SF
214 int bytes_ret = 0;
215
216 /* BB FIXME add check that strings total less
217 than 335 or will need to send them as arrays */
218
0223cf0b
SF
219 /* unicode strings, must be word aligned before the call */
220/* if ((long) bcc_ptr % 2) {
3979877e
SF
221 *bcc_ptr = 0;
222 bcc_ptr++;
0223cf0b 223 } */
3979877e 224 /* copy user */
790fe579 225 if (ses->userName == NULL) {
6e659c63
SF
226 /* null user mount */
227 *bcc_ptr = 0;
228 *(bcc_ptr+1) = 0;
301a6a31 229 } else {
3979877e 230 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
301a6a31 231 MAX_USERNAME_SIZE, nls_cp);
3979877e
SF
232 }
233 bcc_ptr += 2 * bytes_ret;
234 bcc_ptr += 2; /* account for null termination */
3979877e 235
0d3a01fa
JL
236 unicode_domain_string(&bcc_ptr, ses, nls_cp);
237 unicode_oslm_strings(&bcc_ptr, nls_cp);
3979877e
SF
238
239 *pbcc_area = bcc_ptr;
240}
241
3870253e 242static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 243 const struct nls_table *nls_cp)
3979877e 244{
790fe579 245 char *bcc_ptr = *pbcc_area;
3979877e
SF
246
247 /* copy user */
248 /* BB what about null user mounts - check that we do this BB */
790fe579
SF
249 /* copy user */
250 if (ses->userName == NULL) {
251 /* BB what about null user mounts - check that we do this BB */
301a6a31
SF
252 } else {
253 strncpy(bcc_ptr, ses->userName, MAX_USERNAME_SIZE);
790fe579 254 }
301a6a31 255 bcc_ptr += strnlen(ses->userName, MAX_USERNAME_SIZE);
3979877e 256 *bcc_ptr = 0;
790fe579 257 bcc_ptr++; /* account for null termination */
3979877e 258
790fe579
SF
259 /* copy domain */
260
261 if (ses->domainName != NULL) {
262 strncpy(bcc_ptr, ses->domainName, 256);
3979877e 263 bcc_ptr += strnlen(ses->domainName, 256);
790fe579 264 } /* else we will send a null domain name
6e659c63 265 so the server will default to its own domain */
3979877e
SF
266 *bcc_ptr = 0;
267 bcc_ptr++;
268
269 /* BB check for overflow here */
270
271 strcpy(bcc_ptr, "Linux version ");
272 bcc_ptr += strlen("Linux version ");
96b644bd
SH
273 strcpy(bcc_ptr, init_utsname()->release);
274 bcc_ptr += strlen(init_utsname()->release) + 1;
3979877e
SF
275
276 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
277 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
278
790fe579 279 *pbcc_area = bcc_ptr;
3979877e
SF
280}
281
59140797
JL
282static void
283decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
284 const struct nls_table *nls_cp)
3979877e 285{
59140797 286 int len;
790fe579 287 char *data = *pbcc_area;
3979877e 288
b6b38f70 289 cFYI(1, "bleft %d", bleft);
3979877e 290
27b87fe5
JL
291 /*
292 * Windows servers do not always double null terminate their final
293 * Unicode string. Check to see if there are an uneven number of bytes
294 * left. If so, then add an extra NULL pad byte to the end of the
295 * response.
296 *
297 * See section 2.7.2 in "Implementing CIFS" for details
298 */
299 if (bleft % 2) {
300 data[bleft] = 0;
301 ++bleft;
302 }
50c2f753 303
26f57364 304 kfree(ses->serverOS);
d185cda7 305 ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f70 306 cFYI(1, "serverOS=%s", ses->serverOS);
59140797
JL
307 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
308 data += len;
309 bleft -= len;
310 if (bleft <= 0)
311 return;
3979877e 312
26f57364 313 kfree(ses->serverNOS);
d185cda7 314 ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f70 315 cFYI(1, "serverNOS=%s", ses->serverNOS);
59140797
JL
316 len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
317 data += len;
318 bleft -= len;
319 if (bleft <= 0)
320 return;
790fe579 321
26f57364 322 kfree(ses->serverDomain);
d185cda7 323 ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);
b6b38f70 324 cFYI(1, "serverDomain=%s", ses->serverDomain);
790fe579 325
59140797 326 return;
3979877e
SF
327}
328
790fe579
SF
329static int decode_ascii_ssetup(char **pbcc_area, int bleft,
330 struct cifsSesInfo *ses,
331 const struct nls_table *nls_cp)
3979877e
SF
332{
333 int rc = 0;
334 int len;
790fe579 335 char *bcc_ptr = *pbcc_area;
3979877e 336
b6b38f70 337 cFYI(1, "decode sessetup ascii. bleft %d", bleft);
50c2f753 338
3979877e 339 len = strnlen(bcc_ptr, bleft);
790fe579 340 if (len >= bleft)
3979877e 341 return rc;
50c2f753 342
26f57364 343 kfree(ses->serverOS);
3979877e
SF
344
345 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 346 if (ses->serverOS)
3979877e 347 strncpy(ses->serverOS, bcc_ptr, len);
790fe579 348 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
b6b38f70 349 cFYI(1, "OS/2 server");
9ac00b7d
SF
350 ses->flags |= CIFS_SES_OS2;
351 }
3979877e
SF
352
353 bcc_ptr += len + 1;
354 bleft -= len + 1;
355
356 len = strnlen(bcc_ptr, bleft);
790fe579 357 if (len >= bleft)
3979877e
SF
358 return rc;
359
26f57364 360 kfree(ses->serverNOS);
3979877e
SF
361
362 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 363 if (ses->serverNOS)
3979877e
SF
364 strncpy(ses->serverNOS, bcc_ptr, len);
365
366 bcc_ptr += len + 1;
367 bleft -= len + 1;
368
790fe579
SF
369 len = strnlen(bcc_ptr, bleft);
370 if (len > bleft)
371 return rc;
3979877e 372
9ac00b7d
SF
373 /* No domain field in LANMAN case. Domain is
374 returned by old servers in the SMB negprot response */
375 /* BB For newer servers which do not support Unicode,
376 but thus do return domain here we could add parsing
377 for it later, but it is not very important */
b6b38f70 378 cFYI(1, "ascii: bytes left %d", bleft);
3979877e
SF
379
380 return rc;
381}
382
0b3cc858
SF
383static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
384 struct cifsSesInfo *ses)
385{
9fbc5908
SF
386 unsigned int tioffset; /* challeng message target info area */
387 unsigned int tilen; /* challeng message target info area length */
388
0b3cc858
SF
389 CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
390
391 if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
b6b38f70 392 cERROR(1, "challenge blob len %d too small", blob_len);
0b3cc858
SF
393 return -EINVAL;
394 }
395
396 if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
b6b38f70 397 cERROR(1, "blob signature incorrect %s", pblob->Signature);
0b3cc858
SF
398 return -EINVAL;
399 }
400 if (pblob->MessageType != NtLmChallenge) {
b6b38f70 401 cERROR(1, "Incorrect message type %d", pblob->MessageType);
0b3cc858
SF
402 return -EINVAL;
403 }
404
405 memcpy(ses->server->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
406 /* BB we could decode pblob->NegotiateFlags; some may be useful */
407 /* In particular we can examine sign flags */
408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
409 we must set the MIC field of the AUTHENTICATE_MESSAGE */
410
3ec6bbcd
SP
411 ses->server->ntlmssp.server_flags = le32_to_cpu(pblob->NegotiateFlags);
412
9fbc5908
SF
413 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
414 tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
415 ses->server->tilen = tilen;
416 if (tilen) {
417 ses->server->tiblob = kmalloc(tilen, GFP_KERNEL);
418 if (!ses->server->tiblob) {
419 cERROR(1, "Challenge target info allocation failure");
420 return -ENOMEM;
421 }
422 memcpy(ses->server->tiblob, bcc_ptr + tioffset, tilen);
423 }
424
0b3cc858
SF
425 return 0;
426}
427
428#ifdef CONFIG_CIFS_EXPERIMENTAL
429/* BB Move to ntlmssp.c eventually */
430
431/* We do not malloc the blob, it is passed in pbuffer, because
432 it is fixed size, and small, making this approach cleaner */
433static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
434 struct cifsSesInfo *ses)
435{
436 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
437 __u32 flags;
438
439 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
440 sec_blob->MessageType = NtLmNegotiate;
441
442 /* BB is NTLMV2 session security format easier to use here? */
443 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
444 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
3ec6bbcd 445 NTLMSSP_NEGOTIATE_NTLM;
0b3cc858 446 if (ses->server->secMode &
3ec6bbcd
SP
447 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
448 flags |= NTLMSSP_NEGOTIATE_SIGN |
449 NTLMSSP_NEGOTIATE_KEY_XCH |
450 NTLMSSP_NEGOTIATE_EXTENDED_SEC;
451 }
0b3cc858
SF
452
453 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
454
455 sec_blob->WorkstationName.BufferOffset = 0;
456 sec_blob->WorkstationName.Length = 0;
457 sec_blob->WorkstationName.MaximumLength = 0;
458
459 /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
460 sec_blob->DomainName.BufferOffset = 0;
461 sec_blob->DomainName.Length = 0;
462 sec_blob->DomainName.MaximumLength = 0;
463}
464
465/* We do not malloc the blob, it is passed in pbuffer, because its
466 maximum possible size is fixed and small, making this approach cleaner.
467 This function returns the length of the data in the blob */
468static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
469 struct cifsSesInfo *ses,
ebe6aa5a 470 const struct nls_table *nls_cp, bool first)
0b3cc858 471{
9fbc5908
SF
472 int rc;
473 unsigned int size;
0b3cc858
SF
474 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
475 __u32 flags;
476 unsigned char *tmp;
9fbc5908 477 struct ntlmv2_resp ntlmv2_response = {};
0b3cc858
SF
478
479 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
480 sec_blob->MessageType = NtLmAuthenticate;
481
482 flags = NTLMSSP_NEGOTIATE_56 |
483 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
484 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
485 NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;
486 if (ses->server->secMode &
487 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
488 flags |= NTLMSSP_NEGOTIATE_SIGN;
489 if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
490 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
491
492 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
493 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
494
495 sec_blob->LmChallengeResponse.BufferOffset =
496 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
497 sec_blob->LmChallengeResponse.Length = 0;
498 sec_blob->LmChallengeResponse.MaximumLength = 0;
499
0b3cc858 500 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
9fbc5908
SF
501 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp);
502 if (rc) {
503 cERROR(1, "error rc: %d during ntlmssp ntlmv2 setup", rc);
504 goto setup_ntlmv2_ret;
505 }
506 size = sizeof(struct ntlmv2_resp);
507 memcpy(tmp, (char *)&ntlmv2_response, size);
508 tmp += size;
509 if (ses->server->tilen > 0) {
510 memcpy(tmp, ses->server->tiblob, ses->server->tilen);
511 tmp += ses->server->tilen;
512 } else
513 ses->server->tilen = 0;
0b3cc858 514
9fbc5908
SF
515 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size +
516 ses->server->tilen);
517 sec_blob->NtChallengeResponse.MaximumLength =
518 cpu_to_le16(size + ses->server->tilen);
0b3cc858
SF
519
520 if (ses->domainName == NULL) {
521 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
522 sec_blob->DomainName.Length = 0;
523 sec_blob->DomainName.MaximumLength = 0;
524 tmp += 2;
525 } else {
526 int len;
527 len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,
528 MAX_USERNAME_SIZE, nls_cp);
529 len *= 2; /* unicode is 2 bytes each */
0b3cc858
SF
530 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
531 sec_blob->DomainName.Length = cpu_to_le16(len);
532 sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
533 tmp += len;
534 }
535
536 if (ses->userName == NULL) {
537 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
538 sec_blob->UserName.Length = 0;
539 sec_blob->UserName.MaximumLength = 0;
540 tmp += 2;
541 } else {
542 int len;
543 len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
544 MAX_USERNAME_SIZE, nls_cp);
545 len *= 2; /* unicode is 2 bytes each */
0b3cc858
SF
546 sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
547 sec_blob->UserName.Length = cpu_to_le16(len);
548 sec_blob->UserName.MaximumLength = cpu_to_le16(len);
549 tmp += len;
550 }
551
552 sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
553 sec_blob->WorkstationName.Length = 0;
554 sec_blob->WorkstationName.MaximumLength = 0;
555 tmp += 2;
556
9fbc5908
SF
557 if ((ses->server->ntlmssp.server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
558 !calc_seckey(ses->server)) {
559 memcpy(tmp, ses->server->ntlmssp.ciphertext, CIFS_CPHTXT_SIZE);
560 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
561 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
562 sec_blob->SessionKey.MaximumLength =
563 cpu_to_le16(CIFS_CPHTXT_SIZE);
564 tmp += CIFS_CPHTXT_SIZE;
565 } else {
566 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
567 sec_blob->SessionKey.Length = 0;
568 sec_blob->SessionKey.MaximumLength = 0;
569 }
570
571 ses->server->sequence_number = 0;
572
573setup_ntlmv2_ret:
574 if (ses->server->tilen > 0)
575 kfree(ses->server->tiblob);
576
0b3cc858
SF
577 return tmp - pbuffer;
578}
579
580
581static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
582 struct cifsSesInfo *ses)
583{
584 build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
585 pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
586
587 return;
588}
589
9fbc5908 590static int setup_ntlmssp_auth_req(char *ntlmsspblob,
0b3cc858 591 struct cifsSesInfo *ses,
ebe6aa5a 592 const struct nls_table *nls, bool first_time)
0b3cc858
SF
593{
594 int bloblen;
595
9fbc5908 596 bloblen = build_ntlmssp_auth_blob(ntlmsspblob, ses, nls,
0b3cc858 597 first_time);
0b3cc858
SF
598
599 return bloblen;
600}
601#endif
602
790fe579 603int
ebe6aa5a
JL
604CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
605 const struct nls_table *nls_cp)
3979877e
SF
606{
607 int rc = 0;
608 int wct;
3979877e
SF
609 struct smb_hdr *smb_buf;
610 char *bcc_ptr;
750d1151 611 char *str_area;
3979877e
SF
612 SESSION_SETUP_ANDX *pSMB;
613 __u32 capabilities;
614 int count;
2442421b
SF
615 int resp_buf_type;
616 struct kvec iov[3];
3979877e
SF
617 enum securityEnum type;
618 __u16 action;
619 int bytes_remaining;
2442421b 620 struct key *spnego_key = NULL;
0b3cc858 621 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
ebe6aa5a 622 bool first_time;
254e55ed 623
790fe579 624 if (ses == NULL)
3979877e
SF
625 return -EINVAL;
626
ebe6aa5a
JL
627 read_lock(&cifs_tcp_ses_lock);
628 first_time = is_first_ses_reconnect(ses);
629 read_unlock(&cifs_tcp_ses_lock);
630
3979877e 631 type = ses->server->secType;
f40c5628 632
b6b38f70 633 cFYI(1, "sess setup type %d", type);
0b3cc858
SF
634ssetup_ntlmssp_authenticate:
635 if (phase == NtLmChallenge)
636 phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
637
790fe579 638 if (type == LANMAN) {
3979877e
SF
639#ifndef CONFIG_CIFS_WEAK_PW_HASH
640 /* LANMAN and plaintext are less secure and off by default.
641 So we make this explicitly be turned on in kconfig (in the
642 build) and turned on at runtime (changed from the default)
643 in proc/fs/cifs or via mount parm. Unfortunately this is
644 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
645 return -EOPNOTSUPP;
646#endif
647 wct = 10; /* lanman 2 style sessionsetup */
790fe579 648 } else if ((type == NTLM) || (type == NTLMv2)) {
9312f675 649 /* For NTLMv2 failures eventually may need to retry NTLM */
3979877e 650 wct = 13; /* old style NTLM sessionsetup */
790fe579 651 } else /* same size: negotiate or auth, NTLMSSP or extended security */
3979877e
SF
652 wct = 12;
653
654 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
655 (void **)&smb_buf);
790fe579 656 if (rc)
3979877e
SF
657 return rc;
658
659 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
660
661 capabilities = cifs_ssetup_hdr(ses, pSMB);
750d1151 662
2442421b
SF
663 /* we will send the SMB in three pieces:
664 a fixed length beginning part, an optional
665 SPNEGO blob (which can be zero length), and a
666 last part which will include the strings
667 and rest of bcc area. This allows us to avoid
668 a large buffer 17K allocation */
790fe579
SF
669 iov[0].iov_base = (char *)pSMB;
670 iov[0].iov_len = smb_buf->smb_buf_length + 4;
750d1151 671
2442421b
SF
672 /* setting this here allows the code at the end of the function
673 to free the request buffer if there's an error */
674 resp_buf_type = CIFS_SMALL_BUFFER;
675
750d1151
SF
676 /* 2000 big enough to fit max user, domain, NOS name etc. */
677 str_area = kmalloc(2000, GFP_KERNEL);
5e6e6232 678 if (str_area == NULL) {
2442421b
SF
679 rc = -ENOMEM;
680 goto ssetup_exit;
5e6e6232 681 }
750d1151 682 bcc_ptr = str_area;
3979877e 683
9ac00b7d
SF
684 ses->flags &= ~CIFS_SES_LANMAN;
685
2442421b
SF
686 iov[1].iov_base = NULL;
687 iov[1].iov_len = 0;
688
790fe579 689 if (type == LANMAN) {
3979877e 690#ifdef CONFIG_CIFS_WEAK_PW_HASH
7c7b25bc 691 char lnm_session_key[CIFS_SESS_KEY_SIZE];
3979877e 692
c76da9da
SF
693 pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
694
3979877e
SF
695 /* no capabilities flags in old lanman negotiation */
696
790fe579 697 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e
SF
698 /* BB calculate hash with password */
699 /* and copy into bcc */
700
4e53a3fb
JL
701 calc_lanman_hash(ses->password, ses->server->cryptKey,
702 ses->server->secMode & SECMODE_PW_ENCRYPT ?
703 true : false, lnm_session_key);
704
790fe579 705 ses->flags |= CIFS_SES_LANMAN;
7c7b25bc
SF
706 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
707 bcc_ptr += CIFS_SESS_KEY_SIZE;
3979877e
SF
708
709 /* can not sign if LANMAN negotiated so no need
710 to calculate signing key? but what if server
711 changed to do higher than lanman dialect and
712 we reconnected would we ever calc signing_key? */
713
b6b38f70 714 cFYI(1, "Negotiating LANMAN setting up strings");
3979877e
SF
715 /* Unicode not allowed for LANMAN dialects */
716 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
790fe579 717#endif
3979877e 718 } else if (type == NTLM) {
7c7b25bc 719 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3979877e
SF
720
721 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
722 pSMB->req_no_secext.CaseInsensitivePasswordLength =
7c7b25bc 723 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e 724 pSMB->req_no_secext.CaseSensitivePasswordLength =
7c7b25bc 725 cpu_to_le16(CIFS_SESS_KEY_SIZE);
50c2f753 726
3979877e
SF
727 /* calculate session key */
728 SMBNTencrypt(ses->password, ses->server->cryptKey,
729 ntlm_session_key);
730
790fe579 731 if (first_time) /* should this be moved into common code
3979877e 732 with similar ntlmv2 path? */
9fbc5908 733 cifs_calculate_session_key(&ses->server->session_key,
3979877e
SF
734 ntlm_session_key, ses->password);
735 /* copy session key */
736
790fe579 737 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 738 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 739 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 740 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 741 if (ses->capabilities & CAP_UNICODE) {
0223cf0b
SF
742 /* unicode strings must be word aligned */
743 if (iov[0].iov_len % 2) {
744 *bcc_ptr = 0;
790fe579
SF
745 bcc_ptr++;
746 }
7c7b25bc 747 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 748 } else
7c7b25bc
SF
749 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
750 } else if (type == NTLMv2) {
790fe579 751 char *v2_sess_key =
6d027cfd 752 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
f64b23ae
SF
753
754 /* BB FIXME change all users of v2_sess_key to
755 struct ntlmv2_resp */
7c7b25bc 756
790fe579 757 if (v2_sess_key == NULL) {
2442421b
SF
758 rc = -ENOMEM;
759 goto ssetup_exit;
7c7b25bc
SF
760 }
761
762 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
763
764 /* LM2 password would be here if we supported it */
765 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
766 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */
767
768 pSMB->req_no_secext.CaseSensitivePasswordLength =
f64b23ae 769 cpu_to_le16(sizeof(struct ntlmv2_resp));
7c7b25bc
SF
770
771 /* calculate session key */
9fbc5908
SF
772 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
773 if (rc) {
774 kfree(v2_sess_key);
775 goto ssetup_exit;
776 }
8a224d48 777 /* FIXME: calculate MAC key */
3870253e
SF
778 memcpy(bcc_ptr, (char *)v2_sess_key,
779 sizeof(struct ntlmv2_resp));
f64b23ae
SF
780 bcc_ptr += sizeof(struct ntlmv2_resp);
781 kfree(v2_sess_key);
9fbc5908
SF
782 if (ses->server->tilen > 0) {
783 memcpy(bcc_ptr, ses->server->tiblob,
784 ses->server->tilen);
785 bcc_ptr += ses->server->tilen;
786 }
790fe579
SF
787 if (ses->capabilities & CAP_UNICODE) {
788 if (iov[0].iov_len % 2) {
0223cf0b 789 *bcc_ptr = 0;
26f57364
SF
790 bcc_ptr++;
791 }
3979877e 792 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 793 } else
3979877e 794 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
26efa0ba 795 } else if (type == Kerberos) {
2442421b
SF
796#ifdef CONFIG_CIFS_UPCALL
797 struct cifs_spnego_msg *msg;
798 spnego_key = cifs_get_spnego_key(ses);
799 if (IS_ERR(spnego_key)) {
800 rc = PTR_ERR(spnego_key);
801 spnego_key = NULL;
802 goto ssetup_exit;
803 }
804
805 msg = spnego_key->payload.data;
6ce5eecb
SF
806 /* check version field to make sure that cifs.upcall is
807 sending us a response in an expected form */
808 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
b6b38f70 809 cERROR(1, "incorrect version of cifs.upcall (expected"
6ce5eecb 810 " %d but got %d)",
b6b38f70 811 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
6ce5eecb
SF
812 rc = -EKEYREJECTED;
813 goto ssetup_exit;
814 }
2442421b
SF
815 /* bail out if key is too long */
816 if (msg->sesskey_len >
9fbc5908 817 sizeof(ses->server->session_key.data.krb5)) {
b6b38f70
JP
818 cERROR(1, "Kerberos signing key too long (%u bytes)",
819 msg->sesskey_len);
2442421b
SF
820 rc = -EOVERFLOW;
821 goto ssetup_exit;
822 }
1a67570c 823 if (first_time) {
9fbc5908
SF
824 ses->server->session_key.len = msg->sesskey_len;
825 memcpy(ses->server->session_key.data.krb5,
1a67570c
JL
826 msg->data, msg->sesskey_len);
827 }
3979877e
SF
828 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
829 capabilities |= CAP_EXTENDED_SECURITY;
830 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2442421b
SF
831 iov[1].iov_base = msg->data + msg->sesskey_len;
832 iov[1].iov_len = msg->secblob_len;
833 pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
834
835 if (ses->capabilities & CAP_UNICODE) {
836 /* unicode strings must be word aligned */
28c5a02a 837 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
2442421b
SF
838 *bcc_ptr = 0;
839 bcc_ptr++;
840 }
841 unicode_oslm_strings(&bcc_ptr, nls_cp);
842 unicode_domain_string(&bcc_ptr, ses, nls_cp);
843 } else
844 /* BB: is this right? */
845 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
846#else /* ! CONFIG_CIFS_UPCALL */
b6b38f70 847 cERROR(1, "Kerberos negotiated but upcall support disabled!");
2442421b
SF
848 rc = -ENOSYS;
849 goto ssetup_exit;
850#endif /* CONFIG_CIFS_UPCALL */
851 } else {
0b3cc858 852#ifdef CONFIG_CIFS_EXPERIMENTAL
f46c7234 853 if (type == RawNTLMSSP) {
0b3cc858 854 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
b6b38f70 855 cERROR(1, "NTLMSSP requires Unicode support");
0b3cc858
SF
856 rc = -ENOSYS;
857 goto ssetup_exit;
858 }
859
b6b38f70 860 cFYI(1, "ntlmssp session setup phase %d", phase);
0b3cc858
SF
861 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
862 capabilities |= CAP_EXTENDED_SECURITY;
863 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
864 if (phase == NtLmNegotiate) {
865 setup_ntlmssp_neg_req(pSMB, ses);
866 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
9fbc5908 867 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
0b3cc858
SF
868 } else if (phase == NtLmAuthenticate) {
869 int blob_len;
c89e5198
SF
870 char *ntlmsspblob;
871
9fbc5908
SF
872 ntlmsspblob = kmalloc(5 *
873 sizeof(struct _AUTHENTICATE_MESSAGE),
874 GFP_KERNEL);
875 if (!ntlmsspblob) {
876 cERROR(1, "Can't allocate NTLMSSP");
877 rc = -ENOMEM;
878 goto ssetup_exit;
879 }
880
881 blob_len = setup_ntlmssp_auth_req(ntlmsspblob,
882 ses,
883 nls_cp,
884 first_time);
0b3cc858 885 iov[1].iov_len = blob_len;
9fbc5908
SF
886 iov[1].iov_base = ntlmsspblob;
887 pSMB->req.SecurityBlobLength =
888 cpu_to_le16(blob_len);
844823cb
SF
889 /* Make sure that we tell the server that we
890 are using the uid that it just gave us back
891 on the response (challenge) */
892 smb_buf->Uid = ses->Suid;
0b3cc858 893 } else {
b6b38f70 894 cERROR(1, "invalid phase %d", phase);
0b3cc858
SF
895 rc = -ENOSYS;
896 goto ssetup_exit;
897 }
0b3cc858
SF
898 /* unicode strings must be word aligned */
899 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
900 *bcc_ptr = 0;
901 bcc_ptr++;
902 }
903 unicode_oslm_strings(&bcc_ptr, nls_cp);
904 } else {
b6b38f70 905 cERROR(1, "secType %d not supported!", type);
0b3cc858
SF
906 rc = -ENOSYS;
907 goto ssetup_exit;
908 }
909#else
b6b38f70 910 cERROR(1, "secType %d not supported!", type);
2442421b
SF
911 rc = -ENOSYS;
912 goto ssetup_exit;
0b3cc858 913#endif
3979877e
SF
914 }
915
2442421b
SF
916 iov[2].iov_base = str_area;
917 iov[2].iov_len = (long) bcc_ptr - (long) str_area;
918
919 count = iov[1].iov_len + iov[2].iov_len;
3979877e
SF
920 smb_buf->smb_buf_length += count;
921
3979877e
SF
922 BCC_LE(smb_buf) = cpu_to_le16(count);
923
2442421b 924 rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
133672ef 925 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
3979877e
SF
926 /* SMB request buf freed in SendReceive2 */
927
b6b38f70 928 cFYI(1, "ssetup rc from sendrecv2 is %d", rc);
3979877e
SF
929
930 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
931 smb_buf = (struct smb_hdr *)iov[0].iov_base;
932
0b3cc858
SF
933 if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
934 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
935 if (phase != NtLmNegotiate) {
b6b38f70 936 cERROR(1, "Unexpected more processing error");
0b3cc858
SF
937 goto ssetup_exit;
938 }
939 /* NTLMSSP Negotiate sent now processing challenge (response) */
940 phase = NtLmChallenge; /* process ntlmssp challenge */
941 rc = 0; /* MORE_PROC rc is not an error here, but expected */
942 }
943 if (rc)
944 goto ssetup_exit;
945
790fe579 946 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
3979877e 947 rc = -EIO;
b6b38f70 948 cERROR(1, "bad word count %d", smb_buf->WordCount);
3979877e
SF
949 goto ssetup_exit;
950 }
951 action = le16_to_cpu(pSMB->resp.Action);
952 if (action & GUEST_LOGIN)
b6b38f70 953 cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
3979877e 954 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
b6b38f70 955 cFYI(1, "UID = %d ", ses->Suid);
3979877e
SF
956 /* response can have either 3 or 4 word count - Samba sends 3 */
957 /* and lanman response is 3 */
958 bytes_remaining = BCC(smb_buf);
959 bcc_ptr = pByteArea(smb_buf);
960
790fe579 961 if (smb_buf->WordCount == 4) {
3979877e
SF
962 __u16 blob_len;
963 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
790fe579 964 if (blob_len > bytes_remaining) {
b6b38f70 965 cERROR(1, "bad security blob length %d", blob_len);
3979877e
SF
966 rc = -EINVAL;
967 goto ssetup_exit;
968 }
0b3cc858
SF
969 if (phase == NtLmChallenge) {
970 rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
971 /* now goto beginning for ntlmssp authenticate phase */
972 if (rc)
973 goto ssetup_exit;
974 }
975 bcc_ptr += blob_len;
3979877e 976 bytes_remaining -= blob_len;
790fe579 977 }
3979877e
SF
978
979 /* BB check if Unicode and decode strings */
27b87fe5
JL
980 if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
981 /* unicode string area must be word-aligned */
982 if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
983 ++bcc_ptr;
984 --bytes_remaining;
985 }
59140797 986 decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
27b87fe5 987 } else {
63135e08
SF
988 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
989 ses, nls_cp);
27b87fe5 990 }
50c2f753 991
3979877e 992ssetup_exit:
dfd15c46
JL
993 if (spnego_key) {
994 key_revoke(spnego_key);
2442421b 995 key_put(spnego_key);
dfd15c46 996 }
750d1151 997 kfree(str_area);
790fe579 998 if (resp_buf_type == CIFS_SMALL_BUFFER) {
b6b38f70 999 cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
3979877e 1000 cifs_small_buf_release(iov[0].iov_base);
790fe579 1001 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
3979877e
SF
1002 cifs_buf_release(iov[0].iov_base);
1003
0b3cc858
SF
1004 /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
1005 if ((phase == NtLmChallenge) && (rc == 0))
1006 goto ssetup_ntlmssp_authenticate;
1007
3979877e
SF
1008 return rc;
1009}