]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/sess.c
[CIFS] parse server_GUID in SPNEGO negProt response
[net-next-2.6.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
3870253e 77static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 78 const struct nls_table *nls_cp)
3979877e 79{
790fe579 80 char *bcc_ptr = *pbcc_area;
3979877e
SF
81 int bytes_ret = 0;
82
83 /* BB FIXME add check that strings total less
84 than 335 or will need to send them as arrays */
85
0223cf0b
SF
86 /* unicode strings, must be word aligned before the call */
87/* if ((long) bcc_ptr % 2) {
3979877e
SF
88 *bcc_ptr = 0;
89 bcc_ptr++;
0223cf0b 90 } */
3979877e 91 /* copy user */
790fe579 92 if (ses->userName == NULL) {
6e659c63
SF
93 /* null user mount */
94 *bcc_ptr = 0;
95 *(bcc_ptr+1) = 0;
3979877e
SF
96 } else { /* 300 should be long enough for any conceivable user name */
97 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
98 300, nls_cp);
99 }
100 bcc_ptr += 2 * bytes_ret;
101 bcc_ptr += 2; /* account for null termination */
102 /* copy domain */
790fe579 103 if (ses->domainName == NULL) {
6e659c63
SF
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 */
106 *bcc_ptr = 0;
107 *(bcc_ptr+1) = 0;
108 bytes_ret = 0;
109 } else
3870253e 110 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
3979877e
SF
111 256, nls_cp);
112 bcc_ptr += 2 * bytes_ret;
113 bcc_ptr += 2; /* account for null terminator */
114
115 /* Copy OS version */
116 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
117 nls_cp);
118 bcc_ptr += 2 * bytes_ret;
96b644bd 119 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
3979877e
SF
120 32, nls_cp);
121 bcc_ptr += 2 * bytes_ret;
122 bcc_ptr += 2; /* trailing null */
123
124 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
790fe579 125 32, nls_cp);
3979877e
SF
126 bcc_ptr += 2 * bytes_ret;
127 bcc_ptr += 2; /* trailing null */
128
129 *pbcc_area = bcc_ptr;
130}
131
3870253e 132static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
790fe579 133 const struct nls_table *nls_cp)
3979877e 134{
790fe579 135 char *bcc_ptr = *pbcc_area;
3979877e
SF
136
137 /* copy user */
138 /* BB what about null user mounts - check that we do this BB */
790fe579
SF
139 /* copy user */
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);
144 }
3979877e 145 /* BB improve check for overflow */
790fe579 146 bcc_ptr += strnlen(ses->userName, 300);
3979877e 147 *bcc_ptr = 0;
790fe579 148 bcc_ptr++; /* account for null termination */
3979877e 149
790fe579
SF
150 /* copy domain */
151
152 if (ses->domainName != NULL) {
153 strncpy(bcc_ptr, ses->domainName, 256);
3979877e 154 bcc_ptr += strnlen(ses->domainName, 256);
790fe579 155 } /* else we will send a null domain name
6e659c63 156 so the server will default to its own domain */
3979877e
SF
157 *bcc_ptr = 0;
158 bcc_ptr++;
159
160 /* BB check for overflow here */
161
162 strcpy(bcc_ptr, "Linux version ");
163 bcc_ptr += strlen("Linux version ");
96b644bd
SH
164 strcpy(bcc_ptr, init_utsname()->release);
165 bcc_ptr += strlen(init_utsname()->release) + 1;
3979877e
SF
166
167 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
168 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
169
790fe579 170 *pbcc_area = bcc_ptr;
3979877e
SF
171}
172
790fe579
SF
173static int decode_unicode_ssetup(char **pbcc_area, int bleft,
174 struct cifsSesInfo *ses,
175 const struct nls_table *nls_cp)
3979877e
SF
176{
177 int rc = 0;
178 int words_left, len;
790fe579 179 char *data = *pbcc_area;
3979877e
SF
180
181
182
790fe579 183 cFYI(1, ("bleft %d", bleft));
3979877e
SF
184
185
8e6f195a
SF
186 /* SMB header is unaligned, so cifs servers word align start of
187 Unicode strings */
188 data++;
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
192 which follows it */
50c2f753 193
3979877e
SF
194 words_left = bleft / 2;
195
196 /* save off server operating system */
197 len = UniStrnlen((wchar_t *) data, words_left);
198
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 */
790fe579 202 if (len >= words_left)
3979877e
SF
203 return rc;
204
26f57364 205 kfree(ses->serverOS);
3979877e
SF
206 /* UTF-8 string will not grow more than four times as big as UCS-16 */
207 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
26f57364
SF
208 if (ses->serverOS != NULL)
209 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
3979877e
SF
210 data += 2 * (len + 1);
211 words_left -= len + 1;
212
213 /* save off server network operating system */
214 len = UniStrnlen((wchar_t *) data, words_left);
215
790fe579 216 if (len >= words_left)
3979877e
SF
217 return rc;
218
26f57364 219 kfree(ses->serverNOS);
3979877e 220 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
790fe579 221 if (ses->serverNOS != NULL) {
3979877e
SF
222 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
223 nls_cp);
790fe579
SF
224 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
225 cFYI(1, ("NT4 server"));
3979877e
SF
226 ses->flags |= CIFS_SES_NT4;
227 }
228 }
229 data += 2 * (len + 1);
230 words_left -= len + 1;
231
790fe579
SF
232 /* save off server domain */
233 len = UniStrnlen((wchar_t *) data, words_left);
234
235 if (len > words_left)
236 return rc;
237
26f57364 238 kfree(ses->serverDomain);
790fe579
SF
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,
242 nls_cp);
243 ses->serverDomain[2*len] = 0;
244 ses->serverDomain[(2*len) + 1] = 0;
245 }
246 data += 2 * (len + 1);
247 words_left -= len + 1;
248
249 cFYI(1, ("words left: %d", words_left));
3979877e
SF
250
251 return rc;
252}
253
790fe579
SF
254static int decode_ascii_ssetup(char **pbcc_area, int bleft,
255 struct cifsSesInfo *ses,
256 const struct nls_table *nls_cp)
3979877e
SF
257{
258 int rc = 0;
259 int len;
790fe579 260 char *bcc_ptr = *pbcc_area;
3979877e 261
790fe579 262 cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
50c2f753 263
3979877e 264 len = strnlen(bcc_ptr, bleft);
790fe579 265 if (len >= bleft)
3979877e 266 return rc;
50c2f753 267
26f57364 268 kfree(ses->serverOS);
3979877e
SF
269
270 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 271 if (ses->serverOS)
3979877e 272 strncpy(ses->serverOS, bcc_ptr, len);
790fe579
SF
273 if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
274 cFYI(1, ("OS/2 server"));
9ac00b7d
SF
275 ses->flags |= CIFS_SES_OS2;
276 }
3979877e
SF
277
278 bcc_ptr += len + 1;
279 bleft -= len + 1;
280
281 len = strnlen(bcc_ptr, bleft);
790fe579 282 if (len >= bleft)
3979877e
SF
283 return rc;
284
26f57364 285 kfree(ses->serverNOS);
3979877e
SF
286
287 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
790fe579 288 if (ses->serverNOS)
3979877e
SF
289 strncpy(ses->serverNOS, bcc_ptr, len);
290
291 bcc_ptr += len + 1;
292 bleft -= len + 1;
293
790fe579
SF
294 len = strnlen(bcc_ptr, bleft);
295 if (len > bleft)
296 return rc;
3979877e 297
9ac00b7d
SF
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 */
790fe579 303 cFYI(1, ("ascii: bytes left %d", bleft));
3979877e
SF
304
305 return rc;
306}
307
790fe579 308int
3979877e
SF
309CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
310 const struct nls_table *nls_cp)
311{
312 int rc = 0;
313 int wct;
3979877e
SF
314 struct smb_hdr *smb_buf;
315 char *bcc_ptr;
750d1151 316 char *str_area;
3979877e
SF
317 SESSION_SETUP_ANDX *pSMB;
318 __u32 capabilities;
319 int count;
320 int resp_buf_type = 0;
750d1151 321 struct kvec iov[2];
3979877e
SF
322 enum securityEnum type;
323 __u16 action;
324 int bytes_remaining;
254e55ed 325
790fe579 326 if (ses == NULL)
3979877e
SF
327 return -EINVAL;
328
329 type = ses->server->secType;
f40c5628 330
790fe579
SF
331 cFYI(1, ("sess setup type %d", type));
332 if (type == LANMAN) {
3979877e
SF
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 */
339 return -EOPNOTSUPP;
340#endif
341 wct = 10; /* lanman 2 style sessionsetup */
790fe579 342 } else if ((type == NTLM) || (type == NTLMv2)) {
9312f675 343 /* For NTLMv2 failures eventually may need to retry NTLM */
3979877e 344 wct = 13; /* old style NTLM sessionsetup */
790fe579 345 } else /* same size: negotiate or auth, NTLMSSP or extended security */
3979877e
SF
346 wct = 12;
347
348 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
349 (void **)&smb_buf);
790fe579 350 if (rc)
3979877e
SF
351 return rc;
352
353 pSMB = (SESSION_SETUP_ANDX *)smb_buf;
354
355 capabilities = cifs_ssetup_hdr(ses, pSMB);
750d1151
SF
356
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 */
790fe579
SF
362 iov[0].iov_base = (char *)pSMB;
363 iov[0].iov_len = smb_buf->smb_buf_length + 4;
750d1151
SF
364
365 /* 2000 big enough to fit max user, domain, NOS name etc. */
366 str_area = kmalloc(2000, GFP_KERNEL);
5e6e6232
CG
367 if (str_area == NULL) {
368 cifs_small_buf_release(smb_buf);
369 return -ENOMEM;
370 }
750d1151 371 bcc_ptr = str_area;
3979877e 372
9ac00b7d
SF
373 ses->flags &= ~CIFS_SES_LANMAN;
374
790fe579 375 if (type == LANMAN) {
3979877e 376#ifdef CONFIG_CIFS_WEAK_PW_HASH
7c7b25bc 377 char lnm_session_key[CIFS_SESS_KEY_SIZE];
3979877e
SF
378
379 /* no capabilities flags in old lanman negotiation */
380
790fe579 381 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e
SF
382 /* BB calculate hash with password */
383 /* and copy into bcc */
384
7c7b25bc 385 calc_lanman_hash(ses, lnm_session_key);
790fe579 386 ses->flags |= CIFS_SES_LANMAN;
750d1151 387/* #ifdef CONFIG_CIFS_DEBUG2
3979877e 388 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
7c7b25bc 389 CIFS_SESS_KEY_SIZE);
750d1151 390#endif */
7c7b25bc
SF
391 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
392 bcc_ptr += CIFS_SESS_KEY_SIZE;
3979877e
SF
393
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? */
398
790fe579 399 cFYI(1, ("Negotiating LANMAN setting up strings"));
3979877e
SF
400 /* Unicode not allowed for LANMAN dialects */
401 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
790fe579 402#endif
3979877e 403 } else if (type == NTLM) {
7c7b25bc 404 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3979877e
SF
405
406 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
407 pSMB->req_no_secext.CaseInsensitivePasswordLength =
7c7b25bc 408 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3979877e 409 pSMB->req_no_secext.CaseSensitivePasswordLength =
7c7b25bc 410 cpu_to_le16(CIFS_SESS_KEY_SIZE);
50c2f753 411
3979877e
SF
412 /* calculate session key */
413 SMBNTencrypt(ses->password, ses->server->cryptKey,
414 ntlm_session_key);
415
790fe579 416 if (first_time) /* should this be moved into common code
3979877e 417 with similar ntlmv2 path? */
b609f06a 418 cifs_calculate_mac_key(&ses->server->mac_signing_key,
3979877e
SF
419 ntlm_session_key, ses->password);
420 /* copy session key */
421
790fe579 422 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 423 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 424 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
7c7b25bc 425 bcc_ptr += CIFS_SESS_KEY_SIZE;
790fe579 426 if (ses->capabilities & CAP_UNICODE) {
0223cf0b
SF
427 /* unicode strings must be word aligned */
428 if (iov[0].iov_len % 2) {
429 *bcc_ptr = 0;
790fe579
SF
430 bcc_ptr++;
431 }
7c7b25bc 432 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 433 } else
7c7b25bc
SF
434 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
435 } else if (type == NTLMv2) {
790fe579 436 char *v2_sess_key =
6d027cfd 437 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
f64b23ae
SF
438
439 /* BB FIXME change all users of v2_sess_key to
440 struct ntlmv2_resp */
7c7b25bc 441
790fe579 442 if (v2_sess_key == NULL) {
7c7b25bc
SF
443 cifs_small_buf_release(smb_buf);
444 return -ENOMEM;
445 }
446
447 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
448
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); */
452
453 pSMB->req_no_secext.CaseSensitivePasswordLength =
f64b23ae 454 cpu_to_le16(sizeof(struct ntlmv2_resp));
7c7b25bc
SF
455
456 /* calculate session key */
1717ffc5 457 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
790fe579
SF
458 if (first_time) /* should this be moved into common code
459 with similar ntlmv2 path? */
7c7b25bc
SF
460 /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
461 response BB FIXME, v2_sess_key); */
462
463 /* copy session key */
464
465 /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
466 bcc_ptr += LM2_SESS_KEY_SIZE; */
3870253e
SF
467 memcpy(bcc_ptr, (char *)v2_sess_key,
468 sizeof(struct ntlmv2_resp));
f64b23ae
SF
469 bcc_ptr += sizeof(struct ntlmv2_resp);
470 kfree(v2_sess_key);
790fe579
SF
471 if (ses->capabilities & CAP_UNICODE) {
472 if (iov[0].iov_len % 2) {
0223cf0b 473 *bcc_ptr = 0;
26f57364
SF
474 bcc_ptr++;
475 }
3979877e 476 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
0223cf0b 477 } else
3979877e
SF
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 */
484 }
485
750d1151 486 count = (long) bcc_ptr - (long) str_area;
3979877e
SF
487 smb_buf->smb_buf_length += count;
488
3979877e
SF
489 BCC_LE(smb_buf) = cpu_to_le16(count);
490
750d1151 491 iov[1].iov_base = str_area;
790fe579 492 iov[1].iov_len = count;
750d1151 493 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
3979877e
SF
494 /* SMB request buf freed in SendReceive2 */
495
790fe579
SF
496 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
497 if (rc)
3979877e
SF
498 goto ssetup_exit;
499
500 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
501 smb_buf = (struct smb_hdr *)iov[0].iov_base;
502
790fe579 503 if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
3979877e 504 rc = -EIO;
790fe579 505 cERROR(1, ("bad word count %d", smb_buf->WordCount));
3979877e
SF
506 goto ssetup_exit;
507 }
508 action = le16_to_cpu(pSMB->resp.Action);
509 if (action & GUEST_LOGIN)
189acaae 510 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
3979877e
SF
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);
517
790fe579 518 if (smb_buf->WordCount == 4) {
3979877e
SF
519 __u16 blob_len;
520 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
521 bcc_ptr += blob_len;
790fe579
SF
522 if (blob_len > bytes_remaining) {
523 cERROR(1, ("bad security blob length %d", blob_len));
3979877e
SF
524 rc = -EINVAL;
525 goto ssetup_exit;
526 }
527 bytes_remaining -= blob_len;
790fe579 528 }
3979877e
SF
529
530 /* BB check if Unicode and decode strings */
790fe579 531 if (smb_buf->Flags2 & SMBFLG2_UNICODE)
3979877e
SF
532 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
533 ses, nls_cp);
534 else
63135e08
SF
535 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
536 ses, nls_cp);
50c2f753 537
3979877e 538ssetup_exit:
750d1151 539 kfree(str_area);
790fe579
SF
540 if (resp_buf_type == CIFS_SMALL_BUFFER) {
541 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
3979877e 542 cifs_small_buf_release(iov[0].iov_base);
790fe579 543 } else if (resp_buf_type == CIFS_LARGE_BUFFER)
3979877e
SF
544 cifs_buf_release(iov[0].iov_base);
545
546 return rc;
547}