• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   fs/cifs/sess.c
3  *
4  *   SMB/CIFS session setup handling routines
5  *
6  *   Copyright (c) International Business Machines  Corp., 2006, 2007
7  *   Author(s): Steve French (sfrench@us.ibm.com)
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #include "cifspdu.h"
25 #include "cifsglob.h"
26 #include "cifsproto.h"
27 #include "cifs_unicode.h"
28 #include "cifs_debug.h"
29 #include "ntlmssp.h"
30 #include "nterr.h"
31 #include <linux/utsname.h>
32 #include "cifs_spnego.h"
33 
34 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
35 			 unsigned char *p24);
36 
37 /* Checks if this is the first smb session to be reconnected after
38    the socket has been reestablished (so we know whether to use vc 0).
39    Called while holding the cifs_tcp_ses_lock, so do not block */
is_first_ses_reconnect(struct cifsSesInfo * ses)40 static 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 	/* could not find a session that was already connected,
52 	   this must be the first one we are reconnecting */
53 	return true;
54 }
55 
56 /*
57  *	vc number 0 is treated specially by some servers, and should be the
58  *      first one we request.  After that we can use vcnumbers up to maxvcs,
59  *	one for each smb session (some Windows versions set maxvcs incorrectly
60  *	so maxvc=1 can be ignored).  If we have too many vcs, we can reuse
61  *	any vc but zero (some servers reset the connection on vcnum zero)
62  *
63  */
get_next_vcnum(struct cifsSesInfo * ses)64 static __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 	/* Quoting the MS-SMB specification: "Windows-based SMB servers set this
74 	field to one but do not enforce this limit, which allows an SMB client
75 	to establish more virtual circuits than allowed by this value ... but
76 	other server implementations can enforce this limit." */
77 	if (max_vcs < 2)
78 		max_vcs = 0xFFFF;
79 
80 	write_lock(&cifs_tcp_ses_lock);
81 	if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
82 			goto get_vc_num_exit;  /* vcnum will be zero */
83 	for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
84 		if (i == 0) /* this is the only connection, use vc 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; /* found duplicate, try next vcnum */
95 			}
96 		}
97 		if (free_vc_found)
98 			break; /* we found a vcnumber that will work - use it */
99 	}
100 
101 	if (i == 0)
102 		vcnum = 0; /* for most common case, ie if one smb session, use
103 			      vc zero.  Also for case when no free vcnum, zero
104 			      is safest to send (some clients only send zero) */
105 	else if (free_vc_found == 0)
106 		vcnum = 1;  /* we can not reuse vc=0 safely, since some servers
107 				reset all uids on that, but 1 is ok. */
108 	else
109 		vcnum = i;
110 	ses->vcnum = vcnum;
111 get_vc_num_exit:
112 	write_unlock(&cifs_tcp_ses_lock);
113 
114 	return le16_to_cpu(vcnum);
115 }
116 
cifs_ssetup_hdr(struct cifsSesInfo * ses,SESSION_SETUP_ANDX * pSMB)117 static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
118 {
119 	__u32 capabilities = 0;
120 
121 	/* init fields common to all four types of SessSetup */
122 	/* Note that offsets for first seven fields in req struct are same  */
123 	/*	in CIFS Specs so does not matter which of 3 forms of struct */
124 	/*	that we use in next few lines                               */
125 	/* Note that header is initialized to zero in header_assemble */
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 	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
132 
133 	/* BB verify whether signing required on neg or just on auth frame
134 	   (and NTLM case) */
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 
161 static void
unicode_oslm_strings(char ** pbcc_area,const struct nls_table * nls_cp)162 unicode_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 	/* Copy OS version */
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; /* trailing null */
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; /* trailing null */
180 
181 	*pbcc_area = bcc_ptr;
182 }
183 
unicode_domain_string(char ** pbcc_area,struct cifsSesInfo * ses,const struct nls_table * nls_cp)184 static 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 	/* copy domain */
191 	if (ses->domainName == NULL) {
192 		/* Sending null domain better than using a bogus domain name (as
193 		we did briefly in 2.6.18) since server will use its default */
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;  /* account for null terminator */
202 
203 	*pbcc_area = bcc_ptr;
204 }
205 
206 
unicode_ssetup_strings(char ** pbcc_area,struct cifsSesInfo * ses,const struct nls_table * nls_cp)207 static 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 	/* BB FIXME add check that strings total less
214 	than 335 or will need to send them as arrays */
215 
216 	/* unicode strings, must be word aligned before the call */
217 /*	if ((long) bcc_ptr % 2)	{
218 		*bcc_ptr = 0;
219 		bcc_ptr++;
220 	} */
221 	/* copy user */
222 	if (ses->userName == NULL) {
223 		/* null user mount */
224 		*bcc_ptr = 0;
225 		*(bcc_ptr+1) = 0;
226 	} else { /* 300 should be long enough for any conceivable user name */
227 		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
228 					  300, nls_cp);
229 	}
230 	bcc_ptr += 2 * bytes_ret;
231 	bcc_ptr += 2; /* account for null termination */
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 
ascii_ssetup_strings(char ** pbcc_area,struct cifsSesInfo * ses,const struct nls_table * nls_cp)239 static 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 	/* copy user */
245 	/* BB what about null user mounts - check that we do this BB */
246 	/* copy user */
247 	if (ses->userName == NULL) {
248 		/* BB what about null user mounts - check that we do this BB */
249 	} else { /* 300 should be long enough for any conceivable user name */
250 		strncpy(bcc_ptr, ses->userName, 300);
251 	}
252 	/* BB improve check for overflow */
253 	bcc_ptr += strnlen(ses->userName, 300);
254 	*bcc_ptr = 0;
255 	bcc_ptr++; /* account for null termination */
256 
257 	/* copy domain */
258 
259 	if (ses->domainName != NULL) {
260 		strncpy(bcc_ptr, ses->domainName, 256);
261 		bcc_ptr += strnlen(ses->domainName, 256);
262 	} /* else we will send a null domain name
263 	     so the server will default to its own domain */
264 	*bcc_ptr = 0;
265 	bcc_ptr++;
266 
267 	/* BB check for overflow here */
268 
269 	strcpy(bcc_ptr, "Linux version ");
270 	bcc_ptr += strlen("Linux version ");
271 	strcpy(bcc_ptr, init_utsname()->release);
272 	bcc_ptr += strlen(init_utsname()->release) + 1;
273 
274 	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
275 	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
276 
277 	*pbcc_area = bcc_ptr;
278 }
279 
decode_unicode_ssetup(char ** pbcc_area,int bleft,struct cifsSesInfo * ses,const struct nls_table * nls_cp)280 static int decode_unicode_ssetup(char **pbcc_area, int bleft,
281 				 struct cifsSesInfo *ses,
282 				 const struct nls_table *nls_cp)
283 {
284 	int rc = 0;
285 	int words_left, len;
286 	char *data = *pbcc_area;
287 
288 
289 
290 	cFYI(1, ("bleft %d", bleft));
291 
292 
293 	/* SMB header is unaligned, so cifs servers word align start of
294 	   Unicode strings */
295 	data++;
296 	bleft--; /* Windows servers do not always double null terminate
297 		    their final Unicode string - in which case we
298 		    now will not attempt to decode the byte of junk
299 		    which follows it */
300 
301 	words_left = bleft / 2;
302 
303 	/* save off server operating system */
304 	len = UniStrnlen((wchar_t *) data, words_left);
305 
306 /* We look for obvious messed up bcc or strings in response so we do not go off
307    the end since (at least) WIN2K and Windows XP have a major bug in not null
308    terminating last Unicode string in response  */
309 	if (len >= words_left)
310 		return rc;
311 
312 	kfree(ses->serverOS);
313 	/* UTF-8 string will not grow more than four times as big as UCS-16 */
314 	ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL);
315 	if (ses->serverOS != NULL)
316 		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
317 	data += 2 * (len + 1);
318 	words_left -= len + 1;
319 
320 	/* save off server network operating system */
321 	len = UniStrnlen((wchar_t *) data, words_left);
322 
323 	if (len >= words_left)
324 		return rc;
325 
326 	kfree(ses->serverNOS);
327 	ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL);
328 	if (ses->serverNOS != NULL) {
329 		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
330 				   nls_cp);
331 		if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
332 			cFYI(1, ("NT4 server"));
333 			ses->flags |= CIFS_SES_NT4;
334 		}
335 	}
336 	data += 2 * (len + 1);
337 	words_left -= len + 1;
338 
339 	/* save off server domain */
340 	len = UniStrnlen((wchar_t *) data, words_left);
341 
342 	if (len > words_left)
343 		return rc;
344 
345 	kfree(ses->serverDomain);
346 	ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
347 	if (ses->serverDomain != NULL) {
348 		cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
349 				   nls_cp);
350 		ses->serverDomain[2*len] = 0;
351 		ses->serverDomain[(2*len) + 1] = 0;
352 	}
353 	data += 2 * (len + 1);
354 	words_left -= len + 1;
355 
356 	cFYI(1, ("words left: %d", words_left));
357 
358 	return rc;
359 }
360 
decode_ascii_ssetup(char ** pbcc_area,int bleft,struct cifsSesInfo * ses,const struct nls_table * nls_cp)361 static int decode_ascii_ssetup(char **pbcc_area, int bleft,
362 			       struct cifsSesInfo *ses,
363 			       const struct nls_table *nls_cp)
364 {
365 	int rc = 0;
366 	int len;
367 	char *bcc_ptr = *pbcc_area;
368 
369 	cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
370 
371 	len = strnlen(bcc_ptr, bleft);
372 	if (len >= bleft)
373 		return rc;
374 
375 	kfree(ses->serverOS);
376 
377 	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
378 	if (ses->serverOS)
379 		strncpy(ses->serverOS, bcc_ptr, len);
380 	if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
381 			cFYI(1, ("OS/2 server"));
382 			ses->flags |= CIFS_SES_OS2;
383 	}
384 
385 	bcc_ptr += len + 1;
386 	bleft -= len + 1;
387 
388 	len = strnlen(bcc_ptr, bleft);
389 	if (len >= bleft)
390 		return rc;
391 
392 	kfree(ses->serverNOS);
393 
394 	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
395 	if (ses->serverNOS)
396 		strncpy(ses->serverNOS, bcc_ptr, len);
397 
398 	bcc_ptr += len + 1;
399 	bleft -= len + 1;
400 
401 	len = strnlen(bcc_ptr, bleft);
402 	if (len > bleft)
403 		return rc;
404 
405 	/* No domain field in LANMAN case. Domain is
406 	   returned by old servers in the SMB negprot response */
407 	/* BB For newer servers which do not support Unicode,
408 	   but thus do return domain here we could add parsing
409 	   for it later, but it is not very important */
410 	cFYI(1, ("ascii: bytes left %d", bleft));
411 
412 	return rc;
413 }
414 
415 int
CIFS_SessSetup(unsigned int xid,struct cifsSesInfo * ses,int first_time,const struct nls_table * nls_cp)416 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
417 		const struct nls_table *nls_cp)
418 {
419 	int rc = 0;
420 	int wct;
421 	struct smb_hdr *smb_buf;
422 	char *bcc_ptr;
423 	char *str_area;
424 	SESSION_SETUP_ANDX *pSMB;
425 	__u32 capabilities;
426 	int count;
427 	int resp_buf_type;
428 	struct kvec iov[3];
429 	enum securityEnum type;
430 	__u16 action;
431 	int bytes_remaining;
432 	struct key *spnego_key = NULL;
433 
434 	if (ses == NULL)
435 		return -EINVAL;
436 
437 	type = ses->server->secType;
438 
439 	cFYI(1, ("sess setup type %d", type));
440 	if (type == LANMAN) {
441 #ifndef CONFIG_CIFS_WEAK_PW_HASH
442 		/* LANMAN and plaintext are less secure and off by default.
443 		So we make this explicitly be turned on in kconfig (in the
444 		build) and turned on at runtime (changed from the default)
445 		in proc/fs/cifs or via mount parm.  Unfortunately this is
446 		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
447 		return -EOPNOTSUPP;
448 #endif
449 		wct = 10; /* lanman 2 style sessionsetup */
450 	} else if ((type == NTLM) || (type == NTLMv2)) {
451 		/* For NTLMv2 failures eventually may need to retry NTLM */
452 		wct = 13; /* old style NTLM sessionsetup */
453 	} else /* same size: negotiate or auth, NTLMSSP or extended security */
454 		wct = 12;
455 
456 	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
457 			    (void **)&smb_buf);
458 	if (rc)
459 		return rc;
460 
461 	pSMB = (SESSION_SETUP_ANDX *)smb_buf;
462 
463 	capabilities = cifs_ssetup_hdr(ses, pSMB);
464 
465 	/* we will send the SMB in three pieces:
466 	a fixed length beginning part, an optional
467 	SPNEGO blob (which can be zero length), and a
468 	last part which will include the strings
469 	and rest of bcc area. This allows us to avoid
470 	a large buffer 17K allocation */
471 	iov[0].iov_base = (char *)pSMB;
472 	iov[0].iov_len = smb_buf->smb_buf_length + 4;
473 
474 	/* setting this here allows the code at the end of the function
475 	   to free the request buffer if there's an error */
476 	resp_buf_type = CIFS_SMALL_BUFFER;
477 
478 	/* 2000 big enough to fit max user, domain, NOS name etc. */
479 	str_area = kmalloc(2000, GFP_KERNEL);
480 	if (str_area == NULL) {
481 		rc = -ENOMEM;
482 		goto ssetup_exit;
483 	}
484 	bcc_ptr = str_area;
485 
486 	ses->flags &= ~CIFS_SES_LANMAN;
487 
488 	iov[1].iov_base = NULL;
489 	iov[1].iov_len = 0;
490 
491 	if (type == LANMAN) {
492 #ifdef CONFIG_CIFS_WEAK_PW_HASH
493 		char lnm_session_key[CIFS_SESS_KEY_SIZE];
494 
495 		pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
496 
497 		/* no capabilities flags in old lanman negotiation */
498 
499 		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
500 		/* BB calculate hash with password */
501 		/* and copy into bcc */
502 
503 		calc_lanman_hash(ses->password, ses->server->cryptKey,
504 				 ses->server->secMode & SECMODE_PW_ENCRYPT ?
505 					true : false, lnm_session_key);
506 
507 		ses->flags |= CIFS_SES_LANMAN;
508 		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
509 		bcc_ptr += CIFS_SESS_KEY_SIZE;
510 
511 		/* can not sign if LANMAN negotiated so no need
512 		to calculate signing key? but what if server
513 		changed to do higher than lanman dialect and
514 		we reconnected would we ever calc signing_key? */
515 
516 		cFYI(1, ("Negotiating LANMAN setting up strings"));
517 		/* Unicode not allowed for LANMAN dialects */
518 		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
519 #endif
520 	} else if (type == NTLM) {
521 		char ntlm_session_key[CIFS_SESS_KEY_SIZE];
522 
523 		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
524 		pSMB->req_no_secext.CaseInsensitivePasswordLength =
525 			cpu_to_le16(CIFS_SESS_KEY_SIZE);
526 		pSMB->req_no_secext.CaseSensitivePasswordLength =
527 			cpu_to_le16(CIFS_SESS_KEY_SIZE);
528 
529 		/* calculate session key */
530 		SMBNTencrypt(ses->password, ses->server->cryptKey,
531 			     ntlm_session_key);
532 
533 		if (first_time) /* should this be moved into common code
534 				  with similar ntlmv2 path? */
535 			cifs_calculate_mac_key(&ses->server->mac_signing_key,
536 				ntlm_session_key, ses->password);
537 		/* copy session key */
538 
539 		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
540 		bcc_ptr += CIFS_SESS_KEY_SIZE;
541 		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
542 		bcc_ptr += CIFS_SESS_KEY_SIZE;
543 		if (ses->capabilities & CAP_UNICODE) {
544 			/* unicode strings must be word aligned */
545 			if (iov[0].iov_len % 2) {
546 				*bcc_ptr = 0;
547 				bcc_ptr++;
548 			}
549 			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
550 		} else
551 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
552 	} else if (type == NTLMv2) {
553 		char *v2_sess_key =
554 			kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
555 
556 		/* BB FIXME change all users of v2_sess_key to
557 		   struct ntlmv2_resp */
558 
559 		if (v2_sess_key == NULL) {
560 			rc = -ENOMEM;
561 			goto ssetup_exit;
562 		}
563 
564 		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
565 
566 		/* LM2 password would be here if we supported it */
567 		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
568 		/*	cpu_to_le16(LM2_SESS_KEY_SIZE); */
569 
570 		pSMB->req_no_secext.CaseSensitivePasswordLength =
571 			cpu_to_le16(sizeof(struct ntlmv2_resp));
572 
573 		/* calculate session key */
574 		setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
575 		if (first_time) /* should this be moved into common code
576 				   with similar ntlmv2 path? */
577 		/*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
578 				response BB FIXME, v2_sess_key); */
579 
580 		/* copy session key */
581 
582 	/*	memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
583 		bcc_ptr += LM2_SESS_KEY_SIZE; */
584 		memcpy(bcc_ptr, (char *)v2_sess_key,
585 		       sizeof(struct ntlmv2_resp));
586 		bcc_ptr += sizeof(struct ntlmv2_resp);
587 		kfree(v2_sess_key);
588 		if (ses->capabilities & CAP_UNICODE) {
589 			if (iov[0].iov_len % 2) {
590 				*bcc_ptr = 0;
591 				bcc_ptr++;
592 			}
593 			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
594 		} else
595 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
596 	} else if (type == Kerberos || type == MSKerberos) {
597 #ifdef CONFIG_CIFS_UPCALL
598 		struct cifs_spnego_msg *msg;
599 		spnego_key = cifs_get_spnego_key(ses);
600 		if (IS_ERR(spnego_key)) {
601 			rc = PTR_ERR(spnego_key);
602 			spnego_key = NULL;
603 			goto ssetup_exit;
604 		}
605 
606 		msg = spnego_key->payload.data;
607 		/* check version field to make sure that cifs.upcall is
608 		   sending us a response in an expected form */
609 		if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
610 			cERROR(1, ("incorrect version of cifs.upcall (expected"
611 				   " %d but got %d)",
612 				   CIFS_SPNEGO_UPCALL_VERSION, msg->version));
613 			rc = -EKEYREJECTED;
614 			goto ssetup_exit;
615 		}
616 		/* bail out if key is too long */
617 		if (msg->sesskey_len >
618 		    sizeof(ses->server->mac_signing_key.data.krb5)) {
619 			cERROR(1, ("Kerberos signing key too long (%u bytes)",
620 				msg->sesskey_len));
621 			rc = -EOVERFLOW;
622 			goto ssetup_exit;
623 		}
624 		if (first_time) {
625 			ses->server->mac_signing_key.len = msg->sesskey_len;
626 			memcpy(ses->server->mac_signing_key.data.krb5,
627 				msg->data, msg->sesskey_len);
628 		}
629 		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
630 		capabilities |= CAP_EXTENDED_SECURITY;
631 		pSMB->req.Capabilities = cpu_to_le32(capabilities);
632 		iov[1].iov_base = msg->data + msg->sesskey_len;
633 		iov[1].iov_len = msg->secblob_len;
634 		pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
635 
636 		if (ses->capabilities & CAP_UNICODE) {
637 			/* unicode strings must be word aligned */
638 			if ((iov[0].iov_len + iov[1].iov_len) % 2) {
639 				*bcc_ptr = 0;
640 				bcc_ptr++;
641 			}
642 			unicode_oslm_strings(&bcc_ptr, nls_cp);
643 			unicode_domain_string(&bcc_ptr, ses, nls_cp);
644 		} else
645 		/* BB: is this right? */
646 			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
647 #else /* ! CONFIG_CIFS_UPCALL */
648 		cERROR(1, ("Kerberos negotiated but upcall support disabled!"));
649 		rc = -ENOSYS;
650 		goto ssetup_exit;
651 #endif /* CONFIG_CIFS_UPCALL */
652 	} else {
653 		cERROR(1, ("secType %d not supported!", type));
654 		rc = -ENOSYS;
655 		goto ssetup_exit;
656 	}
657 
658 	iov[2].iov_base = str_area;
659 	iov[2].iov_len = (long) bcc_ptr - (long) str_area;
660 
661 	count = iov[1].iov_len + iov[2].iov_len;
662 	smb_buf->smb_buf_length += count;
663 
664 	BCC_LE(smb_buf) = cpu_to_le16(count);
665 
666 	rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
667 			  CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
668 	/* SMB request buf freed in SendReceive2 */
669 
670 	cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
671 	if (rc)
672 		goto ssetup_exit;
673 
674 	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
675 	smb_buf = (struct smb_hdr *)iov[0].iov_base;
676 
677 	if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
678 		rc = -EIO;
679 		cERROR(1, ("bad word count %d", smb_buf->WordCount));
680 		goto ssetup_exit;
681 	}
682 	action = le16_to_cpu(pSMB->resp.Action);
683 	if (action & GUEST_LOGIN)
684 		cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
685 	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
686 	cFYI(1, ("UID = %d ", ses->Suid));
687 	/* response can have either 3 or 4 word count - Samba sends 3 */
688 	/* and lanman response is 3 */
689 	bytes_remaining = BCC(smb_buf);
690 	bcc_ptr = pByteArea(smb_buf);
691 
692 	if (smb_buf->WordCount == 4) {
693 		__u16 blob_len;
694 		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
695 		bcc_ptr += blob_len;
696 		if (blob_len > bytes_remaining) {
697 			cERROR(1, ("bad security blob length %d", blob_len));
698 			rc = -EINVAL;
699 			goto ssetup_exit;
700 		}
701 		bytes_remaining -= blob_len;
702 	}
703 
704 	/* BB check if Unicode and decode strings */
705 	if (smb_buf->Flags2 & SMBFLG2_UNICODE)
706 		rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
707 						   ses, nls_cp);
708 	else
709 		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
710 					 ses, nls_cp);
711 
712 ssetup_exit:
713 	if (spnego_key) {
714 		key_revoke(spnego_key);
715 		key_put(spnego_key);
716 	}
717 	kfree(str_area);
718 	if (resp_buf_type == CIFS_SMALL_BUFFER) {
719 		cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
720 		cifs_small_buf_release(iov[0].iov_base);
721 	} else if (resp_buf_type == CIFS_LARGE_BUFFER)
722 		cifs_buf_release(iov[0].iov_base);
723 
724 	return rc;
725 }
726