sess.c revision 133672efbc1085f9af990bdc145e1822ea93bcf3
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
33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
34			 unsigned char *p24);
35
36static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
37{
38	__u32 capabilities = 0;
39
40	/* init fields common to all four types of SessSetup */
41	/* note that header is initialized to zero in header_assemble */
42	pSMB->req.AndXCommand = 0xFF;
43	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
44	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
45
46	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
47
48	/* BB verify whether signing required on neg or just on auth frame
49	   (and NTLM case) */
50
51	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
52			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
53
54	if (ses->server->secMode &
55	    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
56		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
57
58	if (ses->capabilities & CAP_UNICODE) {
59		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
60		capabilities |= CAP_UNICODE;
61	}
62	if (ses->capabilities & CAP_STATUS32) {
63		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
64		capabilities |= CAP_STATUS32;
65	}
66	if (ses->capabilities & CAP_DFS) {
67		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
68		capabilities |= CAP_DFS;
69	}
70	if (ses->capabilities & CAP_UNIX)
71		capabilities |= CAP_UNIX;
72
73	/* BB check whether to init vcnum BB */
74	return capabilities;
75}
76
77static void
78unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
79{
80	char *bcc_ptr = *pbcc_area;
81	int bytes_ret = 0;
82
83	/* Copy OS version */
84	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
85				  nls_cp);
86	bcc_ptr += 2 * bytes_ret;
87	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
88				  32, nls_cp);
89	bcc_ptr += 2 * bytes_ret;
90	bcc_ptr += 2; /* trailing null */
91
92	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
93				  32, nls_cp);
94	bcc_ptr += 2 * bytes_ret;
95	bcc_ptr += 2; /* trailing null */
96
97	*pbcc_area = bcc_ptr;
98}
99
100static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
101				   const struct nls_table *nls_cp)
102{
103	char *bcc_ptr = *pbcc_area;
104	int bytes_ret = 0;
105
106	/* copy domain */
107	if (ses->domainName == NULL) {
108		/* Sending null domain better than using a bogus domain name (as
109		we did briefly in 2.6.18) since server will use its default */
110		*bcc_ptr = 0;
111		*(bcc_ptr+1) = 0;
112		bytes_ret = 0;
113	} else
114		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
115					  256, nls_cp);
116	bcc_ptr += 2 * bytes_ret;
117	bcc_ptr += 2;  /* account for null terminator */
118
119	*pbcc_area = bcc_ptr;
120}
121
122
123static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
124				   const struct nls_table *nls_cp)
125{
126	char *bcc_ptr = *pbcc_area;
127	int bytes_ret = 0;
128
129	/* BB FIXME add check that strings total less
130	than 335 or will need to send them as arrays */
131
132	/* unicode strings, must be word aligned before the call */
133/*	if ((long) bcc_ptr % 2)	{
134		*bcc_ptr = 0;
135		bcc_ptr++;
136	} */
137	/* copy user */
138	if (ses->userName == NULL) {
139		/* null user mount */
140		*bcc_ptr = 0;
141		*(bcc_ptr+1) = 0;
142	} else { /* 300 should be long enough for any conceivable user name */
143		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
144					  300, nls_cp);
145	}
146	bcc_ptr += 2 * bytes_ret;
147	bcc_ptr += 2; /* account for null termination */
148
149	unicode_domain_string(&bcc_ptr, ses, nls_cp);
150	unicode_oslm_strings(&bcc_ptr, nls_cp);
151
152	*pbcc_area = bcc_ptr;
153}
154
155static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
156				 const struct nls_table *nls_cp)
157{
158	char *bcc_ptr = *pbcc_area;
159
160	/* copy user */
161	/* BB what about null user mounts - check that we do this BB */
162	/* copy user */
163	if (ses->userName == NULL) {
164		/* BB what about null user mounts - check that we do this BB */
165	} else { /* 300 should be long enough for any conceivable user name */
166		strncpy(bcc_ptr, ses->userName, 300);
167	}
168	/* BB improve check for overflow */
169	bcc_ptr += strnlen(ses->userName, 300);
170	*bcc_ptr = 0;
171	bcc_ptr++; /* account for null termination */
172
173	/* copy domain */
174
175	if (ses->domainName != NULL) {
176		strncpy(bcc_ptr, ses->domainName, 256);
177		bcc_ptr += strnlen(ses->domainName, 256);
178	} /* else we will send a null domain name
179	     so the server will default to its own domain */
180	*bcc_ptr = 0;
181	bcc_ptr++;
182
183	/* BB check for overflow here */
184
185	strcpy(bcc_ptr, "Linux version ");
186	bcc_ptr += strlen("Linux version ");
187	strcpy(bcc_ptr, init_utsname()->release);
188	bcc_ptr += strlen(init_utsname()->release) + 1;
189
190	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
191	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
192
193	*pbcc_area = bcc_ptr;
194}
195
196static int decode_unicode_ssetup(char **pbcc_area, int bleft,
197				 struct cifsSesInfo *ses,
198				 const struct nls_table *nls_cp)
199{
200	int rc = 0;
201	int words_left, len;
202	char *data = *pbcc_area;
203
204
205
206	cFYI(1, ("bleft %d", bleft));
207
208
209	/* SMB header is unaligned, so cifs servers word align start of
210	   Unicode strings */
211	data++;
212	bleft--; /* Windows servers do not always double null terminate
213		    their final Unicode string - in which case we
214		    now will not attempt to decode the byte of junk
215		    which follows it */
216
217	words_left = bleft / 2;
218
219	/* save off server operating system */
220	len = UniStrnlen((wchar_t *) data, words_left);
221
222/* We look for obvious messed up bcc or strings in response so we do not go off
223   the end since (at least) WIN2K and Windows XP have a major bug in not null
224   terminating last Unicode string in response  */
225	if (len >= words_left)
226		return rc;
227
228	kfree(ses->serverOS);
229	/* UTF-8 string will not grow more than four times as big as UCS-16 */
230	ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
231	if (ses->serverOS != NULL)
232		cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
233	data += 2 * (len + 1);
234	words_left -= len + 1;
235
236	/* save off server network operating system */
237	len = UniStrnlen((wchar_t *) data, words_left);
238
239	if (len >= words_left)
240		return rc;
241
242	kfree(ses->serverNOS);
243	ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
244	if (ses->serverNOS != NULL) {
245		cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
246				   nls_cp);
247		if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
248			cFYI(1, ("NT4 server"));
249			ses->flags |= CIFS_SES_NT4;
250		}
251	}
252	data += 2 * (len + 1);
253	words_left -= len + 1;
254
255	/* save off server domain */
256	len = UniStrnlen((wchar_t *) data, words_left);
257
258	if (len > words_left)
259		return rc;
260
261	kfree(ses->serverDomain);
262	ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
263	if (ses->serverDomain != NULL) {
264		cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
265				   nls_cp);
266		ses->serverDomain[2*len] = 0;
267		ses->serverDomain[(2*len) + 1] = 0;
268	}
269	data += 2 * (len + 1);
270	words_left -= len + 1;
271
272	cFYI(1, ("words left: %d", words_left));
273
274	return rc;
275}
276
277static int decode_ascii_ssetup(char **pbcc_area, int bleft,
278			       struct cifsSesInfo *ses,
279			       const struct nls_table *nls_cp)
280{
281	int rc = 0;
282	int len;
283	char *bcc_ptr = *pbcc_area;
284
285	cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
286
287	len = strnlen(bcc_ptr, bleft);
288	if (len >= bleft)
289		return rc;
290
291	kfree(ses->serverOS);
292
293	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
294	if (ses->serverOS)
295		strncpy(ses->serverOS, bcc_ptr, len);
296	if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
297			cFYI(1, ("OS/2 server"));
298			ses->flags |= CIFS_SES_OS2;
299	}
300
301	bcc_ptr += len + 1;
302	bleft -= len + 1;
303
304	len = strnlen(bcc_ptr, bleft);
305	if (len >= bleft)
306		return rc;
307
308	kfree(ses->serverNOS);
309
310	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
311	if (ses->serverNOS)
312		strncpy(ses->serverNOS, bcc_ptr, len);
313
314	bcc_ptr += len + 1;
315	bleft -= len + 1;
316
317	len = strnlen(bcc_ptr, bleft);
318	if (len > bleft)
319		return rc;
320
321	/* No domain field in LANMAN case. Domain is
322	   returned by old servers in the SMB negprot response */
323	/* BB For newer servers which do not support Unicode,
324	   but thus do return domain here we could add parsing
325	   for it later, but it is not very important */
326	cFYI(1, ("ascii: bytes left %d", bleft));
327
328	return rc;
329}
330
331int
332CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
333		const struct nls_table *nls_cp)
334{
335	int rc = 0;
336	int wct;
337	struct smb_hdr *smb_buf;
338	char *bcc_ptr;
339	char *str_area;
340	SESSION_SETUP_ANDX *pSMB;
341	__u32 capabilities;
342	int count;
343	int resp_buf_type = 0;
344	struct kvec iov[2];
345	enum securityEnum type;
346	__u16 action;
347	int bytes_remaining;
348
349	if (ses == NULL)
350		return -EINVAL;
351
352	type = ses->server->secType;
353
354	cFYI(1, ("sess setup type %d", type));
355	if (type == LANMAN) {
356#ifndef CONFIG_CIFS_WEAK_PW_HASH
357		/* LANMAN and plaintext are less secure and off by default.
358		So we make this explicitly be turned on in kconfig (in the
359		build) and turned on at runtime (changed from the default)
360		in proc/fs/cifs or via mount parm.  Unfortunately this is
361		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
362		return -EOPNOTSUPP;
363#endif
364		wct = 10; /* lanman 2 style sessionsetup */
365	} else if ((type == NTLM) || (type == NTLMv2)) {
366		/* For NTLMv2 failures eventually may need to retry NTLM */
367		wct = 13; /* old style NTLM sessionsetup */
368	} else /* same size: negotiate or auth, NTLMSSP or extended security */
369		wct = 12;
370
371	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
372			    (void **)&smb_buf);
373	if (rc)
374		return rc;
375
376	pSMB = (SESSION_SETUP_ANDX *)smb_buf;
377
378	capabilities = cifs_ssetup_hdr(ses, pSMB);
379
380	/* we will send the SMB in two pieces,
381	a fixed length beginning part, and a
382	second part which will include the strings
383	and rest of bcc area, in order to avoid having
384	to do a large buffer 17K allocation */
385	iov[0].iov_base = (char *)pSMB;
386	iov[0].iov_len = smb_buf->smb_buf_length + 4;
387
388	/* 2000 big enough to fit max user, domain, NOS name etc. */
389	str_area = kmalloc(2000, GFP_KERNEL);
390	if (str_area == NULL) {
391		cifs_small_buf_release(smb_buf);
392		return -ENOMEM;
393	}
394	bcc_ptr = str_area;
395
396	ses->flags &= ~CIFS_SES_LANMAN;
397
398	if (type == LANMAN) {
399#ifdef CONFIG_CIFS_WEAK_PW_HASH
400		char lnm_session_key[CIFS_SESS_KEY_SIZE];
401
402		/* no capabilities flags in old lanman negotiation */
403
404		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
405		/* BB calculate hash with password */
406		/* and copy into bcc */
407
408		calc_lanman_hash(ses, lnm_session_key);
409		ses->flags |= CIFS_SES_LANMAN;
410/* #ifdef CONFIG_CIFS_DEBUG2
411		cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
412			CIFS_SESS_KEY_SIZE);
413#endif */
414		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
415		bcc_ptr += CIFS_SESS_KEY_SIZE;
416
417		/* can not sign if LANMAN negotiated so no need
418		to calculate signing key? but what if server
419		changed to do higher than lanman dialect and
420		we reconnected would we ever calc signing_key? */
421
422		cFYI(1, ("Negotiating LANMAN setting up strings"));
423		/* Unicode not allowed for LANMAN dialects */
424		ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
425#endif
426	} else if (type == NTLM) {
427		char ntlm_session_key[CIFS_SESS_KEY_SIZE];
428
429		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
430		pSMB->req_no_secext.CaseInsensitivePasswordLength =
431			cpu_to_le16(CIFS_SESS_KEY_SIZE);
432		pSMB->req_no_secext.CaseSensitivePasswordLength =
433			cpu_to_le16(CIFS_SESS_KEY_SIZE);
434
435		/* calculate session key */
436		SMBNTencrypt(ses->password, ses->server->cryptKey,
437			     ntlm_session_key);
438
439		if (first_time) /* should this be moved into common code
440				  with similar ntlmv2 path? */
441			cifs_calculate_mac_key(&ses->server->mac_signing_key,
442				ntlm_session_key, ses->password);
443		/* copy session key */
444
445		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
446		bcc_ptr += CIFS_SESS_KEY_SIZE;
447		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
448		bcc_ptr += CIFS_SESS_KEY_SIZE;
449		if (ses->capabilities & CAP_UNICODE) {
450			/* unicode strings must be word aligned */
451			if (iov[0].iov_len % 2) {
452				*bcc_ptr = 0;
453				bcc_ptr++;
454			}
455			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
456		} else
457			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
458	} else if (type == NTLMv2) {
459		char *v2_sess_key =
460			kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
461
462		/* BB FIXME change all users of v2_sess_key to
463		   struct ntlmv2_resp */
464
465		if (v2_sess_key == NULL) {
466			cifs_small_buf_release(smb_buf);
467			return -ENOMEM;
468		}
469
470		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
471
472		/* LM2 password would be here if we supported it */
473		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
474		/*	cpu_to_le16(LM2_SESS_KEY_SIZE); */
475
476		pSMB->req_no_secext.CaseSensitivePasswordLength =
477			cpu_to_le16(sizeof(struct ntlmv2_resp));
478
479		/* calculate session key */
480		setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
481		if (first_time) /* should this be moved into common code
482				   with similar ntlmv2 path? */
483		/*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
484				response BB FIXME, v2_sess_key); */
485
486		/* copy session key */
487
488	/*	memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
489		bcc_ptr += LM2_SESS_KEY_SIZE; */
490		memcpy(bcc_ptr, (char *)v2_sess_key,
491		       sizeof(struct ntlmv2_resp));
492		bcc_ptr += sizeof(struct ntlmv2_resp);
493		kfree(v2_sess_key);
494		if (ses->capabilities & CAP_UNICODE) {
495			if (iov[0].iov_len % 2) {
496				*bcc_ptr = 0;
497				bcc_ptr++;
498			}
499			unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
500		} else
501			ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
502	} else /* NTLMSSP or SPNEGO */ {
503		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
504		capabilities |= CAP_EXTENDED_SECURITY;
505		pSMB->req.Capabilities = cpu_to_le32(capabilities);
506		/* BB set password lengths */
507	}
508
509	count = (long) bcc_ptr - (long) str_area;
510	smb_buf->smb_buf_length += count;
511
512	BCC_LE(smb_buf) = cpu_to_le16(count);
513
514	iov[1].iov_base = str_area;
515	iov[1].iov_len = count;
516	rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
517			  CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
518	/* SMB request buf freed in SendReceive2 */
519
520	cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
521	if (rc)
522		goto ssetup_exit;
523
524	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
525	smb_buf = (struct smb_hdr *)iov[0].iov_base;
526
527	if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
528		rc = -EIO;
529		cERROR(1, ("bad word count %d", smb_buf->WordCount));
530		goto ssetup_exit;
531	}
532	action = le16_to_cpu(pSMB->resp.Action);
533	if (action & GUEST_LOGIN)
534		cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
535	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
536	cFYI(1, ("UID = %d ", ses->Suid));
537	/* response can have either 3 or 4 word count - Samba sends 3 */
538	/* and lanman response is 3 */
539	bytes_remaining = BCC(smb_buf);
540	bcc_ptr = pByteArea(smb_buf);
541
542	if (smb_buf->WordCount == 4) {
543		__u16 blob_len;
544		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
545		bcc_ptr += blob_len;
546		if (blob_len > bytes_remaining) {
547			cERROR(1, ("bad security blob length %d", blob_len));
548			rc = -EINVAL;
549			goto ssetup_exit;
550		}
551		bytes_remaining -= blob_len;
552	}
553
554	/* BB check if Unicode and decode strings */
555	if (smb_buf->Flags2 & SMBFLG2_UNICODE)
556		rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
557						   ses, nls_cp);
558	else
559		rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
560					 ses, nls_cp);
561
562ssetup_exit:
563	kfree(str_area);
564	if (resp_buf_type == CIFS_SMALL_BUFFER) {
565		cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
566		cifs_small_buf_release(iov[0].iov_base);
567	} else if (resp_buf_type == CIFS_LARGE_BUFFER)
568		cifs_buf_release(iov[0].iov_base);
569
570	return rc;
571}
572