aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/misc.c')
-rw-r--r--fs/cifs/misc.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 34a06692e4f..812c6bb0fe3 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/misc.c 2 * fs/cifs/misc.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2004 4 * Copyright (C) International Business Machines Corp., 2002,2005
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -161,6 +161,9 @@ cifs_buf_get(void)
161 if (ret_buf) { 161 if (ret_buf) {
162 memset(ret_buf, 0, sizeof(struct smb_hdr) + 3); 162 memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
163 atomic_inc(&bufAllocCount); 163 atomic_inc(&bufAllocCount);
164#ifdef CONFIG_CIFS_STATS2
165 atomic_inc(&totBufAllocCount);
166#endif /* CONFIG_CIFS_STATS2 */
164 } 167 }
165 168
166 return ret_buf; 169 return ret_buf;
@@ -195,6 +198,10 @@ cifs_small_buf_get(void)
195 /* No need to clear memory here, cleared in header assemble */ 198 /* No need to clear memory here, cleared in header assemble */
196 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ 199 /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
197 atomic_inc(&smBufAllocCount); 200 atomic_inc(&smBufAllocCount);
201#ifdef CONFIG_CIFS_STATS2
202 atomic_inc(&totSmBufAllocCount);
203#endif /* CONFIG_CIFS_STATS2 */
204
198 } 205 }
199 return ret_buf; 206 return ret_buf;
200} 207}
@@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
292 struct cifsSesInfo * ses; 299 struct cifsSesInfo * ses;
293 char *temp = (char *) buffer; 300 char *temp = (char *) buffer;
294 301
295 memset(temp,0,MAX_CIFS_HDR_SIZE); 302 memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */
296 303
297 buffer->smb_buf_length = 304 buffer->smb_buf_length =
298 (2 * word_count) + sizeof (struct smb_hdr) - 305 (2 * word_count) + sizeof (struct smb_hdr) -
@@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
348 /* BB Add support for establishing new tCon and SMB Session */ 355 /* BB Add support for establishing new tCon and SMB Session */
349 /* with userid/password pairs found on the smb session */ 356 /* with userid/password pairs found on the smb session */
350 /* for other target tcp/ip addresses BB */ 357 /* for other target tcp/ip addresses BB */
351 if(current->uid != treeCon->ses->linux_uid) { 358 if(current->fsuid != treeCon->ses->linux_uid) {
352 cFYI(1,("Multiuser mode and UID did not match tcon uid ")); 359 cFYI(1,("Multiuser mode and UID did not match tcon uid"));
353 read_lock(&GlobalSMBSeslock); 360 read_lock(&GlobalSMBSeslock);
354 list_for_each(temp_item, &GlobalSMBSessionList) { 361 list_for_each(temp_item, &GlobalSMBSessionList) {
355 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); 362 ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
356 if(ses->linux_uid == current->uid) { 363 if(ses->linux_uid == current->fsuid) {
357 if(ses->server == treeCon->ses->server) { 364 if(ses->server == treeCon->ses->server) {
358 cFYI(1,("found matching uid substitute right smb_uid")); 365 cFYI(1,("found matching uid substitute right smb_uid"));
359 buffer->Uid = ses->Suid; 366 buffer->Uid = ses->Suid;
@@ -397,12 +404,12 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
397 if(smb->Command == SMB_COM_LOCKING_ANDX) 404 if(smb->Command == SMB_COM_LOCKING_ANDX)
398 return 0; 405 return 0;
399 else 406 else
400 cERROR(1, ("Rcvd Request not response ")); 407 cERROR(1, ("Rcvd Request not response"));
401 } 408 }
402 } else { /* bad signature or mid */ 409 } else { /* bad signature or mid */
403 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) 410 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
404 cERROR(1, 411 cERROR(1,
405 ("Bad protocol string signature header %x ", 412 ("Bad protocol string signature header %x",
406 *(unsigned int *) smb->Protocol)); 413 *(unsigned int *) smb->Protocol));
407 if (mid != smb->Mid) 414 if (mid != smb->Mid)
408 cERROR(1, ("Mids do not match")); 415 cERROR(1, ("Mids do not match"));
@@ -417,7 +424,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
417 __u32 len = smb->smb_buf_length; 424 __u32 len = smb->smb_buf_length;
418 __u32 clc_len; /* calculated length */ 425 __u32 clc_len; /* calculated length */
419 cFYI(0, 426 cFYI(0,
420 ("Entering checkSMB with Length: %x, smb_buf_length: %x ", 427 ("Entering checkSMB with Length: %x, smb_buf_length: %x",
421 length, len)); 428 length, len));
422 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 429 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
423 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 430 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
@@ -451,9 +458,16 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
451 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); 458 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
452 /* Windows XP can return a few bytes too much, presumably 459 /* Windows XP can return a few bytes too much, presumably
453 an illegal pad, at the end of byte range lock responses 460 an illegal pad, at the end of byte range lock responses
454 so we allow for up to eight byte pad, as long as actual 461 so we allow for that three byte pad, as long as actual
455 received length is as long or longer than calculated length */ 462 received length is as long or longer than calculated length */
456 if((4+len > clc_len) && (len <= clc_len + 3)) 463 /* We have now had to extend this more, since there is a
464 case in which it needs to be bigger still to handle a
465 malformed response to transact2 findfirst from WinXP when
466 access denied is returned and thus bcc and wct are zero
467 but server says length is 0x21 bytes too long as if the server
468 forget to reset the smb rfc1001 length when it reset the
469 wct and bcc to minimum size and drop the t2 parms and data */
470 if((4+len > clc_len) && (len <= clc_len + 512))
457 return 0; 471 return 0;
458 else 472 else
459 return 1; 473 return 1;
@@ -678,7 +692,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
678 __u16 temp; 692 __u16 temp;
679 693
680 if(!mapChars) 694 if(!mapChars)
681 return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); 695 return cifs_strtoUCS(target, source, PATH_MAX, cp);
682 696
683 for(i = 0, j = 0; i < maxlen; j++) { 697 for(i = 0, j = 0; i < maxlen; j++) {
684 src_char = source[i]; 698 src_char = source[i];