diff options
author | Steve French <sfrench@us.ibm.com> | 2006-06-27 02:28:30 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-06-27 02:28:30 -0400 |
commit | 750d1151a6c95ef9b9a188bb7cff6b80ee30da17 (patch) | |
tree | 1a69d1e42ffebefa13842372c97d505e37159f7e /fs/cifs/sess.c | |
parent | 124a27fe32398a69d16bae374aeb17ad67a0ebbf (diff) |
[CIFS] Fix allocation of buffers for new session setup routine to allow
longer user and domain names and allow passing sec options on mount
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r-- | fs/cifs/sess.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 70e32a81c213..7737edd1baf1 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -138,7 +138,7 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
138 | strncpy(bcc_ptr, ses->userName, 300); | 138 | strncpy(bcc_ptr, ses->userName, 300); |
139 | } | 139 | } |
140 | /* BB improve check for overflow */ | 140 | /* BB improve check for overflow */ |
141 | bcc_ptr += strnlen(ses->userName, 200); | 141 | bcc_ptr += strnlen(ses->userName, 300); |
142 | *bcc_ptr = 0; | 142 | *bcc_ptr = 0; |
143 | bcc_ptr++; /* account for null termination */ | 143 | bcc_ptr++; /* account for null termination */ |
144 | 144 | ||
@@ -313,11 +313,12 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
313 | int wct; | 313 | int wct; |
314 | struct smb_hdr *smb_buf; | 314 | struct smb_hdr *smb_buf; |
315 | char *bcc_ptr; | 315 | char *bcc_ptr; |
316 | char *str_area; | ||
316 | SESSION_SETUP_ANDX *pSMB; | 317 | SESSION_SETUP_ANDX *pSMB; |
317 | __u32 capabilities; | 318 | __u32 capabilities; |
318 | int count; | 319 | int count; |
319 | int resp_buf_type = 0; | 320 | int resp_buf_type = 0; |
320 | struct kvec iov[2]; /* BB split variable length info into 2nd iovec */ | 321 | struct kvec iov[2]; |
321 | enum securityEnum type; | 322 | enum securityEnum type; |
322 | __u16 action; | 323 | __u16 action; |
323 | int bytes_remaining; | 324 | int bytes_remaining; |
@@ -351,7 +352,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
351 | pSMB = (SESSION_SETUP_ANDX *)smb_buf; | 352 | pSMB = (SESSION_SETUP_ANDX *)smb_buf; |
352 | 353 | ||
353 | capabilities = cifs_ssetup_hdr(ses, pSMB); | 354 | capabilities = cifs_ssetup_hdr(ses, pSMB); |
354 | bcc_ptr = pByteArea(smb_buf); | 355 | |
356 | /* we will send the SMB in two pieces, | ||
357 | a fixed length beginning part, and a | ||
358 | second part which will include the strings | ||
359 | and rest of bcc area, in order to avoid having | ||
360 | to do a large buffer 17K allocation */ | ||
361 | iov[0].iov_base = (char *)pSMB; | ||
362 | iov[0].iov_len = smb_buf->smb_buf_length + 4; | ||
363 | |||
364 | /* 2000 big enough to fit max user, domain, NOS name etc. */ | ||
365 | str_area = kmalloc(2000, GFP_KERNEL); | ||
366 | bcc_ptr = str_area; | ||
355 | 367 | ||
356 | if(type == LANMAN) { | 368 | if(type == LANMAN) { |
357 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 369 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
@@ -365,10 +377,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
365 | 377 | ||
366 | calc_lanman_hash(ses, lnm_session_key); | 378 | calc_lanman_hash(ses, lnm_session_key); |
367 | 379 | ||
368 | #ifdef CONFIG_CIFS_DEBUG2 | 380 | /* #ifdef CONFIG_CIFS_DEBUG2 |
369 | cifs_dump_mem("cryptkey: ",ses->server->cryptKey, | 381 | cifs_dump_mem("cryptkey: ",ses->server->cryptKey, |
370 | CIFS_SESS_KEY_SIZE); | 382 | CIFS_SESS_KEY_SIZE); |
371 | #endif | 383 | #endif */ |
372 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); | 384 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); |
373 | bcc_ptr += CIFS_SESS_KEY_SIZE; | 385 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
374 | 386 | ||
@@ -377,7 +389,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
377 | changed to do higher than lanman dialect and | 389 | changed to do higher than lanman dialect and |
378 | we reconnected would we ever calc signing_key? */ | 390 | we reconnected would we ever calc signing_key? */ |
379 | 391 | ||
380 | cERROR(1,("Negotiating LANMAN setting up strings")); | 392 | cFYI(1,("Negotiating LANMAN setting up strings")); |
381 | /* Unicode not allowed for LANMAN dialects */ | 393 | /* Unicode not allowed for LANMAN dialects */ |
382 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 394 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
383 | #endif | 395 | #endif |
@@ -396,7 +408,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
396 | 408 | ||
397 | if(first_time) /* should this be moved into common code | 409 | if(first_time) /* should this be moved into common code |
398 | with similar ntlmv2 path? */ | 410 | with similar ntlmv2 path? */ |
399 | cifs_calculate_mac_key( ses->server->mac_signing_key, | 411 | cifs_calculate_mac_key(ses->server->mac_signing_key, |
400 | ntlm_session_key, ses->password); | 412 | ntlm_session_key, ses->password); |
401 | /* copy session key */ | 413 | /* copy session key */ |
402 | 414 | ||
@@ -454,23 +466,14 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
454 | /* BB set password lengths */ | 466 | /* BB set password lengths */ |
455 | } | 467 | } |
456 | 468 | ||
457 | count = (long) bcc_ptr - (long) pByteArea(smb_buf); | 469 | count = (long) bcc_ptr - (long) str_area; |
458 | smb_buf->smb_buf_length += count; | 470 | smb_buf->smb_buf_length += count; |
459 | 471 | ||
460 | /* if we switch to small buffers, count will need to be fewer | ||
461 | than 383 (strings less than 335 bytes) */ | ||
462 | |||
463 | BCC_LE(smb_buf) = cpu_to_le16(count); | 472 | BCC_LE(smb_buf) = cpu_to_le16(count); |
464 | 473 | ||
465 | 474 | iov[1].iov_base = str_area; | |
466 | /* BB FIXME check for other non ntlm code paths */ | 475 | iov[1].iov_len = count; |
467 | 476 | rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); | |
468 | /* BB check is this too big for a small smb? */ | ||
469 | |||
470 | iov[0].iov_base = (char *)pSMB; | ||
471 | iov[0].iov_len = smb_buf->smb_buf_length + 4; | ||
472 | |||
473 | rc = SendReceive2(xid, ses, iov, 1 /* num_iovecs */, &resp_buf_type, 0); | ||
474 | /* SMB request buf freed in SendReceive2 */ | 477 | /* SMB request buf freed in SendReceive2 */ |
475 | 478 | ||
476 | cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); | 479 | cFYI(1,("ssetup rc from sendrecv2 is %d",rc)); |
@@ -515,6 +518,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
515 | rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp); | 518 | rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp); |
516 | 519 | ||
517 | ssetup_exit: | 520 | ssetup_exit: |
521 | kfree(str_area); | ||
518 | if(resp_buf_type == CIFS_SMALL_BUFFER) { | 522 | if(resp_buf_type == CIFS_SMALL_BUFFER) { |
519 | cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base)); | 523 | cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base)); |
520 | cifs_small_buf_release(iov[0].iov_base); | 524 | cifs_small_buf_release(iov[0].iov_base); |