[CIFS] minor checkpatch cleanup
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / cifs / sess.c
CommitLineData
3979877e
SF
1/*
2 * fs/cifs/sess.c
3 *
4 * SMB/CIFS session setup handling routines
5 *
790fe579 6 * Copyright (c) International Business Machines Corp., 2006, 2007
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>
3979877e 32
3979877e 33extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
790fe579 34 unsigned char *p24);
3979877e 35
3979877e
SF
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
790fe579 48 /* BB verify whether signing required on neg or just on auth frame
3979877e
SF
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
790fe579
SF
54 if (ses->server->secMode &
55 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3979877e
SF
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 }
26f57364 70 if (ses->capabilities & CAP_UNIX)
3979877e 71 capabilities |= CAP_UNIX;
3979877e
SF
72
73 /* BB check whether to init vcnum BB */
74 return capabilities;
75}
76
0d3a01fa
JL
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
3870253e 123static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 124 const struct nls_table *nls_cp)
3979877e 125{
790fe579 126 char *bcc_ptr = *pbcc_area;
3979877e
SF
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
0223cf0b
SF
132 /* unicode strings, must be word aligned before the call */
133/* if ((long) bcc_ptr % 2) {
3979877e
SF
134 *bcc_ptr = 0;
135 bcc_ptr++;
0223cf0b 136 } */
3979877e 137 /* copy user */
790fe579 138 if (ses->userName == NULL) {
6e659c63
SF
139 /* null user mount */
140 *bcc_ptr = 0;
141 *(bcc_ptr+1) = 0;
3979877e
SF
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 */
3979877e 148
0d3a01fa
JL
149 unicode_domain_string(&bcc_ptr, ses, nls_cp);
150 unicode_oslm_strings(&bcc_ptr, nls_cp);
3979877e
SF
151
152 *pbcc_area = bcc_ptr;
153}
154
3870253e 155static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 156 const struct nls_table *nls_cp)
3979877e 157{
790fe579 158 char *bcc_ptr = *pbcc_area;
3979877e
SF
159
160 /* copy user */
161 /* BB what about null user mounts - check that we do this BB */
790fe579
SF
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 }
3979877e 168 /* BB improve check for overflow */
790fe579 169 bcc_ptr += strnlen(ses->userName, 300);
3979877e 170 *bcc_ptr = 0;
790fe579 171 bcc_ptr++; /* account for null termination */
3979877e 172
790fe579
SF
173 /* copy domain */
174
175 if (ses->domainName != NULL) {
176 strncpy(bcc_ptr, ses->domainName, 256);
3979877e 177 bcc_ptr += strnlen(ses->domainName, 256);
790fe579 178 } /* else we will send a null domain name
6e659c63 179 so the server will default to its own domain */
3979877e
SF
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 ");
96b644bd
SH
187 strcpy(bcc_ptr, init_utsname()->release);
188 bcc_ptr += strlen(init_utsname()->release) + 1;
3979877e
SF
189
190 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
191 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
192
790fe579 193 *pbcc_area = bcc_ptr;
3979877e
SF
194}
195
790fe579
SF
196static int decode_unicode_ssetup(char **pbcc_area, int bleft,
197 struct cifsSesInfo *ses,
198 const struct nls_table *nls_cp)
3979877e
SF
199{
200 int rc = 0;
201 int words_left, len;
790fe579 202 char *data = *pbcc_area;
3979877e
SF
203
204
205
790fe579 206 cFYI(1, ("bleft %d", bleft));
3979877e
SF
207
208
8e6f195a
SF
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 */
50c2f753 216
3979877e
SF
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 */
790fe579 225 if (len >= words_left)
3979877e
SF
226 return rc;
227
26f57364 228 kfree(ses->serverOS);
3979877e
SF
229 /* UTF-8 string will not grow more than four times as big as UCS-16 */
230 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
26f57364
SF
231 if (ses->serverOS != NULL)
232 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
3979877e
SF
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
790fe579 239 if (len >= words_left)
3979877e
SF
240 return rc;
241
26f57364 242 kfree(ses->serverNOS);
3979877e 243 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
790fe579 244 if (ses->serverNOS != NULL) {
3979877e
SF
245 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
246 nls_cp);
790fe579
SF
247 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
248 cFYI(1, ("NT4 server"));
3979877e
SF
249 ses->flags |= CIFS_SES_NT4;
250 }
251 }
252 data += 2 * (len + 1);
253 words_left -= len + 1;
254
790fe579
SF
255 /* save off server domain */
256 len = UniStrnlen((wchar_t *) data, words_left);
257
258 if (len > words_left)
259 return rc;
260
26f57364 261 kfree(ses->serverDomain);
790fe579
SF
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));
3979877e
SF
273
274 return rc;
275}
276
790fe579
SF
277static int decode_ascii_ssetup(char **pbcc_area, int bleft,
278 struct cifsSesInfo *ses,
279 const struct nls_table *nls_cp)
3979877e
SF
280{
281 int rc = 0;
282 int len;
790fe579 283 char *bcc_ptr = *pbcc_area;
3979877e 284
790fe579 285 cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
50c2f753 286
3979877e 287 len = strnlen(bcc_ptr, bleft);
790fe579 288 if (len >= bleft)
3979877e 289 return rc;
50c2f753 290
26f57364 291 kfree(ses->serverOS);
3979877e
SF
292
293 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 294 if (ses->serverOS)
3979877e 295 strncpy(ses->serverOS, bcc_ptr, len);
790fe579
SF
296 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
297 cFYI(1, ("OS/2 server"));
9ac00b7d
SF
298 ses->flags |= CIFS_SES_OS2;
299 }
3979877e
SF
300
301 bcc_ptr += len + 1;
302 bleft -= len + 1;
303
304 len = strnlen(bcc_ptr, bleft);
790fe579 305 if (len >= bleft)
3979877e
SF
306 return rc;
307
26f57364 308 kfree(ses->serverNOS);
3979877e
SF
309
310 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 311 if (ses->serverNOS)
3979877e
SF
312 strncpy(ses->serverNOS, bcc_ptr, len);
313
314 bcc_ptr += len + 1;
315 bleft -= len + 1;
316
790fe579
SF
317 len = strnlen(bcc_ptr, bleft);
318 if (len > bleft)
319 return rc;
3979877e 320
9ac00b7d
SF
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 */
790fe579 326 cFYI(1, ("ascii: bytes left %d", bleft));
3979877e
SF
327
328 return rc;
329}
330
790fe579 331int
3979877e
SF
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;
3979877e
SF
337 struct smb_hdr *smb_buf;
338 char *bcc_ptr;
750d1151 339 char *str_area;
3979877e
SF
340 SESSION_SETUP_ANDX *pSMB;
341 __u32 capabilities;
342 int count;
343 int resp_buf_type = 0;
750d1151 344 struct kvec iov[2];
3979877e
SF
345 enum securityEnum type;
346 __u16 action;
347 int bytes_remaining;
254e55ed 348
790fe579 349 if (ses == NULL)
3979877e
SF
350 return -EINVAL;
351
352 type = ses->server->secType;
f40c5628 353
790fe579
SF
354 cFYI(1, ("sess setup type %d", type));
355 if (type == LANMAN) {
3979877e
SF
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 */
790fe579 365 } else if ((type == NTLM) || (type == NTLMv2)) {
9312f675 366 /* For NTLMv2 failures eventually may need to retry NTLM */
3979877e 367 wct = 13; /* old style NTLM sessionsetup */
790fe579 368 } else /* same size: negotiate or auth, NTLMSSP or extended security */
3979877e
SF
369 wct = 12;
370
371 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
372 (void **)&smb_buf);
790fe579 373 if (rc)
3979877e
SF
374 return rc;
375
376 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
377
378 capabilities = cifs_ssetup_hdr(ses, pSMB);
750d1151
SF
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 */
790fe579
SF
385 iov[0].iov_base = (char *)pSMB;
386 iov[0].iov_len = smb_buf->smb_buf_length + 4;
750d1151
SF
387
388 /* 2000 big enough to fit max user, domain, NOS name etc. */
389 str_area = kmalloc(2000, GFP_KERNEL);
5e6e6232
CG
390 if (str_area == NULL) {
391 cifs_small_buf_release(smb_buf);
392 return -ENOMEM;
393 }
750d1151 394 bcc_ptr = str_area;
3979877e 395
9ac00b7d
SF
396 ses->flags &= ~CIFS_SES_LANMAN;
397
790fe579 398 if (type == LANMAN) {
3979877e 399#ifdef CONFIG_CIFS_WEAK_PW_HASH
7c7b25bc 400 char lnm_session_key[CIFS_SESS_KEY_SIZE];
3979877e
SF
401
402 /* no capabilities flags in old lanman negotiation */
403
790fe579 404 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e
SF
405 /* BB calculate hash with password */
406 /* and copy into bcc */
407
7c7b25bc 408 calc_lanman_hash(ses, lnm_session_key);
790fe579 409 ses->flags |= CIFS_SES_LANMAN;
750d1151 410/* #ifdef CONFIG_CIFS_DEBUG2
3979877e 411 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
7c7b25bc 412 CIFS_SESS_KEY_SIZE);
750d1151 413#endif */
7c7b25bc
SF
414 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
415 bcc_ptr += CIFS_SESS_KEY_SIZE;
3979877e
SF
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
790fe579 422 cFYI(1, ("Negotiating LANMAN setting up strings"));
3979877e
SF
423 /* Unicode not allowed for LANMAN dialects */
424 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
790fe579 425#endif
3979877e 426 } else if (type == NTLM) {
7c7b25bc 427 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3979877e
SF
428
429 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
430 pSMB->req_no_secext.CaseInsensitivePasswordLength =
7c7b25bc 431 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e 432 pSMB->req_no_secext.CaseSensitivePasswordLength =
7c7b25bc 433 cpu_to_le16(CIFS_SESS_KEY_SIZE);
50c2f753 434
3979877e
SF
435 /* calculate session key */
436 SMBNTencrypt(ses->password, ses->server->cryptKey,
437 ntlm_session_key);
438
790fe579 439 if (first_time) /* should this be moved into common code
3979877e 440 with similar ntlmv2 path? */
b609f06a 441 cifs_calculate_mac_key(&ses->server->mac_signing_key,
3979877e
SF
442 ntlm_session_key, ses->password);
443 /* copy session key */
444
790fe579 445 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 446 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 447 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 448 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 449 if (ses->capabilities & CAP_UNICODE) {
0223cf0b
SF
450 /* unicode strings must be word aligned */
451 if (iov[0].iov_len % 2) {
452 *bcc_ptr = 0;
790fe579
SF
453 bcc_ptr++;
454 }
7c7b25bc 455 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 456 } else
7c7b25bc
SF
457 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
458 } else if (type == NTLMv2) {
790fe579 459 char *v2_sess_key =
6d027cfd 460 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
f64b23ae
SF
461
462 /* BB FIXME change all users of v2_sess_key to
463 struct ntlmv2_resp */
7c7b25bc 464
790fe579 465 if (v2_sess_key == NULL) {
7c7b25bc
SF
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 =
f64b23ae 477 cpu_to_le16(sizeof(struct ntlmv2_resp));
7c7b25bc
SF
478
479 /* calculate session key */
1717ffc5 480 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
790fe579
SF
481 if (first_time) /* should this be moved into common code
482 with similar ntlmv2 path? */
7c7b25bc
SF
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; */
3870253e
SF
490 memcpy(bcc_ptr, (char *)v2_sess_key,
491 sizeof(struct ntlmv2_resp));
f64b23ae
SF
492 bcc_ptr += sizeof(struct ntlmv2_resp);
493 kfree(v2_sess_key);
790fe579
SF
494 if (ses->capabilities & CAP_UNICODE) {
495 if (iov[0].iov_len % 2) {
0223cf0b 496 *bcc_ptr = 0;
26f57364
SF
497 bcc_ptr++;
498 }
3979877e 499 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 500 } else
3979877e
SF
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
750d1151 509 count = (long) bcc_ptr - (long) str_area;
3979877e
SF
510 smb_buf->smb_buf_length += count;
511
3979877e
SF
512 BCC_LE(smb_buf) = cpu_to_le16(count);
513
750d1151 514 iov[1].iov_base = str_area;
790fe579 515 iov[1].iov_len = count;
a761ac57 516 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
133672ef 517 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
3979877e
SF
518 /* SMB request buf freed in SendReceive2 */
519
790fe579
SF
520 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
521 if (rc)
3979877e
SF
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
790fe579 527 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
3979877e 528 rc = -EIO;
790fe579 529 cERROR(1, ("bad word count %d", smb_buf->WordCount));
3979877e
SF
530 goto ssetup_exit;
531 }
532 action = le16_to_cpu(pSMB->resp.Action);
533 if (action & GUEST_LOGIN)
189acaae 534 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
3979877e
SF
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
790fe579 542 if (smb_buf->WordCount == 4) {
3979877e
SF
543 __u16 blob_len;
544 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
545 bcc_ptr += blob_len;
790fe579
SF
546 if (blob_len > bytes_remaining) {
547 cERROR(1, ("bad security blob length %d", blob_len));
3979877e
SF
548 rc = -EINVAL;
549 goto ssetup_exit;
550 }
551 bytes_remaining -= blob_len;
790fe579 552 }
3979877e
SF
553
554 /* BB check if Unicode and decode strings */
790fe579 555 if (smb_buf->Flags2 & SMBFLG2_UNICODE)
3979877e
SF
556 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
557 ses, nls_cp);
558 else
63135e08
SF
559 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
560 ses, nls_cp);
50c2f753 561
3979877e 562ssetup_exit:
750d1151 563 kfree(str_area);
790fe579
SF
564 if (resp_buf_type == CIFS_SMALL_BUFFER) {
565 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
3979877e 566 cifs_small_buf_release(iov[0].iov_base);
790fe579 567 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
3979877e
SF
568 cifs_buf_release(iov[0].iov_base);
569
570 return rc;
571}