xref: /linux/fs/smb/client/smb1session.c (revision f13208f26c052d06a10c53eda4c78c930f2b9c47)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  *
4  *   SMB/CIFS session setup handling routines
5  *
6  *   Copyright (c) International Business Machines  Corp., 2006, 2009
7  *   Author(s): Steve French (sfrench@us.ibm.com)
8  *
9  */
10 
11 #include "cifsproto.h"
12 #include "smb1proto.h"
13 #include "ntlmssp.h"
14 #include "nterr.h"
15 #include "cifs_spnego.h"
16 #include "cifs_unicode.h"
17 #include "cifs_debug.h"
18 
19 struct sess_data {
20 	unsigned int xid;
21 	struct cifs_ses *ses;
22 	struct TCP_Server_Info *server;
23 	void (*func)(struct sess_data *);
24 	int result;
25 	unsigned int in_len;
26 
27 	/* we will send the SMB in three pieces:
28 	 * a fixed length beginning part, an optional
29 	 * SPNEGO blob (which can be zero length), and a
30 	 * last part which will include the strings
31 	 * and rest of bcc area. This allows us to avoid
32 	 * a large buffer 17K allocation
33 	 */
34 	int buf0_type;
35 	struct kvec iov[3];
36 };
37 
38 static __u32 cifs_ssetup_hdr(struct cifs_ses *ses,
39 			     struct TCP_Server_Info *server,
40 			     SESSION_SETUP_ANDX *pSMB)
41 {
42 	__u32 capabilities = 0;
43 
44 	/* init fields common to all four types of SessSetup */
45 	/* Note that offsets for first seven fields in req struct are same  */
46 	/*	in CIFS Specs so does not matter which of 3 forms of struct */
47 	/*	that we use in next few lines                               */
48 	/* Note that header is initialized to zero in header_assemble */
49 	pSMB->req.AndXCommand = 0xFF;
50 	pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
51 					CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
52 					USHRT_MAX));
53 	pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq);
54 	pSMB->req.VcNumber = cpu_to_le16(1);
55 	pSMB->req.SessionKey = server->session_key_id;
56 
57 	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
58 
59 	/* BB verify whether signing required on neg or just auth frame (and NTLM case) */
60 
61 	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
62 			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
63 
64 	if (server->sign)
65 		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
66 
67 	if (ses->capabilities & CAP_UNICODE) {
68 		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
69 		capabilities |= CAP_UNICODE;
70 	}
71 	if (ses->capabilities & CAP_STATUS32) {
72 		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
73 		capabilities |= CAP_STATUS32;
74 	}
75 	if (ses->capabilities & CAP_DFS) {
76 		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
77 		capabilities |= CAP_DFS;
78 	}
79 	if (ses->capabilities & CAP_UNIX)
80 		capabilities |= CAP_UNIX;
81 
82 	return capabilities;
83 }
84 
85 static void
86 unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
87 {
88 	char *bcc_ptr = *pbcc_area;
89 	int bytes_ret = 0;
90 
91 	/* Copy OS version */
92 	bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
93 				    nls_cp);
94 	bcc_ptr += 2 * bytes_ret;
95 	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
96 				    32, nls_cp);
97 	bcc_ptr += 2 * bytes_ret;
98 	bcc_ptr += 2; /* trailing null */
99 
100 	bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
101 				    32, nls_cp);
102 	bcc_ptr += 2 * bytes_ret;
103 	bcc_ptr += 2; /* trailing null */
104 
105 	*pbcc_area = bcc_ptr;
106 }
107 
108 static void ascii_oslm_strings(char **pbcc_area)
109 {
110 	char *bcc_ptr = *pbcc_area;
111 
112 	strcpy(bcc_ptr, "Linux version ");
113 	bcc_ptr += strlen("Linux version ");
114 	strcpy(bcc_ptr, init_utsname()->release);
115 	bcc_ptr += strlen(init_utsname()->release) + 1;
116 
117 	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
118 	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
119 
120 	*pbcc_area = bcc_ptr;
121 }
122 
123 static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses)
124 {
125 	char *bcc_ptr = *pbcc_area;
126 	int bytes_ret = 0;
127 
128 	/* copy domain */
129 	if (ses->domainName == NULL) {
130 		/*
131 		 * Sending null domain better than using a bogus domain name (as
132 		 * we did briefly in 2.6.18) since server will use its default
133 		 */
134 		*bcc_ptr = 0;
135 		*(bcc_ptr+1) = 0;
136 		bytes_ret = 0;
137 	} else
138 		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
139 					    CIFS_MAX_DOMAINNAME_LEN,
140 					    ses->local_nls);
141 	bcc_ptr += 2 * bytes_ret;
142 	bcc_ptr += 2;  /* account for null terminator */
143 
144 	*pbcc_area = bcc_ptr;
145 }
146 
147 static void ascii_domain_string(char **pbcc_area, struct cifs_ses *ses)
148 {
149 	char *bcc_ptr = *pbcc_area;
150 	int len;
151 
152 	/* copy domain */
153 	if (ses->domainName != NULL) {
154 		len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
155 		if (WARN_ON_ONCE(len < 0))
156 			len = CIFS_MAX_DOMAINNAME_LEN - 1;
157 		bcc_ptr += len;
158 	} /* else we send a null domain name so server will default to its own domain */
159 	*bcc_ptr = 0;
160 	bcc_ptr++;
161 
162 	*pbcc_area = bcc_ptr;
163 }
164 
165 static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses)
166 {
167 	char *bcc_ptr = *pbcc_area;
168 	int bytes_ret = 0;
169 
170 	/* BB FIXME add check that strings less than 335 or will need to send as arrays */
171 
172 	/* copy user */
173 	if (ses->user_name == NULL) {
174 		/* null user mount */
175 		*bcc_ptr = 0;
176 		*(bcc_ptr+1) = 0;
177 	} else {
178 		bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
179 					    CIFS_MAX_USERNAME_LEN,
180 					    ses->local_nls);
181 	}
182 	bcc_ptr += 2 * bytes_ret;
183 	bcc_ptr += 2; /* account for null termination */
184 
185 	unicode_domain_string(&bcc_ptr, ses);
186 	unicode_oslm_strings(&bcc_ptr, ses->local_nls);
187 
188 	*pbcc_area = bcc_ptr;
189 }
190 
191 static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses)
192 {
193 	char *bcc_ptr = *pbcc_area;
194 	int len;
195 
196 	/* copy user */
197 	/* BB what about null user mounts - check that we do this BB */
198 	/* copy user */
199 	if (ses->user_name != NULL) {
200 		len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
201 		if (WARN_ON_ONCE(len < 0))
202 			len = CIFS_MAX_USERNAME_LEN - 1;
203 		bcc_ptr += len;
204 	}
205 	/* else null user mount */
206 	*bcc_ptr = 0;
207 	bcc_ptr++; /* account for null termination */
208 
209 	/* BB check for overflow here */
210 
211 	ascii_domain_string(&bcc_ptr, ses);
212 	ascii_oslm_strings(&bcc_ptr);
213 
214 	*pbcc_area = bcc_ptr;
215 }
216 
217 static void decode_unicode_ssetup(char **pbcc_area, int bleft,
218 				  struct cifs_ses *ses)
219 {
220 	int len;
221 	char *data = *pbcc_area;
222 
223 	cifs_dbg(FYI, "bleft %d\n", bleft);
224 
225 	kfree(ses->serverOS);
226 	ses->serverOS = cifs_strndup_from_utf16(data, bleft, true,
227 						ses->local_nls);
228 	cifs_dbg(FYI, "serverOS=%s\n", ses->serverOS);
229 	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
230 	data += len;
231 	bleft -= len;
232 	if (bleft <= 0)
233 		return;
234 
235 	kfree(ses->serverNOS);
236 	ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true,
237 						 ses->local_nls);
238 	cifs_dbg(FYI, "serverNOS=%s\n", ses->serverNOS);
239 	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
240 	data += len;
241 	bleft -= len;
242 	if (bleft <= 0)
243 		return;
244 
245 	kfree(ses->serverDomain);
246 	ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true,
247 						    ses->local_nls);
248 	cifs_dbg(FYI, "serverDomain=%s\n", ses->serverDomain);
249 
250 	return;
251 }
252 
253 static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
254 				struct cifs_ses *ses)
255 {
256 	int len;
257 	char *bcc_ptr = *pbcc_area;
258 
259 	cifs_dbg(FYI, "decode sessetup ascii. bleft %d\n", bleft);
260 
261 	len = strnlen(bcc_ptr, bleft);
262 	if (len >= bleft)
263 		return;
264 
265 	kfree(ses->serverOS);
266 
267 	ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
268 	if (ses->serverOS) {
269 		memcpy(ses->serverOS, bcc_ptr, len);
270 		ses->serverOS[len] = 0;
271 		if (strncmp(ses->serverOS, "OS/2", 4) == 0)
272 			cifs_dbg(FYI, "OS/2 server\n");
273 	}
274 
275 	bcc_ptr += len + 1;
276 	bleft -= len + 1;
277 
278 	len = strnlen(bcc_ptr, bleft);
279 	if (len >= bleft)
280 		return;
281 
282 	kfree(ses->serverNOS);
283 
284 	ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
285 	if (ses->serverNOS) {
286 		memcpy(ses->serverNOS, bcc_ptr, len);
287 		ses->serverNOS[len] = 0;
288 	}
289 
290 	bcc_ptr += len + 1;
291 	bleft -= len + 1;
292 
293 	len = strnlen(bcc_ptr, bleft);
294 	if (len > bleft)
295 		return;
296 
297 	/*
298 	 * No domain field in LANMAN case. Domain is
299 	 * returned by old servers in the SMB negprot response
300 	 *
301 	 * BB For newer servers which do not support Unicode,
302 	 * but thus do return domain here, we could add parsing
303 	 * for it later, but it is not very important
304 	 */
305 	cifs_dbg(FYI, "ascii: bytes left %d\n", bleft);
306 }
307 
308 static int
309 sess_alloc_buffer(struct sess_data *sess_data, int wct)
310 {
311 	int rc;
312 	struct cifs_ses *ses = sess_data->ses;
313 	struct smb_hdr *smb_buf;
314 
315 	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
316 				  (void **)&smb_buf);
317 
318 	if (rc < 0)
319 		return rc;
320 
321 	sess_data->in_len = rc;
322 	sess_data->iov[0].iov_base = (char *)smb_buf;
323 	sess_data->iov[0].iov_len = sess_data->in_len;
324 	/*
325 	 * This variable will be used to clear the buffer
326 	 * allocated above in case of any error in the calling function.
327 	 */
328 	sess_data->buf0_type = CIFS_SMALL_BUFFER;
329 
330 	/* 2000 big enough to fit max user, domain, NOS name etc. */
331 	sess_data->iov[2].iov_base = kmalloc(2000, GFP_KERNEL);
332 	if (!sess_data->iov[2].iov_base) {
333 		rc = -ENOMEM;
334 		goto out_free_smb_buf;
335 	}
336 
337 	return 0;
338 
339 out_free_smb_buf:
340 	cifs_small_buf_release(smb_buf);
341 	sess_data->iov[0].iov_base = NULL;
342 	sess_data->iov[0].iov_len = 0;
343 	sess_data->buf0_type = CIFS_NO_BUFFER;
344 	return rc;
345 }
346 
347 static void
348 sess_free_buffer(struct sess_data *sess_data)
349 {
350 	struct kvec *iov = sess_data->iov;
351 
352 	/*
353 	 * Zero the session data before freeing, as it might contain sensitive info (keys, etc).
354 	 * Note that iov[1] is already freed by caller.
355 	 */
356 	if (sess_data->buf0_type != CIFS_NO_BUFFER && iov[0].iov_base)
357 		memzero_explicit(iov[0].iov_base, iov[0].iov_len);
358 
359 	free_rsp_buf(sess_data->buf0_type, iov[0].iov_base);
360 	sess_data->buf0_type = CIFS_NO_BUFFER;
361 	kfree_sensitive(iov[2].iov_base);
362 }
363 
364 static int
365 sess_establish_session(struct sess_data *sess_data)
366 {
367 	struct cifs_ses *ses = sess_data->ses;
368 	struct TCP_Server_Info *server = sess_data->server;
369 
370 	cifs_server_lock(server);
371 	if (!server->session_estab) {
372 		if (server->sign) {
373 			server->session_key.response =
374 				kmemdup(ses->auth_key.response,
375 				ses->auth_key.len, GFP_KERNEL);
376 			if (!server->session_key.response) {
377 				cifs_server_unlock(server);
378 				return -ENOMEM;
379 			}
380 			server->session_key.len =
381 						ses->auth_key.len;
382 		}
383 		server->sequence_number = 0x2;
384 		server->session_estab = true;
385 	}
386 	cifs_server_unlock(server);
387 
388 	cifs_dbg(FYI, "CIFS session established successfully\n");
389 	return 0;
390 }
391 
392 static int
393 sess_sendreceive(struct sess_data *sess_data)
394 {
395 	int rc;
396 	struct smb_hdr *smb_buf = (struct smb_hdr *) sess_data->iov[0].iov_base;
397 	__u16 count;
398 	struct kvec rsp_iov = { NULL, 0 };
399 
400 	count = sess_data->iov[1].iov_len + sess_data->iov[2].iov_len;
401 	sess_data->in_len += count;
402 	put_bcc(count, smb_buf);
403 
404 	rc = SendReceive2(sess_data->xid, sess_data->ses,
405 			  sess_data->iov, 3 /* num_iovecs */,
406 			  &sess_data->buf0_type,
407 			  CIFS_LOG_ERROR, &rsp_iov);
408 	cifs_small_buf_release(sess_data->iov[0].iov_base);
409 	memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
410 
411 	return rc;
412 }
413 
414 static void
415 sess_auth_ntlmv2(struct sess_data *sess_data)
416 {
417 	int rc = 0;
418 	struct smb_hdr *smb_buf;
419 	SESSION_SETUP_ANDX *pSMB;
420 	char *bcc_ptr;
421 	struct cifs_ses *ses = sess_data->ses;
422 	struct TCP_Server_Info *server = sess_data->server;
423 	__u32 capabilities;
424 	__u16 bytes_remaining;
425 
426 	/* old style NTLM sessionsetup */
427 	/* wct = 13 */
428 	rc = sess_alloc_buffer(sess_data, 13);
429 	if (rc)
430 		goto out;
431 
432 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
433 	bcc_ptr = sess_data->iov[2].iov_base;
434 	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
435 
436 	pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
437 
438 	/* LM2 password would be here if we supported it */
439 	pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
440 
441 	if (ses->user_name != NULL) {
442 		/* calculate nlmv2 response and session key */
443 		rc = setup_ntlmv2_rsp(ses);
444 		if (rc) {
445 			cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
446 			goto out;
447 		}
448 
449 		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
450 				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
451 		bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
452 
453 		/* set case sensitive password length after tilen may get
454 		 * assigned, tilen is 0 otherwise.
455 		 */
456 		pSMB->req_no_secext.CaseSensitivePasswordLength =
457 			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
458 	} else {
459 		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
460 	}
461 
462 	if (ses->capabilities & CAP_UNICODE) {
463 		if (!IS_ALIGNED(sess_data->iov[0].iov_len, 2)) {
464 			*bcc_ptr = 0;
465 			bcc_ptr++;
466 		}
467 		unicode_ssetup_strings(&bcc_ptr, ses);
468 	} else {
469 		ascii_ssetup_strings(&bcc_ptr, ses);
470 	}
471 
472 
473 	sess_data->iov[2].iov_len = (long) bcc_ptr -
474 			(long) sess_data->iov[2].iov_base;
475 
476 	rc = sess_sendreceive(sess_data);
477 	if (rc)
478 		goto out;
479 
480 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
481 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
482 
483 	if (smb_buf->WordCount != 3) {
484 		rc = smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount);
485 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
486 		goto out;
487 	}
488 
489 	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
490 		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
491 
492 	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
493 	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
494 
495 	bytes_remaining = get_bcc(smb_buf);
496 	bcc_ptr = pByteArea(smb_buf);
497 
498 	/* BB check if Unicode and decode strings */
499 	if (bytes_remaining == 0) {
500 		/* no string area to decode, do nothing */
501 	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
502 		/* unicode string area must be word-aligned */
503 		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
504 			++bcc_ptr;
505 			--bytes_remaining;
506 		}
507 		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses);
508 	} else {
509 		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses);
510 	}
511 
512 	rc = sess_establish_session(sess_data);
513 out:
514 	sess_data->result = rc;
515 	sess_data->func = NULL;
516 	sess_free_buffer(sess_data);
517 	kfree_sensitive(ses->auth_key.response);
518 	ses->auth_key.response = NULL;
519 }
520 
521 #ifdef CONFIG_CIFS_UPCALL
522 static void
523 sess_auth_kerberos(struct sess_data *sess_data)
524 {
525 	int rc = 0;
526 	struct smb_hdr *smb_buf;
527 	SESSION_SETUP_ANDX *pSMB;
528 	char *bcc_ptr;
529 	struct cifs_ses *ses = sess_data->ses;
530 	struct TCP_Server_Info *server = sess_data->server;
531 	__u32 capabilities;
532 	__u16 bytes_remaining;
533 	struct key *spnego_key = NULL;
534 	struct cifs_spnego_msg *msg;
535 	u16 blob_len;
536 
537 	/* extended security */
538 	/* wct = 12 */
539 	rc = sess_alloc_buffer(sess_data, 12);
540 	if (rc)
541 		goto out;
542 
543 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
544 	bcc_ptr = sess_data->iov[2].iov_base;
545 	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
546 
547 	spnego_key = cifs_get_spnego_key(ses, server);
548 	if (IS_ERR(spnego_key)) {
549 		rc = PTR_ERR(spnego_key);
550 		spnego_key = NULL;
551 		goto out;
552 	}
553 
554 	msg = spnego_key->payload.data[0];
555 	/*
556 	 * check version field to make sure that cifs.upcall is
557 	 * sending us a response in an expected form
558 	 */
559 	if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
560 		cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
561 			 CIFS_SPNEGO_UPCALL_VERSION, msg->version);
562 		rc = -EKEYREJECTED;
563 		goto out_put_spnego_key;
564 	}
565 
566 	kfree_sensitive(ses->auth_key.response);
567 	ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
568 					 GFP_KERNEL);
569 	if (!ses->auth_key.response) {
570 		cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
571 			 msg->sesskey_len);
572 		rc = -ENOMEM;
573 		goto out_put_spnego_key;
574 	}
575 	ses->auth_key.len = msg->sesskey_len;
576 
577 	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
578 	capabilities |= CAP_EXTENDED_SECURITY;
579 	pSMB->req.Capabilities = cpu_to_le32(capabilities);
580 	sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
581 	sess_data->iov[1].iov_len = msg->secblob_len;
582 	pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
583 
584 	if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
585 		/* unicode strings must be word aligned */
586 		if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
587 			*bcc_ptr = 0;
588 			bcc_ptr++;
589 		}
590 		unicode_oslm_strings(&bcc_ptr, sess_data->ses->local_nls);
591 		unicode_domain_string(&bcc_ptr, ses);
592 	} else {
593 		ascii_oslm_strings(&bcc_ptr);
594 		ascii_domain_string(&bcc_ptr, ses);
595 	}
596 
597 	sess_data->iov[2].iov_len = (long) bcc_ptr -
598 			(long) sess_data->iov[2].iov_base;
599 
600 	rc = sess_sendreceive(sess_data);
601 	if (rc)
602 		goto out_put_spnego_key;
603 
604 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
605 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
606 
607 	if (smb_buf->WordCount != 4) {
608 		rc = smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount);
609 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
610 		goto out_put_spnego_key;
611 	}
612 
613 	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
614 		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
615 
616 	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
617 	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
618 
619 	bytes_remaining = get_bcc(smb_buf);
620 	bcc_ptr = pByteArea(smb_buf);
621 
622 	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
623 	if (blob_len > bytes_remaining) {
624 		cifs_dbg(VFS, "bad security blob length %d\n",
625 				blob_len);
626 		rc = -EINVAL;
627 		goto out_put_spnego_key;
628 	}
629 	bcc_ptr += blob_len;
630 	bytes_remaining -= blob_len;
631 
632 	/* BB check if Unicode and decode strings */
633 	if (bytes_remaining == 0) {
634 		/* no string area to decode, do nothing */
635 	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
636 		/* unicode string area must be word-aligned */
637 		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
638 			++bcc_ptr;
639 			--bytes_remaining;
640 		}
641 		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses);
642 	} else {
643 		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses);
644 	}
645 
646 	rc = sess_establish_session(sess_data);
647 out_put_spnego_key:
648 	key_invalidate(spnego_key);
649 	key_put(spnego_key);
650 out:
651 	sess_data->result = rc;
652 	sess_data->func = NULL;
653 	sess_free_buffer(sess_data);
654 	kfree_sensitive(ses->auth_key.response);
655 	ses->auth_key.response = NULL;
656 }
657 
658 #endif /* ! CONFIG_CIFS_UPCALL */
659 
660 /*
661  * The required kvec buffers have to be allocated before calling this
662  * function.
663  */
664 static int
665 _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data)
666 {
667 	SESSION_SETUP_ANDX *pSMB;
668 	struct cifs_ses *ses = sess_data->ses;
669 	struct TCP_Server_Info *server = sess_data->server;
670 	__u32 capabilities;
671 	char *bcc_ptr;
672 
673 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
674 
675 	capabilities = cifs_ssetup_hdr(ses, server, pSMB);
676 	pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
677 	capabilities |= CAP_EXTENDED_SECURITY;
678 	pSMB->req.Capabilities |= cpu_to_le32(capabilities);
679 
680 	bcc_ptr = sess_data->iov[2].iov_base;
681 
682 	if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) {
683 		/* unicode strings must be word aligned */
684 		if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) {
685 			*bcc_ptr = 0;
686 			bcc_ptr++;
687 		}
688 		unicode_oslm_strings(&bcc_ptr, sess_data->ses->local_nls);
689 	} else {
690 		ascii_oslm_strings(&bcc_ptr);
691 	}
692 
693 	sess_data->iov[2].iov_len = (long) bcc_ptr -
694 					(long) sess_data->iov[2].iov_base;
695 
696 	return 0;
697 }
698 
699 static void
700 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data);
701 
702 static void
703 sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
704 {
705 	int rc;
706 	struct smb_hdr *smb_buf;
707 	SESSION_SETUP_ANDX *pSMB;
708 	struct cifs_ses *ses = sess_data->ses;
709 	struct TCP_Server_Info *server = sess_data->server;
710 	__u16 bytes_remaining;
711 	char *bcc_ptr;
712 	unsigned char *ntlmsspblob = NULL;
713 	u16 blob_len;
714 
715 	cifs_dbg(FYI, "rawntlmssp session setup negotiate phase\n");
716 
717 	/*
718 	 * if memory allocation is successful, caller of this function
719 	 * frees it.
720 	 */
721 	ses->ntlmssp = kmalloc_obj(struct ntlmssp_auth);
722 	if (!ses->ntlmssp) {
723 		rc = -ENOMEM;
724 		goto out;
725 	}
726 	ses->ntlmssp->sesskey_per_smbsess = false;
727 
728 	/* wct = 12 */
729 	rc = sess_alloc_buffer(sess_data, 12);
730 	if (rc)
731 		goto out;
732 
733 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
734 
735 	/* Build security blob before we assemble the request */
736 	rc = build_ntlmssp_negotiate_blob(&ntlmsspblob,
737 				     &blob_len, ses, server);
738 	if (rc)
739 		goto out_free_ntlmsspblob;
740 
741 	sess_data->iov[1].iov_len = blob_len;
742 	sess_data->iov[1].iov_base = ntlmsspblob;
743 	pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
744 
745 	rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
746 	if (rc)
747 		goto out_free_ntlmsspblob;
748 
749 	rc = sess_sendreceive(sess_data);
750 
751 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
752 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
753 
754 	/* If true, rc here is expected and not an error */
755 	if (sess_data->buf0_type != CIFS_NO_BUFFER &&
756 	    smb_buf->Status.CifsError ==
757 			cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
758 		rc = 0;
759 
760 	if (rc)
761 		goto out_free_ntlmsspblob;
762 
763 	cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
764 
765 	if (smb_buf->WordCount != 4) {
766 		rc = smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount);
767 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
768 		goto out_free_ntlmsspblob;
769 	}
770 
771 	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
772 	cifs_dbg(FYI, "UID = %llu\n", ses->Suid);
773 
774 	bytes_remaining = get_bcc(smb_buf);
775 	bcc_ptr = pByteArea(smb_buf);
776 
777 	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
778 	if (blob_len > bytes_remaining) {
779 		cifs_dbg(VFS, "bad security blob length %d\n",
780 				blob_len);
781 		rc = -EINVAL;
782 		goto out_free_ntlmsspblob;
783 	}
784 
785 	rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
786 
787 out_free_ntlmsspblob:
788 	kfree_sensitive(ntlmsspblob);
789 out:
790 	sess_free_buffer(sess_data);
791 
792 	if (!rc) {
793 		sess_data->func = sess_auth_rawntlmssp_authenticate;
794 		return;
795 	}
796 
797 	/* Else error. Cleanup */
798 	kfree_sensitive(ses->auth_key.response);
799 	ses->auth_key.response = NULL;
800 	kfree_sensitive(ses->ntlmssp);
801 	ses->ntlmssp = NULL;
802 
803 	sess_data->func = NULL;
804 	sess_data->result = rc;
805 }
806 
807 static void
808 sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
809 {
810 	int rc;
811 	struct smb_hdr *smb_buf;
812 	SESSION_SETUP_ANDX *pSMB;
813 	struct cifs_ses *ses = sess_data->ses;
814 	struct TCP_Server_Info *server = sess_data->server;
815 	__u16 bytes_remaining;
816 	char *bcc_ptr;
817 	unsigned char *ntlmsspblob = NULL;
818 	u16 blob_len;
819 
820 	cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
821 
822 	/* wct = 12 */
823 	rc = sess_alloc_buffer(sess_data, 12);
824 	if (rc)
825 		goto out;
826 
827 	/* Build security blob before we assemble the request */
828 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
829 	smb_buf = (struct smb_hdr *)pSMB;
830 	rc = build_ntlmssp_auth_blob(&ntlmsspblob,
831 					&blob_len, ses, server);
832 	if (rc)
833 		goto out_free_ntlmsspblob;
834 	sess_data->iov[1].iov_len = blob_len;
835 	sess_data->iov[1].iov_base = ntlmsspblob;
836 	pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
837 	/*
838 	 * Make sure that we tell the server that we are using
839 	 * the uid that it just gave us back on the response
840 	 * (challenge)
841 	 */
842 	smb_buf->Uid = ses->Suid;
843 
844 	rc = _sess_auth_rawntlmssp_assemble_req(sess_data);
845 	if (rc)
846 		goto out_free_ntlmsspblob;
847 
848 	rc = sess_sendreceive(sess_data);
849 	if (rc)
850 		goto out_free_ntlmsspblob;
851 
852 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
853 	smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
854 	if (smb_buf->WordCount != 4) {
855 		rc = smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount);
856 		cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
857 		goto out_free_ntlmsspblob;
858 	}
859 
860 	if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN)
861 		cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */
862 
863 	if (ses->Suid != smb_buf->Uid) {
864 		ses->Suid = smb_buf->Uid;
865 		cifs_dbg(FYI, "UID changed! new UID = %llu\n", ses->Suid);
866 	}
867 
868 	bytes_remaining = get_bcc(smb_buf);
869 	bcc_ptr = pByteArea(smb_buf);
870 	blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
871 	if (blob_len > bytes_remaining) {
872 		cifs_dbg(VFS, "bad security blob length %d\n",
873 				blob_len);
874 		rc = -EINVAL;
875 		goto out_free_ntlmsspblob;
876 	}
877 	bcc_ptr += blob_len;
878 	bytes_remaining -= blob_len;
879 
880 
881 	/* BB check if Unicode and decode strings */
882 	if (bytes_remaining == 0) {
883 		/* no string area to decode, do nothing */
884 	} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
885 		/* unicode string area must be word-aligned */
886 		if (!IS_ALIGNED((unsigned long)bcc_ptr - (unsigned long)smb_buf, 2)) {
887 			++bcc_ptr;
888 			--bytes_remaining;
889 		}
890 		decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses);
891 	} else {
892 		decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses);
893 	}
894 
895 out_free_ntlmsspblob:
896 	kfree_sensitive(ntlmsspblob);
897 out:
898 	sess_free_buffer(sess_data);
899 
900 	if (!rc)
901 		rc = sess_establish_session(sess_data);
902 
903 	/* Cleanup */
904 	kfree_sensitive(ses->auth_key.response);
905 	ses->auth_key.response = NULL;
906 	kfree_sensitive(ses->ntlmssp);
907 	ses->ntlmssp = NULL;
908 
909 	sess_data->func = NULL;
910 	sess_data->result = rc;
911 }
912 
913 static int select_sec(struct sess_data *sess_data)
914 {
915 	int type;
916 	struct cifs_ses *ses = sess_data->ses;
917 	struct TCP_Server_Info *server = sess_data->server;
918 
919 	type = cifs_select_sectype(server, ses->sectype);
920 	cifs_dbg(FYI, "sess setup type %d\n", type);
921 	if (type == Unspecified) {
922 		cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
923 		return -EINVAL;
924 	}
925 
926 	switch (type) {
927 	case NTLMv2:
928 		sess_data->func = sess_auth_ntlmv2;
929 		break;
930 	case Kerberos:
931 #ifdef CONFIG_CIFS_UPCALL
932 		sess_data->func = sess_auth_kerberos;
933 		break;
934 #else
935 		cifs_dbg(VFS, "Kerberos negotiated but upcall support disabled!\n");
936 		return -ENOSYS;
937 #endif /* CONFIG_CIFS_UPCALL */
938 	case RawNTLMSSP:
939 		sess_data->func = sess_auth_rawntlmssp_negotiate;
940 		break;
941 	default:
942 		cifs_dbg(VFS, "secType %d not supported!\n", type);
943 		return -ENOSYS;
944 	}
945 
946 	return 0;
947 }
948 
949 int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
950 		   struct TCP_Server_Info *server)
951 {
952 	struct sess_data sess_data;
953 	int rc = 0;
954 
955 	if (ses == NULL) {
956 		WARN(1, "%s: ses == NULL!", __func__);
957 		return -EINVAL;
958 	}
959 
960 	sess_data = (struct sess_data) {
961 		.xid		= xid,
962 		.ses		= ses,
963 		.server		= server,
964 		.buf0_type	= CIFS_NO_BUFFER,
965 	};
966 
967 	rc = select_sec(&sess_data);
968 	if (rc)
969 		goto out;
970 
971 	while (sess_data.func)
972 		sess_data.func(&sess_data);
973 
974 	rc = sess_data.result;
975 
976 out:
977 	memzero_explicit(&sess_data, sizeof(sess_data));
978 	return rc;
979 }
980