X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=fs%2Fcifs%2Fmisc.c;h=432ba15e2c2dc2b07b31ca26ffeca869f6a3b5c8;hb=36177ba655c238e33400cc2837a28720b62784bd;hp=34a06692e4fa9461e624e8ace35de0536d4240d9;hpb=3b621ee5df437d3f332a635ab6421aaa61a7dc2b;p=powerpc.git diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 34a06692e4..432ba15e2c 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -1,7 +1,7 @@ /* * fs/cifs/misc.c * - * Copyright (C) International Business Machines Corp., 2002,2004 + * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -161,6 +161,9 @@ cifs_buf_get(void) if (ret_buf) { memset(ret_buf, 0, sizeof(struct smb_hdr) + 3); atomic_inc(&bufAllocCount); +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&totBufAllocCount); +#endif /* CONFIG_CIFS_STATS2 */ } return ret_buf; @@ -195,6 +198,10 @@ cifs_small_buf_get(void) /* No need to clear memory here, cleared in header assemble */ /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ atomic_inc(&smBufAllocCount); +#ifdef CONFIG_CIFS_STATS2 + atomic_inc(&totSmBufAllocCount); +#endif /* CONFIG_CIFS_STATS2 */ + } return ret_buf; } @@ -292,7 +299,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , struct cifsSesInfo * ses; char *temp = (char *) buffer; - memset(temp,0,MAX_CIFS_HDR_SIZE); + memset(temp,0,256); /* bigger than MAX_CIFS_HDR_SIZE */ buffer->smb_buf_length = (2 * word_count) + sizeof (struct smb_hdr) - @@ -348,12 +355,12 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , /* BB Add support for establishing new tCon and SMB Session */ /* with userid/password pairs found on the smb session */ /* for other target tcp/ip addresses BB */ - if(current->uid != treeCon->ses->linux_uid) { - cFYI(1,("Multiuser mode and UID did not match tcon uid ")); + if(current->fsuid != treeCon->ses->linux_uid) { + cFYI(1,("Multiuser mode and UID did not match tcon uid")); read_lock(&GlobalSMBSeslock); list_for_each(temp_item, &GlobalSMBSessionList) { ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList); - if(ses->linux_uid == current->uid) { + if(ses->linux_uid == current->fsuid) { if(ses->server == treeCon->ses->server) { cFYI(1,("found matching uid substitute right smb_uid")); buffer->Uid = ses->Suid; @@ -397,12 +404,12 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) if(smb->Command == SMB_COM_LOCKING_ANDX) return 0; else - cERROR(1, ("Rcvd Request not response ")); + cERROR(1, ("Rcvd Request not response")); } } else { /* bad signature or mid */ if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) cERROR(1, - ("Bad protocol string signature header %x ", + ("Bad protocol string signature header %x", *(unsigned int *) smb->Protocol)); if (mid != smb->Mid) cERROR(1, ("Mids do not match")); @@ -417,7 +424,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) __u32 len = smb->smb_buf_length; __u32 clc_len; /* calculated length */ cFYI(0, - ("Entering checkSMB with Length: %x, smb_buf_length: %x ", + ("Entering checkSMB with Length: %x, smb_buf_length: %x", length, len)); if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { @@ -451,9 +458,16 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); /* Windows XP can return a few bytes too much, presumably an illegal pad, at the end of byte range lock responses - so we allow for up to eight byte pad, as long as actual + so we allow for that three byte pad, as long as actual received length is as long or longer than calculated length */ - if((4+len > clc_len) && (len <= clc_len + 3)) + /* We have now had to extend this more, since there is a + case in which it needs to be bigger still to handle a + malformed response to transact2 findfirst from WinXP when + access denied is returned and thus bcc and wct are zero + but server says length is 0x21 bytes too long as if the server + forget to reset the smb rfc1001 length when it reset the + wct and bcc to minimum size and drop the t2 parms and data */ + if((4+len > clc_len) && (len <= clc_len + 512)) return 0; else return 1; @@ -461,7 +475,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) return 0; } int -is_valid_oplock_break(struct smb_hdr *buf) +is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) { struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; struct list_head *tmp; @@ -521,7 +535,7 @@ is_valid_oplock_break(struct smb_hdr *buf) read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if (tcon->tid == buf->Tid) { + if ((tcon->tid == buf->Tid) && (srv == tcon->ses->server)) { cifs_stats_inc(&tcon->num_oplock_brks); list_for_each(tmp1,&tcon->openFileList){ netfile = list_entry(tmp1,struct cifsFileInfo, @@ -678,7 +692,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen, __u16 temp; if(!mapChars) - return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp); + return cifs_strtoUCS(target, source, PATH_MAX, cp); for(i = 0, j = 0; i < maxlen; j++) { src_char = source[i];