#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/vfs.h>
-#include <linux/posix_acl_xattr.h>
#include <asm/uaccess.h>
#include "cifspdu.h"
#include "cifsglob.h"
/* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */
}
-static int
-small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
- void **request_buf /* returned */)
-{
- int rc = 0;
-
- /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
- check for tcp and smb session status done differently
- for those three - in the calling routine */
- if(tcon) {
- if((tcon->ses) && (tcon->ses->server)){
- struct nls_table *nls_codepage;
- /* Give Demultiplex thread up to 10 seconds to
- reconnect, should be greater than cifs socket
- timeout which is 7 seconds */
- while(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
- wait_event_interruptible_timeout(tcon->ses->server->response_q,
- (tcon->ses->server->tcpStatus == CifsGood), 10 * HZ);
- if(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
- /* on "soft" mounts we wait once */
- if((tcon->retry == FALSE) ||
- (tcon->ses->status == CifsExiting)) {
- cFYI(1,("gave up waiting on reconnect in smb_init"));
- return -EHOSTDOWN;
- } /* else "hard" mount - keep retrying until
- process is killed or server comes back up */
- } else /* TCP session is reestablished now */
- break;
-
- }
-
- nls_codepage = load_nls_default();
- /* need to prevent multiple threads trying to
- simultaneously reconnect the same SMB session */
- down(&tcon->ses->sesSem);
- if(tcon->ses->status == CifsNeedReconnect)
- rc = cifs_setup_session(0, tcon->ses, nls_codepage);
- if(!rc && (tcon->tidStatus == CifsNeedReconnect)) {
- mark_open_files_invalid(tcon);
- rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon,
- nls_codepage);
- up(&tcon->ses->sesSem);
- if(rc == 0)
- atomic_inc(&tconInfoReconnectCount);
-
- cFYI(1, ("reconnect tcon rc = %d", rc));
- /* Removed call to reopen open files here -
- it is safer (and faster) to reopen files
- one at a time as needed in read and write */
-
- /* Check if handle based operation so we
- know whether we can continue or not without
- returning to caller to reset file handle */
- switch(smb_command) {
- case SMB_COM_READ_ANDX:
- case SMB_COM_WRITE_ANDX:
- case SMB_COM_CLOSE:
- case SMB_COM_FIND_CLOSE2:
- case SMB_COM_LOCKING_ANDX: {
- unload_nls(nls_codepage);
- return -EAGAIN;
- }
- }
- } else {
- up(&tcon->ses->sesSem);
- }
- unload_nls(nls_codepage);
-
- } else {
- return -EIO;
- }
- }
- if(rc)
- return rc;
-
- *request_buf = cifs_small_buf_get();
- if (*request_buf == 0) {
- /* BB should we add a retry in here if not a writepage? */
- return -ENOMEM;
- }
-
- header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,wct);
-
-#ifdef CONFIG_CIFS_STATS
- if(tcon != NULL) {
- atomic_inc(&tcon->num_smbs_sent);
- }
-#endif /* CONFIG_CIFS_STATS */
- return rc;
-}
-
static int
smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
void **request_buf /* returned */ ,
if(tcon != NULL) {
atomic_inc(&tcon->num_smbs_sent);
}
-#endif /* CONFIG_CIFS_STATS */
+#endif
return rc;
}
-static int validate_t2(struct smb_t2_rsp * pSMB)
-{
- int rc = -EINVAL;
- int total_size;
- char * pBCC;
-
- /* check for plausible wct, bcc and t2 data and parm sizes */
- /* check for parm and data offset going beyond end of smb */
- if(pSMB->hdr.WordCount >= 10) {
- if((le16_to_cpu(pSMB->t2_rsp.ParameterOffset) <= 1024) &&
- (le16_to_cpu(pSMB->t2_rsp.DataOffset) <= 1024)) {
- /* check that bcc is at least as big as parms + data */
- /* check that bcc is less than negotiated smb buffer */
- total_size = le16_to_cpu(pSMB->t2_rsp.ParameterCount);
- if(total_size < 512) {
- total_size+=le16_to_cpu(pSMB->t2_rsp.DataCount);
- /* BCC le converted in SendReceive */
- pBCC = (pSMB->hdr.WordCount * 2) + sizeof(struct smb_hdr) +
- (char *)pSMB;
- if((total_size <= (*(u16 *)pBCC)) &&
- (total_size <
- CIFSMaxBufSize+MAX_CIFS_HDR_SIZE)) {
- return 0;
- }
-
- }
- }
- }
- cifs_dump_mem("Invalid transact2 SMB: ",(char *)pSMB,
- sizeof(struct smb_t2_rsp) + 16);
- return rc;
-}
int
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
{
/* probably no need to store and check maxvcs */
server->maxBuf =
min(le32_to_cpu(pSMBr->MaxBufferSize),
- (__u32) CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
+ (__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE);
server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
cFYI(0, ("Max buf = %d ", ses->server->maxBuf));
GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
SecurityBlob,
count - 16,
&server->secType);
- if(rc == 1) {
- /* BB Need to fill struct for sessetup here */
- rc = -EOPNOTSUPP;
- } else {
- rc = -EINVAL;
- }
}
} else
server->capabilities &= ~CAP_EXTENDED_SECURITY;
CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
{
struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response; /* BB removeme BB */
+ struct smb_hdr *smb_buffer_response;
int rc = 0;
int length;
up(&tcon->tconSem);
return -EIO;
}
- rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **)&smb_buffer);
+
+ rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
+ (void **) &smb_buffer, (void **) &smb_buffer_response);
if (rc) {
up(&tcon->tconSem);
return rc;
- } else {
- smb_buffer_response = smb_buffer; /* BB removeme BB */
- }
+ }
rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
&length, 0);
if (rc)
cFYI(1, (" Tree disconnect failed %d", rc));
if (smb_buffer)
- cifs_small_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
up(&tcon->tconSem);
/* No need to return error on this operation if tid invalidated and
up(&ses->sesSem);
return -EBUSY;
}
- rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
- smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */
+
+ rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL /* no tcon anymore */,
+ (void **) &pSMB, (void **) &smb_buffer_response);
if(ses->server) {
if(ses->server->secMode &
}
}
if (pSMB)
- cifs_small_buf_release(pSMB);
+ cifs_buf_release(pSMB);
up(&ses->sesSem);
/* if session dead then we do not need to do ulogoff,
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->fileName, fileName, name_len);
}
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, PATH_MAX
+ name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(dirName, PATH_MAX);
+ name_len = strnlen(dirName, 530);
name_len++; /* trailing null */
strncpy(pSMB->DirName, dirName, name_len);
}
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, PATH_MAX
+ name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(name, PATH_MAX);
+ name_len = strnlen(name, 530);
name_len++; /* trailing null */
strncpy(pSMB->DirName, name, name_len);
}
count = 1; /* account for one byte pad to word boundary */
name_len =
cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1),
- fileName, PATH_MAX
+ fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
pSMB->NameLength = cpu_to_le16(name_len);
} else { /* BB improve the check for buffer overruns BB */
count = 0; /* no pad */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
pSMB->NameLength = cpu_to_le16(name_len);
strncpy(pSMB->fileName, fileName, name_len);
__u16 data_length = le16_to_cpu(pSMBr->DataLength);
*nbytes = data_length;
/*check that DataLength would not go beyond end of SMB */
- if ((data_length > CIFSMaxBufSize)
+ if ((data_length > CIFS_MAX_MSGSIZE)
|| (data_length > count)) {
cFYI(1,("bad length %d for count %d",data_length,count));
rc = -EIO;
CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, const char *buf,
- const char __user * ubuf, const int long_op)
+ const int long_op)
{
int rc = -EACCES;
WRITE_REQ *pSMB = NULL;
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
- pSMB->Reserved = 0xFFFFFFFF;
- pSMB->WriteMode = 0;
pSMB->Remaining = 0;
- /* BB can relax this if buffer is big enough in some cases - ie we can
- send more if LARGE_WRITE_X capability returned by the server and if
- our buffer is big enough or if we convert to iovecs on socket writes
- and eliminate the copy to the CIFS buffer */
bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
if (bytes_sent > count)
bytes_sent = count;
pSMB->DataLengthHigh = 0;
pSMB->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
- if(buf)
- memcpy(pSMB->Data,buf,bytes_sent);
- else if(ubuf)
- copy_from_user(pSMB->Data,ubuf,bytes_sent);
- else {
- /* No buffer */
- if(pSMB)
- cifs_buf_release(pSMB);
- return -EINVAL;
- }
+
+ memcpy(pSMB->Data,buf,bytes_sent);
byte_count = bytes_sent + 1 /* pad */ ;
pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
return rc;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
- const int netfid, const unsigned int count,
- const __u64 offset, unsigned int *nbytes, const char __user *buf,
- const int long_op)
-{
- int rc = -EACCES;
- WRITE_REQ *pSMB = NULL;
- WRITE_RSP *pSMBr = NULL;
- /*int bytes_returned;*/
- unsigned bytes_sent;
- __u16 byte_count;
-
- rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB);
- pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */
-
- if (rc)
- return rc;
- /* tcon and ses pointer are checked in smb_init */
- if (tcon->ses->server == NULL)
- return -ECONNABORTED;
-
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = netfid;
- pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
- pSMB->Reserved = 0xFFFFFFFF;
- pSMB->WriteMode = 0;
- pSMB->Remaining = 0;
- bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;
- if (bytes_sent > count)
- bytes_sent = count;
- pSMB->DataLengthHigh = 0;
- pSMB->DataOffset =
- cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
-
- byte_count = bytes_sent + 1 /* pad */ ;
- pSMB->DataLengthLow = cpu_to_le16(bytes_sent);
- pSMB->DataLengthHigh = 0;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
-/* rc = SendReceive2(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, buf, buflen, &bytes_returned, long_op); */ /* BB fixme BB */
- if (rc) {
- cFYI(1, ("Send error in write2 (large write) = %d", rc));
- *nbytes = 0;
- } else
- *nbytes = le16_to_cpu(pSMBr->Count);
-
- if (pSMB)
- cifs_small_buf_release(pSMB);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-#endif /* CIFS_EXPERIMENTAL */
-
int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u64 len,
cFYI(1, ("In CIFSSMBClose"));
/* do not retry on dead session on close */
- rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
- pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
+ rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
if(rc == -EAGAIN)
return 0;
if (rc)
cERROR(1, ("Send error in Close = %d", rc));
}
}
-
if (pSMB)
- cifs_small_buf_release(pSMB);
+ cifs_buf_release(pSMB);
/* Since session is dead, file will be closed on server already */
if(rc == -EAGAIN)
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
pSMB->OldFileName[name_len + 1] = 0x00;
name_len2 =
cifs_strtoUCS((wchar_t *) & pSMB->
- OldFileName[name_len + 2], toName, PATH_MAX,
+ OldFileName[name_len + 2], toName, 530,
nls_codepage);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
+ name_len = strnlen(fromName, 530);
name_len++; /* trailing null */
strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
+ name_len2 = strnlen(toName, 530);
name_len2++; /* trailing null */
pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage);
} else {
- len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, PATH_MAX, nls_codepage);
+ len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, 530, nls_codepage);
}
rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName,
fromName,
- PATH_MAX /* find define for this maxpathcomponent */,
+ 530 /* find define for this maxpathcomponent */,
nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
/* protocol requires ASCII signature byte on Unicode string */
pSMB->OldFileName[name_len + 1] = 0x00;
name_len2 = cifs_strtoUCS((wchar_t *) & pSMB->
- OldFileName[name_len + 2], toName, PATH_MAX,
+ OldFileName[name_len + 2], toName, 530,
nls_codepage);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
+ name_len = strnlen(fromName, 530);
name_len++; /* trailing null */
strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
+ name_len2 = strnlen(toName, 530);
name_len2++; /* trailing null */
pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
+ name_len = strnlen(fromName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fromName, name_len);
}
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len_target =
- cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) data_offset, toName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len_target++; /* trailing null */
name_len_target *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len_target = strnlen(toName, PATH_MAX);
+ name_len_target = strnlen(toName, 530);
name_len_target++; /* trailing null */
strncpy(data_offset, toName, name_len_target);
}
return rc;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, PATH_MAX
+ name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(toName, PATH_MAX);
+ name_len = strnlen(toName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, toName, name_len);
}
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len_target =
- cifs_strtoUCS((wchar_t *) data_offset, fromName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) data_offset, fromName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len_target++; /* trailing null */
name_len_target *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len_target = strnlen(fromName, PATH_MAX);
+ name_len_target = strnlen(fromName, 530);
name_len_target++; /* trailing null */
strncpy(data_offset, fromName, name_len_target);
}
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
pSMB->OldFileName[name_len + 1] = 0x04;
name_len2 =
cifs_strtoUCS((wchar_t *) & pSMB->
- OldFileName[name_len + 2], toName, PATH_MAX,
+ OldFileName[name_len + 2], toName, 530,
nls_codepage);
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
+ name_len = strnlen(fromName, 530);
name_len++; /* trailing null */
strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
+ name_len2 = strnlen(toName, 530);
name_len2++; /* trailing null */
pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc));
- } else {
- /* decode response */
-
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || (pSMBr->ByteCount < 2))
+ } else { /* decode response */
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ __u16 count = le16_to_cpu(pSMBr->DataCount);
+ if ((pSMBr->ByteCount < 2) || (data_offset > 512))
/* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */
else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
-
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len = UniStrnlen((wchar_t *) ((char *)
&pSMBr->hdr.Protocol +data_offset),
return rc;
}
-#ifdef CONFIG_CIFS_POSIX
-
-/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
-static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace)
-{
- /* u8 cifs fields do not need le conversion */
- ace->e_perm = (__u16)cifs_ace->cifs_e_perm;
- ace->e_tag = (__u16)cifs_ace->cifs_e_tag;
- ace->e_id = (__u32)le64_to_cpu(cifs_ace->cifs_uid);
- /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
-
- return;
-}
-
-/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
-static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,const int acl_type,const int size_of_data_area)
-{
- int size = 0;
- int i;
- __u16 count;
- struct cifs_posix_ace * pACE;
- struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)src;
- posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)trgt;
-
- if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
- return -EOPNOTSUPP;
-
- if(acl_type & ACL_TYPE_ACCESS) {
- count = le16_to_cpu(cifs_acl->access_entry_count);
- pACE = &cifs_acl->ace_array[0];
- size = sizeof(struct cifs_posix_acl);
- size += sizeof(struct cifs_posix_ace) * count;
- /* check if we would go beyond end of SMB */
- if(size_of_data_area < size) {
- cFYI(1,("bad CIFS POSIX ACL size %d vs. %d",size_of_data_area,size));
- return -EINVAL;
- }
- } else if(acl_type & ACL_TYPE_DEFAULT) {
- count = le16_to_cpu(cifs_acl->access_entry_count);
- size = sizeof(struct cifs_posix_acl);
- size += sizeof(struct cifs_posix_ace) * count;
-/* skip past access ACEs to get to default ACEs */
- pACE = &cifs_acl->ace_array[count];
- count = le16_to_cpu(cifs_acl->default_entry_count);
- size += sizeof(struct cifs_posix_ace) * count;
- /* check if we would go beyond end of SMB */
- if(size_of_data_area < size)
- return -EINVAL;
- } else {
- /* illegal type */
- return -EINVAL;
- }
-
- size = posix_acl_xattr_size(count);
- if((buflen == 0) || (local_acl == NULL)) {
- /* used to query ACL EA size */
- } else if(size > buflen) {
- return -ERANGE;
- } else /* buffer big enough */ {
- local_acl->a_version = POSIX_ACL_XATTR_VERSION;
- for(i = 0;i < count ;i++) {
- cifs_convert_ace(&local_acl->a_entries[i],pACE);
- pACE ++;
- }
- }
- return size;
-}
-
-__u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
- const posix_acl_xattr_entry * local_ace)
-{
- __u16 rc = 0; /* 0 = ACL converted ok */
-
- cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm);
- cifs_ace->cifs_e_tag = (__u8)cpu_to_le16(local_ace->e_tag);
- /* BB is there a better way to handle the large uid? */
- if(local_ace->e_id == -1) {
- /* Probably no need to le convert -1 on any arch but can not hurt */
- cifs_ace->cifs_uid = cpu_to_le64(-1);
- } else
- cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id);
- /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
- return rc;
-}
-
-/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
-__u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen,
- const int acl_type)
-{
- __u16 rc = 0;
- struct cifs_posix_acl * cifs_acl = (struct cifs_posix_acl *)parm_data;
- posix_acl_xattr_header * local_acl = (posix_acl_xattr_header *)pACL;
- int count;
- int i;
-
- if((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
- return 0;
-
- count = posix_acl_xattr_count((size_t)buflen);
- cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
- count,buflen,local_acl->a_version));
- if(local_acl->a_version != 2) {
- cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version));
- return 0;
- }
- cifs_acl->version = cpu_to_le16(1);
- if(acl_type == ACL_TYPE_ACCESS)
- cifs_acl->access_entry_count = count;
- else if(acl_type == ACL_TYPE_DEFAULT)
- cifs_acl->default_entry_count = count;
- else {
- cFYI(1,("unknown ACL type %d",acl_type));
- return 0;
- }
- for(i=0;i<count;i++) {
- rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
- &local_acl->a_entries[i]);
- if(rc != 0) {
- /* ACE not converted */
- break;
- }
- }
- if(rc == 0) {
- rc = (__u16)(count * sizeof(struct cifs_posix_ace));
- rc += sizeof(struct cifs_posix_acl);
- /* BB add check to make sure ACL does not overflow SMB */
- }
- return rc;
-}
-
-int
-CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
- const unsigned char *searchName,
- char *acl_inf, const int buflen, const int acl_type,
- const struct nls_table *nls_codepage)
-{
-/* SMB_QUERY_POSIX_ACL */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, ("In GetPosixACL (Unix) for path %s", searchName));
-
-queryAclRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
- /* BB fixme find define for this maxpathcomponent */
- , nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->FileName[name_len] = 0;
- pSMB->FileName[name_len+1] = 0;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX /* BB fixme */);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max data count below from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
- pSMB->Reserved4 = 0;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, ("Send error in Query POSIX ACL = %d", rc));
- } else {
- /* decode response */
-
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || (pSMBr->ByteCount < 2))
- /* BB also check enough total bytes returned */
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
- rc = cifs_copy_posix_acl(acl_inf,
- (char *)&pSMBr->hdr.Protocol+data_offset,
- buflen,acl_type,count);
- }
- }
- if (pSMB)
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto queryAclRetry;
- return rc;
-}
-
-int
-CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
- const unsigned char *fileName,
- const char *local_acl, const int buflen, const int acl_type,
- const struct nls_table *nls_codepage)
-{
- struct smb_com_transaction2_spi_req *pSMB = NULL;
- struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
- char *parm_data;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count, data_count, param_offset, offset;
-
- cFYI(1, ("In SetPosixACL (Unix) for path %s", fileName));
-setAclRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
- /* BB fixme find define for this maxpathcomponent */
- , nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
- params = 6 + name_len;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
-
- /* convert to on the wire format for POSIX ACL */
- data_count = ACL_to_cifs_posix(parm_data,local_acl,buflen,acl_type);
-
- if(data_count == 0) {
- rc = -EOPNOTSUPP;
- goto setACLerrorExit;
- }
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
- byte_count = 3 /* pad */ + params + data_count;
- pSMB->DataCount = cpu_to_le16(data_count);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->Reserved4 = 0;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, ("Set POSIX ACL returned %d", rc));
- }
-
-setACLerrorExit:
- if (pSMB)
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto setAclRetry;
- return rc;
-}
-
-#endif
-
int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName,
int name_len;
__u16 params, byte_count;
-/* cFYI(1, ("In QPathInfo path %s", searchName)); */ /* BB fixme BB */
+ cFYI(1, ("In QPathInfo path %s", searchName));
QPathInfoRetry:
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr);
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
if (rc) {
cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < 40))
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ /* BB also check enough total bytes returned */
+ /* BB we need to improve the validity checking
+ of these trans2 responses */
+ if ((pSMBr->ByteCount < 40) || (data_offset > 512))
rc = -EIO; /* bad smb */
else if (pFindData){
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
data_offset, sizeof (FILE_ALL_INFO));
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
if (rc) {
cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ /* BB also check if enough total bytes returned */
+ if ((pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO)) ||
+ (data_offset > 512) ||
+ (data_offset < sizeof(struct smb_hdr))) {
+ cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d",
+ (int)data_offset,bytes_returned));
rc = -EIO; /* bad smb */
} else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
data_offset,
return rc;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL /* function unused at present */
int
CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,
const char *searchName, FILE_ALL_INFO * findData,
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4);
+ offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4);
pSMB->DataCount = 0;
pSMB->DataOffset = 0;
pSMB->SetupCount = 1; /* one byte, no need to le convert */
return rc;
}
-#endif /* CIFS_EXPERIMENTAL */
int
CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
byte_count = params + 1 /* pad */ ;
pSMB->TotalParameterCount = cpu_to_le16(params);
pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
+ pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
+ smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
pSMB->DataCount = 0;
pSMB->DataOffset = 0;
pSMB->SetupCount = 1; /* one byte no need to make endian neutral */
pSMB->SearchAttributes =
cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
ATTR_DIRECTORY);
- pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_DIRECTORY_INFO)); /* should this be shrunk even more ? */
+ pSMB->SearchCount = cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO)); /* should this be shrunk even more ? */
pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
/* test for Unix extensions */
if (rc) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
cFYI(1, ("Error in FindFirst = %d", rc));
- } else {
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if(!rc) {
- /* decode response */
+ } else { /* decode response */
/* BB add safety checks for these memcpys */
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- *pUnicodeFlag = TRUE;
- else
- *pUnicodeFlag = FALSE;
- memcpy(findParms,
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset),
- sizeof (T2_FFIRST_RSP_PARMS));
- response_data =
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
- memcpy(findData, response_data,
- le16_to_cpu(pSMBr->t2.DataCount));
- }
+ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
+ *pUnicodeFlag = TRUE;
+ else
+ *pUnicodeFlag = FALSE;
+ memcpy(findParms,
+ (char *) &pSMBr->hdr.Protocol +
+ le16_to_cpu(pSMBr->ParameterOffset),
+ sizeof (T2_FFIRST_RSP_PARMS));
+ response_data =
+ (char *) &pSMBr->hdr.Protocol +
+ le16_to_cpu(pSMBr->DataOffset);
+ memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
}
if (pSMB)
cifs_buf_release(pSMB);
return rc;
}
-/* xid, tcon, searchName and codepage are input parms, rest are returned */
-int
-CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon,
- const char *searchName,
- const struct nls_table *nls_codepage,
- __u16 * pnetfid,
- struct cifs_search_info * psrch_inf)
-{
-/* level 257 SMB_ */
- TRANSACTION2_FFIRST_REQ *pSMB = NULL;
- TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
- T2_FFIRST_RSP_PARMS * parms;
- int rc = 0;
- int bytes_returned = 0;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, ("In FindFirst2"));
-
-findFirst2Retry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName,searchName,
- PATH_MAX, nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->FileName[name_len] = 0; /* null terminate just in case */
- pSMB->FileName[name_len+1] = 0;
- } else { /* BB add check for overrun of SMB buf BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
-/* BB fix here and in unicode clause above ie
- if(name_len > buffersize-header)
- free buffer exit; BB */
- strncpy(pSMB->FileName, searchName, name_len);
- pSMB->FileName[name_len] = 0; /* just in case */
- }
-
- params = 12 + name_len /* includes null */ ;
- pSMB->TotalDataCount = 0; /* no EAs */
- pSMB->MaxParameterCount = cpu_to_le16(10);
- pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf -
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
- ATTR_DIRECTORY);
- pSMB->SearchCount= cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
- pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END |
- CIFS_SEARCH_RETURN_RESUME);
- pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
-
- /* BB what should we set StorageType to? Does it matter? BB */
- pSMB->SearchStorageType = 0;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
- if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
- /* BB Add code to handle unsupported level rc */
- cFYI(1, ("Error in FindFirst = %d", rc));
-
- if (pSMB)
- cifs_buf_release(pSMB);
-
- /* BB eventually could optimize out free and realloc of buf */
- /* for this case */
- if (rc == -EAGAIN)
- goto findFirst2Retry;
- } else { /* decode response */
- /* BB remember to free buffer if error BB */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if(rc == 0) {
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- psrch_inf->unicode = TRUE;
- else
- psrch_inf->unicode = FALSE;
-
- psrch_inf->ntwrk_buf_start = (char *)pSMBr;
- psrch_inf->srch_entries_start =
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
-
- parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset));
-
- if(parms->EndofSearch)
- psrch_inf->endOfSearch = TRUE;
- else
- psrch_inf->endOfSearch = FALSE;
-
- psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
- psrch_inf->index_of_last_entry =
- psrch_inf->entries_in_buffer;
-/*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */
- *pnetfid = parms->SearchHandle;
- } else {
- if(pSMB)
- cifs_buf_release(pSMB);
- }
- }
-
- return rc;
-}
-
-int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon,
- __u16 searchHandle, struct cifs_search_info * psrch_inf)
-{
- TRANSACTION2_FNEXT_REQ *pSMB = NULL;
- TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
- T2_FNEXT_RSP_PARMS * parms;
- char *response_data;
- int rc = 0;
- int bytes_returned, name_len;
- __u16 params, byte_count;
-
- cFYI(1, ("In FindNext2"));
-
- if(psrch_inf->endOfSearch == TRUE)
- return -ENOENT;
-
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 14; /* includes 2 bytes of null string, converted to LE below */
- byte_count = 0;
- pSMB->TotalDataCount = 0; /* no EAs */
- pSMB->MaxParameterCount = cpu_to_le16(8);
- pSMB->MaxDataCount =
- cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
- pSMB->SearchHandle = searchHandle; /* always kept as le */
- pSMB->SearchCount =
- cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
- /* test for Unix extensions */
-/* if (tcon->ses->capabilities & CAP_UNIX) {
- pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
- psrch_inf->info_level = SMB_FIND_FILE_UNIX;
- } else {
- pSMB->InformationLevel =
- cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
- psrch_inf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
- } */
- pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
- pSMB->ResumeKey = psrch_inf->resume_key;
- pSMB->SearchFlags =
- cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
-
- name_len = psrch_inf->resume_name_len;
- params += name_len;
- if(name_len < PATH_MAX) {
- memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
- byte_count += name_len;
- } else {
- rc = -EINVAL;
- goto FNext2_err_exit;
- }
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->hdr.smb_buf_length += byte_count;
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
- if (rc) {
- if (rc == -EBADF) {
- psrch_inf->endOfSearch = TRUE;
- rc = 0; /* search probably was closed at end of search above */
- } else
- cFYI(1, ("FindNext returned = %d", rc));
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if(rc == 0) {
- /* BB fixme add lock for file (srch_info) struct here */
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- psrch_inf->unicode = TRUE;
- else
- psrch_inf->unicode = FALSE;
- response_data = (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset);
- parms = (T2_FNEXT_RSP_PARMS *)response_data;
- response_data = (char *)&pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
- cifs_buf_release(psrch_inf->ntwrk_buf_start);
- psrch_inf->srch_entries_start = response_data;
- psrch_inf->ntwrk_buf_start = (char *)pSMB;
- if(parms->EndofSearch)
- psrch_inf->endOfSearch = TRUE;
- else
- psrch_inf->endOfSearch = FALSE;
-
- psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount);
- psrch_inf->index_of_last_entry +=
- psrch_inf->entries_in_buffer;
-/* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */
-
- /* BB fixme add unlock here */
- }
-
- }
-
- /* BB On error, should we leave previous search buf (and count and
- last entry fields) intact or free the previous one? */
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-FNext2_err_exit:
- if ((rc != 0) && pSMB)
- cifs_buf_release(pSMB);
-
- return rc;
-}
-
int
CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,
pSMB->Flags = 0;
pSMB->Timeout = 0;
pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
+ pSMB->ParameterOffset = cpu_to_le16(offsetof(
+ struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
pSMB->DataCount = 0;
pSMB->DataOffset = 0;
pSMB->SetupCount = 1;
pSMB->SearchHandle = searchHandle; /* always kept as le */
findParms->SearchCount = 0; /* set to zero in case of error */
pSMB->SearchCount =
- cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO));
+ cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));
/* test for Unix extensions */
if (tcon->ses->capabilities & CAP_UNIX) {
pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
pSMB->SearchFlags =
cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
/* BB add check to make sure we do not cross end of smb */
- if(name_len < PATH_MAX) {
+ if(name_len < CIFS_MAX_MSGSIZE) {
memcpy(pSMB->ResumeFileName, resume_file_name, name_len);
byte_count += name_len;
}
else
cFYI(1, ("FindNext returned = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
/* BB add safety checks for these memcpys */
- if(rc == 0) {
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- *pUnicodeFlag = TRUE;
- else
- *pUnicodeFlag = FALSE;
- memcpy(findParms,
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset),
- sizeof (T2_FNEXT_RSP_PARMS));
- response_data =
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
- memcpy(findData,response_data,le16_to_cpu(pSMBr->t2.DataCount));
- }
+ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
+ *pUnicodeFlag = TRUE;
+ else
+ *pUnicodeFlag = FALSE;
+ memcpy(findParms,
+ (char *) &pSMBr->hdr.Protocol +
+ le16_to_cpu(pSMBr->ParameterOffset),
+ sizeof (T2_FNEXT_RSP_PARMS));
+ response_data =
+ (char *) &pSMBr->hdr.Protocol +
+ le16_to_cpu(pSMBr->DataOffset);
+ memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
}
if (pSMB)
cifs_buf_release(pSMB);
{
int rc = 0;
FINDCLOSE_REQ *pSMB = NULL;
- CLOSE_RSP *pSMBr = NULL; /* BB removeme BB */
+ CLOSE_RSP *pSMBr = NULL;
int bytes_returned;
cFYI(1, ("In CIFSSMBFindClose"));
- rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
- pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
+ rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
/* no sense returning error if session restarted
file handle has been closed */
if(rc == -EAGAIN)
cERROR(1, ("Send error in FindClose = %d", rc));
}
if (pSMB)
- cifs_small_buf_release(pSMB);
+ cifs_buf_release(pSMB);
/* Since session is dead, search handle closed on server already */
if (rc == -EAGAIN)
return rc;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-int
-CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
- const unsigned char *searchName,
- __u64 * inode_number,
- const struct nls_table *nls_codepage)
-{
- int rc = 0;
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
-
- cFYI(1,("In GetSrvInodeNumber for %s",searchName));
- if(tcon == NULL)
- return -ENODEV;
-
- cFYI(1, ("In QPathInfo path %s", searchName));
-GetInodeNumberRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
-/* BB add missing code here */
-
- if (pSMB)
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto GetInodeNumberRetry;
- return rc;
-}
-#endif /* CIFS_EXPERIMENTAL */
-
int
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
const unsigned char *searchName,
pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
name_len =
cifs_strtoUCS((wchar_t *) pSMB->RequestFileName,
- searchName, PATH_MAX
+ searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->RequestFileName, searchName, name_len);
}
cFYI(1, ("Send error in GetDFSRefer = %d", rc));
} else { /* decode response */
/* BB Add logic to parse referrals here */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < 17)) /* BB also check enough total bytes returned */
- rc = -EIO; /* bad smb */
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ __u16 data_count = le16_to_cpu(pSMBr->DataCount);
+ cFYI(1,
+ ("Decoding GetDFSRefer response. BCC: %d Offset %d",
+ pSMBr->ByteCount, data_offset));
+ if ((pSMBr->ByteCount < 17) || (data_offset > 512)) /* BB also check enough total bytes returned */
+ rc = -EIO; /* bad smb */
else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
-
- cFYI(1,
- ("Decoding GetDFSRefer response. BCC: %d Offset %d",
- pSMBr->ByteCount, data_offset));
referrals =
(struct dfs_referral_level_3 *)
(8 /* sizeof start of data block */ +
if (rc) {
cERROR(1, ("Send error in QFSInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < 24)) /* BB alsO CHEck enough total bytes returned */
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ cFYI(1,
+ ("Decoding qfsinfo response. BCC: %d Offset %d",
+ pSMBr->ByteCount, data_offset));
+ if ((pSMBr->ByteCount < 24) || (data_offset > 512)) /* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */
else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- cFYI(1,
- ("Decoding qfsinfo response. BCC: %d Offset %d",
- pSMBr->ByteCount, data_offset));
-
response_data =
(FILE_SYSTEM_INFO
*) (((char *) &pSMBr->hdr.Protocol) +
if (rc) {
cERROR(1, ("Send error in QFSAttributeInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < 13)) { /* BB also check enough bytes returned */
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ if ((pSMBr->ByteCount < 13) || (data_offset > 512)) { /* BB also check enough bytes returned */
rc = -EIO; /* bad smb */
} else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
response_data =
(FILE_SYSTEM_ATTRIBUTE_INFO
*) (((char *) &pSMBr->hdr.Protocol) +
if (rc) {
cFYI(1, ("Send error in QFSDeviceInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO)))
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))
+ || (data_offset > 512))
rc = -EIO; /* bad smb */
else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
response_data =
(FILE_SYSTEM_DEVICE_INFO
*) (((char *) &pSMBr->hdr.Protocol) +
if (rc) {
cERROR(1, ("Send error in QFSUnixInfo = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || (pSMBr->ByteCount < 13)) {
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
+ if ((pSMBr->ByteCount < 13) || (data_offset > 512)) {
rc = -EIO; /* bad smb */
} else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
response_data =
(FILE_SYSTEM_UNIX_INFO
*) (((char *) &pSMBr->hdr.Protocol) +
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
pSMB->ParameterCount = cpu_to_le16(params);
pSMB->TotalDataCount = pSMB->DataCount;
pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
+ /* I doubt that passthrough levels apply to this old
+ preNT info level */
+/* if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
+ pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
+ else*/
+ pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += byte_count;
memcpy(data_offset, data, sizeof (FILE_INFO_STANDARD));
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}
data_offset =
(FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
offset);
- memset(data_offset, 0, count);
pSMB->DataOffset = cpu_to_le16(offset);
pSMB->ParameterOffset = cpu_to_le16(param_offset);
pSMB->SetupCount = 1;
pSMB->ByteCount = 0;
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, -1);
+ (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cFYI(1, ("Error in Notify = %d", rc));
}
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
if (rc) {
cFYI(1, ("Send error in QueryAllEAs = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
/* BB also check enough total bytes returned */
/* BB we need to improve the validity checking
of these trans2 responses */
- if (rc || (pSMBr->ByteCount < 4))
+ if ((pSMBr->ByteCount < 4) || (data_offset > 512))
rc = -EIO; /* bad smb */
/* else if (pFindData){
memcpy((char *) pFindData,
of list */
/* check that each element of each entry does not
go beyond end of list */
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
struct fealist * ea_response_data;
rc = 0;
/* validate_trans2_offsets() */
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
+ name_len = strnlen(searchName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len);
}
if (rc) {
cFYI(1, ("Send error in Query EA = %d", rc));
} else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
/* BB also check enough total bytes returned */
/* BB we need to improve the validity checking
of these trans2 responses */
- if (rc || (pSMBr->ByteCount < 4))
+ if ((pSMBr->ByteCount < 4) || (data_offset > 512))
rc = -EIO; /* bad smb */
/* else if (pFindData){
memcpy((char *) pFindData,
of list */
/* check that each element of each entry does not
go beyond end of list */
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
struct fealist * ea_response_data;
- rc = -ENODATA;
+ rc = -ENOENT;
/* validate_trans2_offsets() */
/* BB to check if(start of smb + data_offset > &bcc+ bcc)*/
ea_response_data = (struct fealist *)
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
- cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX
+ cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
/* find define for this maxpathcomponent */
, nls_codepage);
name_len++; /* trailing null */
name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
+ name_len = strnlen(fileName, 530);
name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len);
}