4 * SMB/CIFS session setup handling routines
6 * Copyright (c) International Business Machines Corp., 2006, 2007
7 * Author(s): Steve French (sfrench@us.ibm.com)
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.
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.
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
26 #include "cifsproto.h"
27 #include "cifs_unicode.h"
28 #include "cifs_debug.h"
31 #include <linux/utsname.h>
33 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
36 static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
38 __u32 capabilities = 0;
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);
46 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
48 /* BB verify whether signing required on neg or just on auth frame
51 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
52 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
54 if (ses->server->secMode &
55 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
56 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
58 if (ses->capabilities & CAP_UNICODE) {
59 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
60 capabilities |= CAP_UNICODE;
62 if (ses->capabilities & CAP_STATUS32) {
63 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
64 capabilities |= CAP_STATUS32;
66 if (ses->capabilities & CAP_DFS) {
67 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
68 capabilities |= CAP_DFS;
70 if (ses->capabilities & CAP_UNIX)
71 capabilities |= CAP_UNIX;
73 /* BB check whether to init vcnum BB */
77 static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
78 const struct nls_table *nls_cp)
80 char *bcc_ptr = *pbcc_area;
83 /* BB FIXME add check that strings total less
84 than 335 or will need to send them as arrays */
86 /* unicode strings, must be word aligned before the call */
87 /* if ((long) bcc_ptr % 2) {
92 if (ses->userName == NULL) {
96 } else { /* 300 should be long enough for any conceivable user name */
97 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
100 bcc_ptr += 2 * bytes_ret;
101 bcc_ptr += 2; /* account for null termination */
103 if (ses->domainName == NULL) {
104 /* Sending null domain better than using a bogus domain name (as
105 we did briefly in 2.6.18) since server will use its default */
110 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
112 bcc_ptr += 2 * bytes_ret;
113 bcc_ptr += 2; /* account for null terminator */
115 /* Copy OS version */
116 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
118 bcc_ptr += 2 * bytes_ret;
119 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
121 bcc_ptr += 2 * bytes_ret;
122 bcc_ptr += 2; /* trailing null */
124 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
126 bcc_ptr += 2 * bytes_ret;
127 bcc_ptr += 2; /* trailing null */
129 *pbcc_area = bcc_ptr;
132 static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
133 const struct nls_table *nls_cp)
135 char *bcc_ptr = *pbcc_area;
138 /* BB what about null user mounts - check that we do this BB */
140 if (ses->userName == NULL) {
141 /* BB what about null user mounts - check that we do this BB */
142 } else { /* 300 should be long enough for any conceivable user name */
143 strncpy(bcc_ptr, ses->userName, 300);
145 /* BB improve check for overflow */
146 bcc_ptr += strnlen(ses->userName, 300);
148 bcc_ptr++; /* account for null termination */
152 if (ses->domainName != NULL) {
153 strncpy(bcc_ptr, ses->domainName, 256);
154 bcc_ptr += strnlen(ses->domainName, 256);
155 } /* else we will send a null domain name
156 so the server will default to its own domain */
160 /* BB check for overflow here */
162 strcpy(bcc_ptr, "Linux version ");
163 bcc_ptr += strlen("Linux version ");
164 strcpy(bcc_ptr, init_utsname()->release);
165 bcc_ptr += strlen(init_utsname()->release) + 1;
167 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
168 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
170 *pbcc_area = bcc_ptr;
173 static int decode_unicode_ssetup(char **pbcc_area, int bleft,
174 struct cifsSesInfo *ses,
175 const struct nls_table *nls_cp)
179 char *data = *pbcc_area;
183 cFYI(1, ("bleft %d", bleft));
186 /* SMB header is unaligned, so cifs servers word align start of
189 bleft--; /* Windows servers do not always double null terminate
190 their final Unicode string - in which case we
191 now will not attempt to decode the byte of junk
194 words_left = bleft / 2;
196 /* save off server operating system */
197 len = UniStrnlen((wchar_t *) data, words_left);
199 /* We look for obvious messed up bcc or strings in response so we do not go off
200 the end since (at least) WIN2K and Windows XP have a major bug in not null
201 terminating last Unicode string in response */
202 if (len >= words_left)
205 kfree(ses->serverOS);
206 /* UTF-8 string will not grow more than four times as big as UCS-16 */
207 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
208 if (ses->serverOS != NULL)
209 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
210 data += 2 * (len + 1);
211 words_left -= len + 1;
213 /* save off server network operating system */
214 len = UniStrnlen((wchar_t *) data, words_left);
216 if (len >= words_left)
219 kfree(ses->serverNOS);
220 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
221 if (ses->serverNOS != NULL) {
222 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
224 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
225 cFYI(1, ("NT4 server"));
226 ses->flags |= CIFS_SES_NT4;
229 data += 2 * (len + 1);
230 words_left -= len + 1;
232 /* save off server domain */
233 len = UniStrnlen((wchar_t *) data, words_left);
235 if (len > words_left)
238 kfree(ses->serverDomain);
239 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
240 if (ses->serverDomain != NULL) {
241 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
243 ses->serverDomain[2*len] = 0;
244 ses->serverDomain[(2*len) + 1] = 0;
246 data += 2 * (len + 1);
247 words_left -= len + 1;
249 cFYI(1, ("words left: %d", words_left));
254 static int decode_ascii_ssetup(char **pbcc_area, int bleft,
255 struct cifsSesInfo *ses,
256 const struct nls_table *nls_cp)
260 char *bcc_ptr = *pbcc_area;
262 cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
264 len = strnlen(bcc_ptr, bleft);
268 kfree(ses->serverOS);
270 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
272 strncpy(ses->serverOS, bcc_ptr, len);
273 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
274 cFYI(1, ("OS/2 server"));
275 ses->flags |= CIFS_SES_OS2;
281 len = strnlen(bcc_ptr, bleft);
285 kfree(ses->serverNOS);
287 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
289 strncpy(ses->serverNOS, bcc_ptr, len);
294 len = strnlen(bcc_ptr, bleft);
298 /* No domain field in LANMAN case. Domain is
299 returned by old servers in the SMB negprot response */
300 /* BB For newer servers which do not support Unicode,
301 but thus do return domain here we could add parsing
302 for it later, but it is not very important */
303 cFYI(1, ("ascii: bytes left %d", bleft));
309 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
310 const struct nls_table *nls_cp)
314 struct smb_hdr *smb_buf;
317 SESSION_SETUP_ANDX *pSMB;
320 int resp_buf_type = 0;
322 enum securityEnum type;
329 type = ses->server->secType;
331 cFYI(1, ("sess setup type %d", type));
332 if (type == LANMAN) {
333 #ifndef CONFIG_CIFS_WEAK_PW_HASH
334 /* LANMAN and plaintext are less secure and off by default.
335 So we make this explicitly be turned on in kconfig (in the
336 build) and turned on at runtime (changed from the default)
337 in proc/fs/cifs or via mount parm. Unfortunately this is
338 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
341 wct = 10; /* lanman 2 style sessionsetup */
342 } else if ((type == NTLM) || (type == NTLMv2)) {
343 /* For NTLMv2 failures eventually may need to retry NTLM */
344 wct = 13; /* old style NTLM sessionsetup */
345 } else /* same size: negotiate or auth, NTLMSSP or extended security */
348 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
353 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
355 capabilities = cifs_ssetup_hdr(ses, pSMB);
357 /* we will send the SMB in two pieces,
358 a fixed length beginning part, and a
359 second part which will include the strings
360 and rest of bcc area, in order to avoid having
361 to do a large buffer 17K allocation */
362 iov[0].iov_base = (char *)pSMB;
363 iov[0].iov_len = smb_buf->smb_buf_length + 4;
365 /* 2000 big enough to fit max user, domain, NOS name etc. */
366 str_area = kmalloc(2000, GFP_KERNEL);
367 if (str_area == NULL) {
368 cifs_small_buf_release(smb_buf);
373 ses->flags &= ~CIFS_SES_LANMAN;
375 if (type == LANMAN) {
376 #ifdef CONFIG_CIFS_WEAK_PW_HASH
377 char lnm_session_key[CIFS_SESS_KEY_SIZE];
379 /* no capabilities flags in old lanman negotiation */
381 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
382 /* BB calculate hash with password */
383 /* and copy into bcc */
385 calc_lanman_hash(ses, lnm_session_key);
386 ses->flags |= CIFS_SES_LANMAN;
387 /* #ifdef CONFIG_CIFS_DEBUG2
388 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
391 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
392 bcc_ptr += CIFS_SESS_KEY_SIZE;
394 /* can not sign if LANMAN negotiated so no need
395 to calculate signing key? but what if server
396 changed to do higher than lanman dialect and
397 we reconnected would we ever calc signing_key? */
399 cFYI(1, ("Negotiating LANMAN setting up strings"));
400 /* Unicode not allowed for LANMAN dialects */
401 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
403 } else if (type == NTLM) {
404 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
406 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
407 pSMB->req_no_secext.CaseInsensitivePasswordLength =
408 cpu_to_le16(CIFS_SESS_KEY_SIZE);
409 pSMB->req_no_secext.CaseSensitivePasswordLength =
410 cpu_to_le16(CIFS_SESS_KEY_SIZE);
412 /* calculate session key */
413 SMBNTencrypt(ses->password, ses->server->cryptKey,
416 if (first_time) /* should this be moved into common code
417 with similar ntlmv2 path? */
418 cifs_calculate_mac_key(&ses->server->mac_signing_key,
419 ntlm_session_key, ses->password);
420 /* copy session key */
422 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
423 bcc_ptr += CIFS_SESS_KEY_SIZE;
424 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
425 bcc_ptr += CIFS_SESS_KEY_SIZE;
426 if (ses->capabilities & CAP_UNICODE) {
427 /* unicode strings must be word aligned */
428 if (iov[0].iov_len % 2) {
432 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
434 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
435 } else if (type == NTLMv2) {
437 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
439 /* BB FIXME change all users of v2_sess_key to
440 struct ntlmv2_resp */
442 if (v2_sess_key == NULL) {
443 cifs_small_buf_release(smb_buf);
447 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
449 /* LM2 password would be here if we supported it */
450 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
451 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */
453 pSMB->req_no_secext.CaseSensitivePasswordLength =
454 cpu_to_le16(sizeof(struct ntlmv2_resp));
456 /* calculate session key */
457 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
458 if (first_time) /* should this be moved into common code
459 with similar ntlmv2 path? */
460 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
461 response BB FIXME, v2_sess_key); */
463 /* copy session key */
465 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
466 bcc_ptr += LM2_SESS_KEY_SIZE; */
467 memcpy(bcc_ptr, (char *)v2_sess_key,
468 sizeof(struct ntlmv2_resp));
469 bcc_ptr += sizeof(struct ntlmv2_resp);
471 if (ses->capabilities & CAP_UNICODE) {
472 if (iov[0].iov_len % 2) {
476 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
478 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
479 } else /* NTLMSSP or SPNEGO */ {
480 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
481 capabilities |= CAP_EXTENDED_SECURITY;
482 pSMB->req.Capabilities = cpu_to_le32(capabilities);
483 /* BB set password lengths */
486 count = (long) bcc_ptr - (long) str_area;
487 smb_buf->smb_buf_length += count;
489 BCC_LE(smb_buf) = cpu_to_le16(count);
491 iov[1].iov_base = str_area;
492 iov[1].iov_len = count;
493 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
494 /* SMB request buf freed in SendReceive2 */
496 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
500 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
501 smb_buf = (struct smb_hdr *)iov[0].iov_base;
503 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
505 cERROR(1, ("bad word count %d", smb_buf->WordCount));
508 action = le16_to_cpu(pSMB->resp.Action);
509 if (action & GUEST_LOGIN)
510 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
511 ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
512 cFYI(1, ("UID = %d ", ses->Suid));
513 /* response can have either 3 or 4 word count - Samba sends 3 */
514 /* and lanman response is 3 */
515 bytes_remaining = BCC(smb_buf);
516 bcc_ptr = pByteArea(smb_buf);
518 if (smb_buf->WordCount == 4) {
520 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
522 if (blob_len > bytes_remaining) {
523 cERROR(1, ("bad security blob length %d", blob_len));
527 bytes_remaining -= blob_len;
530 /* BB check if Unicode and decode strings */
531 if (smb_buf->Flags2 & SMBFLG2_UNICODE)
532 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
535 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
540 if (resp_buf_type == CIFS_SMALL_BUFFER) {
541 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
542 cifs_small_buf_release(iov[0].iov_base);
543 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
544 cifs_buf_release(iov[0].iov_base);