|
@@ -339,12 +339,13 @@ static int validate_t2(struct smb_t2_rsp *pSMB)
|
|
|
get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
|
|
|
goto vt2_err;
|
|
|
|
|
|
- /* check that bcc is at least as big as parms + data */
|
|
|
- /* check that bcc is less than negotiated smb buffer */
|
|
|
total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
|
|
|
if (total_size >= 512)
|
|
|
goto vt2_err;
|
|
|
|
|
|
+ /* check that bcc is at least as big as parms + data, and that it is
|
|
|
+ * less than negotiated smb buffer
|
|
|
+ */
|
|
|
total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
|
|
|
if (total_size > get_bcc(&pSMB->hdr) ||
|
|
|
total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
|
|
@@ -357,6 +358,13 @@ vt2_err:
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+static inline void inc_rfc1001_len(void *pSMB, int count)
|
|
|
+{
|
|
|
+ struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
|
|
|
+
|
|
|
+ be32_add_cpu(&hdr->smb_buf_length, count);
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|
|
{
|
|
@@ -409,7 +417,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|
|
count += strlen(protocols[i].name) + 1;
|
|
|
/* null at end of source and target buffers anyway */
|
|
|
}
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
|
|
|
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
|
|
@@ -541,10 +549,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|
|
server->secType = RawNTLMSSP;
|
|
|
else if (secFlags & CIFSSEC_MAY_LANMAN)
|
|
|
server->secType = LANMAN;
|
|
|
-/* #ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
|
- else if (secFlags & CIFSSEC_MAY_PLNTXT)
|
|
|
- server->secType = ??
|
|
|
-#endif */
|
|
|
else {
|
|
|
rc = -EOPNOTSUPP;
|
|
|
cERROR(1, "Invalid security type");
|
|
@@ -578,7 +582,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
|
|
|
|
|
|
if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
|
|
|
(server->capabilities & CAP_EXTENDED_SECURITY)) {
|
|
|
- count = pSMBr->ByteCount;
|
|
|
+ count = get_bcc(&pSMBr->hdr);
|
|
|
if (count < 16) {
|
|
|
rc = -EIO;
|
|
|
goto neg_err_exit;
|
|
@@ -732,9 +736,9 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
|
|
|
smb->hdr.Tid = 0xffff;
|
|
|
smb->hdr.WordCount = 1;
|
|
|
put_unaligned_le16(1, &smb->EchoCount);
|
|
|
- put_bcc_le(1, &smb->hdr);
|
|
|
+ put_bcc(1, &smb->hdr);
|
|
|
smb->Data[0] = 'a';
|
|
|
- smb->hdr.smb_buf_length += 3;
|
|
|
+ inc_rfc1001_len(smb, 3);
|
|
|
|
|
|
rc = cifs_call_async(server, (struct smb_hdr *)smb,
|
|
|
cifs_echo_callback, server);
|
|
@@ -852,7 +856,7 @@ PsxDelete:
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -898,7 +902,7 @@ DelFileRetry:
|
|
|
pSMB->SearchAttributes =
|
|
|
cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
|
|
|
pSMB->BufferFormat = 0x04;
|
|
|
- pSMB->hdr.smb_buf_length += name_len + 1;
|
|
|
+ inc_rfc1001_len(pSMB, name_len + 1);
|
|
|
pSMB->ByteCount = cpu_to_le16(name_len + 1);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -942,7 +946,7 @@ RmDirRetry:
|
|
|
}
|
|
|
|
|
|
pSMB->BufferFormat = 0x04;
|
|
|
- pSMB->hdr.smb_buf_length += name_len + 1;
|
|
|
+ inc_rfc1001_len(pSMB, name_len + 1);
|
|
|
pSMB->ByteCount = cpu_to_le16(name_len + 1);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -985,7 +989,7 @@ MkDirRetry:
|
|
|
}
|
|
|
|
|
|
pSMB->BufferFormat = 0x04;
|
|
|
- pSMB->hdr.smb_buf_length += name_len + 1;
|
|
|
+ inc_rfc1001_len(pSMB, name_len + 1);
|
|
|
pSMB->ByteCount = cpu_to_le16(name_len + 1);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -1063,7 +1067,7 @@ PsxCreat:
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -1075,7 +1079,7 @@ PsxCreat:
|
|
|
cFYI(1, "copying inode info");
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
goto psx_create_err;
|
|
|
}
|
|
@@ -1096,7 +1100,7 @@ PsxCreat:
|
|
|
pRetData->Type = cpu_to_le32(-1); /* unknown */
|
|
|
cFYI(DBG2, "unknown type");
|
|
|
} else {
|
|
|
- if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
|
|
|
+ if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
|
|
|
+ sizeof(FILE_UNIX_BASIC_INFO)) {
|
|
|
cERROR(1, "Open response data too small");
|
|
|
pRetData->Type = cpu_to_le32(-1);
|
|
@@ -1228,7 +1232,7 @@ OldOpenRetry:
|
|
|
pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
|
|
|
pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
|
|
|
count += name_len;
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
/* long_op set to 1 to allow for oplock break timeouts */
|
|
@@ -1341,7 +1345,7 @@ openRetry:
|
|
|
SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
|
|
|
|
|
|
count += name_len;
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
/* long_op set to 1 to allow for oplock break timeouts */
|
|
@@ -1426,7 +1430,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|
|
}
|
|
|
|
|
|
iov[0].iov_base = (char *)pSMB;
|
|
|
- iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
|
|
|
+ iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
|
|
|
rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
|
|
|
&resp_buf_type, CIFS_LOG_ERROR);
|
|
|
cifs_stats_inc(&tcon->num_reads);
|
|
@@ -1560,7 +1564,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|
|
|
|
|
pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
|
|
|
pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
|
|
|
if (wct == 14)
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
@@ -1644,11 +1648,12 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|
|
|
|
|
pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
|
|
|
pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
|
|
|
- smb_hdr_len = pSMB->hdr.smb_buf_length + 1; /* hdr + 1 byte pad */
|
|
|
+ /* header + 1 byte pad */
|
|
|
+ smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
|
|
|
if (wct == 14)
|
|
|
- pSMB->hdr.smb_buf_length += count+1;
|
|
|
+ inc_rfc1001_len(pSMB, count + 1);
|
|
|
else /* wct == 12 */
|
|
|
- pSMB->hdr.smb_buf_length += count+5; /* smb data starts later */
|
|
|
+ inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
|
|
|
if (wct == 14)
|
|
|
pSMB->ByteCount = cpu_to_le16(count + 1);
|
|
|
else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
|
|
@@ -1748,7 +1753,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
|
|
|
/* oplock break */
|
|
|
count = 0;
|
|
|
}
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
|
|
|
if (waitFlag) {
|
|
@@ -1839,14 +1844,14 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|
|
pSMB->Fid = smb_file_id;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
if (waitFlag) {
|
|
|
rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned);
|
|
|
} else {
|
|
|
iov[0].iov_base = (char *)pSMB;
|
|
|
- iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
|
|
|
+ iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
|
|
|
rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
|
|
|
&resp_buf_type, timeout);
|
|
|
pSMB = NULL; /* request buf already freed by SendReceive2. Do
|
|
@@ -1862,7 +1867,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|
|
__u16 data_count;
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
goto plk_err_exit;
|
|
|
}
|
|
@@ -2012,7 +2017,7 @@ renameRetry:
|
|
|
}
|
|
|
|
|
|
count = 1 /* 1st signature byte */ + name_len + name_len2;
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2092,7 +2097,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
|
|
|
pSMB->InformationLevel =
|
|
|
cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -2159,7 +2164,7 @@ copyRetry:
|
|
|
}
|
|
|
|
|
|
count = 1 /* 1st signature byte */ + name_len + name_len2;
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2249,7 +2254,7 @@ createSymLinkRetry:
|
|
|
pSMB->DataOffset = cpu_to_le16(offset);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -2335,7 +2340,7 @@ createHardLinkRetry:
|
|
|
pSMB->DataOffset = cpu_to_le16(offset);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -2406,7 +2411,7 @@ winCreateHardLinkRetry:
|
|
|
}
|
|
|
|
|
|
count = 1 /* string type byte */ + name_len + name_len2;
|
|
|
- pSMB->hdr.smb_buf_length += count;
|
|
|
+ inc_rfc1001_len(pSMB, count);
|
|
|
pSMB->ByteCount = cpu_to_le16(count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2477,7 +2482,7 @@ querySymLinkRetry:
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2489,7 +2494,7 @@ querySymLinkRetry:
|
|
|
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
/* BB also check enough total bytes returned */
|
|
|
- if (rc || (pSMBr->ByteCount < 2))
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 2)
|
|
|
rc = -EIO;
|
|
|
else {
|
|
|
bool is_unicode;
|
|
@@ -2516,7 +2521,17 @@ querySymLinkRetry:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_CIFS_EXPERIMENTAL
|
|
|
+#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
|
|
|
+/*
|
|
|
+ * Recent Windows versions now create symlinks more frequently
|
|
|
+ * and they use the "reparse point" mechanism below. We can of course
|
|
|
+ * do symlinks nicely to Samba and other servers which support the
|
|
|
+ * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
|
|
|
+ * "MF" symlinks optionally, but for recent Windows we really need to
|
|
|
+ * reenable the code below and fix the cifs_symlink callers to handle this.
|
|
|
+ * In the interim this code has been moved to its own config option so
|
|
|
+ * it is not compiled in by default until callers fixed up and more tested.
|
|
|
+ */
|
|
|
int
|
|
|
CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
|
|
|
const unsigned char *searchName,
|
|
@@ -2561,14 +2576,14 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
|
|
|
} else { /* decode response */
|
|
|
__u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
|
|
|
__u32 data_count = le32_to_cpu(pSMBr->DataCount);
|
|
|
- if ((pSMBr->ByteCount < 2) || (data_offset > 512)) {
|
|
|
- /* BB also check enough total bytes returned */
|
|
|
+ if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
|
|
|
+ /* BB also check enough total bytes returned */
|
|
|
rc = -EIO; /* bad smb */
|
|
|
goto qreparse_out;
|
|
|
}
|
|
|
if (data_count && (data_count < 2048)) {
|
|
|
char *end_of_smb = 2 /* sizeof byte count */ +
|
|
|
- pSMBr->ByteCount + (char *)&pSMBr->ByteCount;
|
|
|
+ get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
|
|
|
|
|
|
struct reparse_data *reparse_buf =
|
|
|
(struct reparse_data *)
|
|
@@ -2618,7 +2633,7 @@ qreparse_out:
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
|
-#endif /* CIFS_EXPERIMENTAL */
|
|
|
+#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
|
|
|
|
|
|
#ifdef CONFIG_CIFS_POSIX
|
|
|
|
|
@@ -2814,7 +2829,7 @@ queryAclRetry:
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2826,8 +2841,8 @@ queryAclRetry:
|
|
|
/* decode response */
|
|
|
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
- if (rc || (pSMBr->ByteCount < 2))
|
|
|
/* BB also check enough total bytes returned */
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 2)
|
|
|
rc = -EIO; /* bad smb */
|
|
|
else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -2908,7 +2923,7 @@ setAclRetry:
|
|
|
pSMB->ParameterCount = cpu_to_le16(params);
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -2966,7 +2981,7 @@ GetExtAttrRetry:
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
|
|
|
pSMB->Pad = 0;
|
|
|
pSMB->Fid = netfid;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->t2.ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -2976,8 +2991,8 @@ GetExtAttrRetry:
|
|
|
} else {
|
|
|
/* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
- if (rc || (pSMBr->ByteCount < 2))
|
|
|
/* BB also check enough total bytes returned */
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 2)
|
|
|
/* If rc should we check for EOPNOSUPP and
|
|
|
disable the srvino flag? or in caller? */
|
|
|
rc = -EIO; /* bad smb */
|
|
@@ -3052,6 +3067,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
|
|
|
char *end_of_smb;
|
|
|
__u32 data_count, data_offset, parm_count, parm_offset;
|
|
|
struct smb_com_ntransact_rsp *pSMBr;
|
|
|
+ u16 bcc;
|
|
|
|
|
|
*pdatalen = 0;
|
|
|
*pparmlen = 0;
|
|
@@ -3061,8 +3077,8 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
|
|
|
|
|
|
pSMBr = (struct smb_com_ntransact_rsp *)buf;
|
|
|
|
|
|
- /* ByteCount was converted from little endian in SendReceive */
|
|
|
- end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount +
|
|
|
+ bcc = get_bcc(&pSMBr->hdr);
|
|
|
+ end_of_smb = 2 /* sizeof byte count */ + bcc +
|
|
|
(char *)&pSMBr->ByteCount;
|
|
|
|
|
|
data_offset = le32_to_cpu(pSMBr->DataOffset);
|
|
@@ -3088,7 +3104,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
|
|
|
*ppdata, data_count, (data_count + *ppdata),
|
|
|
end_of_smb, pSMBr);
|
|
|
return -EINVAL;
|
|
|
- } else if (parm_count + data_count > pSMBr->ByteCount) {
|
|
|
+ } else if (parm_count + data_count > bcc) {
|
|
|
cFYI(1, "parm count and data count larger than SMB");
|
|
|
return -EINVAL;
|
|
|
}
|
|
@@ -3124,9 +3140,9 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
|
|
|
pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
|
|
|
CIFS_ACL_DACL);
|
|
|
pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
|
|
|
- pSMB->hdr.smb_buf_length += 11;
|
|
|
+ inc_rfc1001_len(pSMB, 11);
|
|
|
iov[0].iov_base = (char *)pSMB;
|
|
|
- iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
|
|
|
+ iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
|
|
|
|
|
|
rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
|
|
|
0);
|
|
@@ -3235,10 +3251,9 @@ setCifsAclRetry:
|
|
|
memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
|
|
|
(char *) pntsd,
|
|
|
acllen);
|
|
|
- pSMB->hdr.smb_buf_length += (byte_count + data_count);
|
|
|
-
|
|
|
+ inc_rfc1001_len(pSMB, byte_count + data_count);
|
|
|
} else
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -3289,7 +3304,7 @@ QInfRetry:
|
|
|
}
|
|
|
pSMB->BufferFormat = 0x04;
|
|
|
name_len++; /* account for buffer type byte */
|
|
|
- pSMB->hdr.smb_buf_length += (__u16) name_len;
|
|
|
+ inc_rfc1001_len(pSMB, (__u16)name_len);
|
|
|
pSMB->ByteCount = cpu_to_le16(name_len);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -3364,7 +3379,7 @@ QFileInfoRetry:
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
|
|
|
pSMB->Pad = 0;
|
|
|
pSMB->Fid = netfid;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -3375,7 +3390,7 @@ QFileInfoRetry:
|
|
|
|
|
|
if (rc) /* BB add auto retry on EOPNOTSUPP? */
|
|
|
rc = -EIO;
|
|
|
- else if (pSMBr->ByteCount < 40)
|
|
|
+ else if (get_bcc(&pSMBr->hdr) < 40)
|
|
|
rc = -EIO; /* bad smb */
|
|
|
else if (pFindData) {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -3451,7 +3466,7 @@ QPathInfoRetry:
|
|
|
else
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -3463,9 +3478,9 @@ QPathInfoRetry:
|
|
|
|
|
|
if (rc) /* BB add auto retry on EOPNOTSUPP? */
|
|
|
rc = -EIO;
|
|
|
- else if (!legacy && (pSMBr->ByteCount < 40))
|
|
|
+ else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
|
|
|
rc = -EIO; /* bad smb */
|
|
|
- else if (legacy && (pSMBr->ByteCount < 24))
|
|
|
+ else if (legacy && get_bcc(&pSMBr->hdr) < 24)
|
|
|
rc = -EIO; /* 24 or 26 expected but we do not read
|
|
|
last field */
|
|
|
else if (pFindData) {
|
|
@@ -3532,7 +3547,7 @@ UnixQFileInfoRetry:
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
|
|
|
pSMB->Pad = 0;
|
|
|
pSMB->Fid = netfid;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -3541,7 +3556,7 @@ UnixQFileInfoRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
|
|
|
cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
|
|
|
"Unix Extensions can be disabled on mount "
|
|
|
"by specifying the nosfu mount option.");
|
|
@@ -3617,7 +3632,7 @@ UnixQPathInfoRetry:
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -3627,7 +3642,7 @@ UnixQPathInfoRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
|
|
|
cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
|
|
|
"Unix Extensions can be disabled on mount "
|
|
|
"by specifying the nosfu mount option.");
|
|
@@ -3731,7 +3746,7 @@ findFirstRetry:
|
|
|
|
|
|
/* BB what should we set StorageType to? Does it matter? BB */
|
|
|
pSMB->SearchStorageType = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -3860,7 +3875,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
|
|
|
byte_count = params + 1 /* pad */ ;
|
|
|
pSMB->TotalParameterCount = cpu_to_le16(params);
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4022,7 +4037,7 @@ GetInodeNumberRetry:
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4032,8 +4047,8 @@ GetInodeNumberRetry:
|
|
|
} else {
|
|
|
/* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
- if (rc || (pSMBr->ByteCount < 2))
|
|
|
/* BB also check enough total bytes returned */
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 2)
|
|
|
/* If rc should we check for EOPNOSUPP and
|
|
|
disable the srvino flag? or in caller? */
|
|
|
rc = -EIO; /* bad smb */
|
|
@@ -4246,7 +4261,7 @@ getDFSRetry:
|
|
|
pSMB->ParameterCount = cpu_to_le16(params);
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->MaxReferralLevel = cpu_to_le16(3);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
|
|
@@ -4258,13 +4273,13 @@ getDFSRetry:
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
/* BB Also check if enough total bytes returned? */
|
|
|
- if (rc || (pSMBr->ByteCount < 17)) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 17) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
goto GetDFSRefExit;
|
|
|
}
|
|
|
|
|
|
cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
|
|
|
- pSMBr->ByteCount,
|
|
|
+ get_bcc(&pSMBr->hdr),
|
|
|
le16_to_cpu(pSMBr->t2.DataOffset));
|
|
|
|
|
|
/* parse returned result into more usable form */
|
|
@@ -4320,7 +4335,7 @@ oldQFSInfoRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4330,12 +4345,12 @@ oldQFSInfoRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 18))
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 18)
|
|
|
rc = -EIO; /* bad smb */
|
|
|
else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
|
cFYI(1, "qfsinf resp BCC: %d Offset %d",
|
|
|
- pSMBr->ByteCount, data_offset);
|
|
|
+ get_bcc(&pSMBr->hdr), data_offset);
|
|
|
|
|
|
response_data = (FILE_SYSTEM_ALLOC_INFO *)
|
|
|
(((char *) &pSMBr->hdr.Protocol) + data_offset);
|
|
@@ -4399,7 +4414,7 @@ QFSInfoRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4409,7 +4424,7 @@ QFSInfoRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 24))
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 24)
|
|
|
rc = -EIO; /* bad smb */
|
|
|
else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -4479,7 +4494,7 @@ QFSAttributeRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4489,7 +4504,7 @@ QFSAttributeRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 13)) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 13) {
|
|
|
/* BB also check if enough bytes returned */
|
|
|
rc = -EIO; /* bad smb */
|
|
|
} else {
|
|
@@ -4550,7 +4565,7 @@ QFSDeviceRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4560,7 +4575,8 @@ QFSDeviceRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < sizeof(FILE_SYSTEM_DEVICE_INFO)))
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) <
|
|
|
+ sizeof(FILE_SYSTEM_DEVICE_INFO))
|
|
|
rc = -EIO; /* bad smb */
|
|
|
else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -4619,7 +4635,7 @@ QFSUnixRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4629,7 +4645,7 @@ QFSUnixRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 13)) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 13) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
} else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -4702,7 +4718,7 @@ SETFSUnixRetry:
|
|
|
pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
|
|
|
pSMB->ClientUnixCap = cpu_to_le64(cap);
|
|
|
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4764,7 +4780,7 @@ QFSPosixRetry:
|
|
|
pSMB->Reserved3 = 0;
|
|
|
pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4774,7 +4790,7 @@ QFSPosixRetry:
|
|
|
} else { /* decode response */
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
|
|
|
- if (rc || (pSMBr->ByteCount < 13)) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 13) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
} else {
|
|
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
|
@@ -4890,7 +4906,7 @@ SetEOFRetry:
|
|
|
pSMB->ParameterCount = cpu_to_le16(params);
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
parm_data->FileSize = cpu_to_le64(size);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -4969,7 +4985,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
|
|
|
cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
|
|
|
}
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
|
|
|
if (rc) {
|
|
@@ -5037,7 +5053,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
|
|
else
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
|
|
|
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
|
|
@@ -5096,7 +5112,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
|
|
|
pSMB->Fid = fid;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
*data_offset = delete_file ? 1 : 0;
|
|
|
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
|
|
@@ -5169,7 +5185,7 @@ SetTimesRetry:
|
|
|
else
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -5221,7 +5237,7 @@ SetAttrLgcyRetry:
|
|
|
}
|
|
|
pSMB->attr = cpu_to_le16(dos_attrs);
|
|
|
pSMB->BufferFormat = 0x04;
|
|
|
- pSMB->hdr.smb_buf_length += name_len + 1;
|
|
|
+ inc_rfc1001_len(pSMB, name_len + 1);
|
|
|
pSMB->ByteCount = cpu_to_le16(name_len + 1);
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
|
@@ -5326,7 +5342,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
|
|
|
pSMB->Fid = fid;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
cifs_fill_unix_set_info(data_offset, args);
|
|
@@ -5402,7 +5418,7 @@ setPermsRetry:
|
|
|
pSMB->TotalDataCount = pSMB->DataCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
|
|
|
cifs_fill_unix_set_info(data_offset, args);
|
|
|
|
|
@@ -5418,79 +5434,6 @@ setPermsRetry:
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
|
|
|
- const int notify_subdirs, const __u16 netfid,
|
|
|
- __u32 filter, struct file *pfile, int multishot,
|
|
|
- const struct nls_table *nls_codepage)
|
|
|
-{
|
|
|
- int rc = 0;
|
|
|
- struct smb_com_transaction_change_notify_req *pSMB = NULL;
|
|
|
- struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
|
|
|
- struct dir_notify_req *dnotify_req;
|
|
|
- int bytes_returned;
|
|
|
-
|
|
|
- cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
|
|
|
- rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
|
|
|
- (void **) &pSMBr);
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
-
|
|
|
- pSMB->TotalParameterCount = 0 ;
|
|
|
- pSMB->TotalDataCount = 0;
|
|
|
- pSMB->MaxParameterCount = cpu_to_le32(2);
|
|
|
- /* BB find exact data count max from sess structure BB */
|
|
|
- pSMB->MaxDataCount = 0; /* same in little endian or be */
|
|
|
-/* BB VERIFY verify which is correct for above BB */
|
|
|
- pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
|
|
|
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
|
|
|
-
|
|
|
- pSMB->MaxSetupCount = 4;
|
|
|
- pSMB->Reserved = 0;
|
|
|
- pSMB->ParameterOffset = 0;
|
|
|
- pSMB->DataCount = 0;
|
|
|
- pSMB->DataOffset = 0;
|
|
|
- pSMB->SetupCount = 4; /* single byte does not need le conversion */
|
|
|
- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
|
|
|
- pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
- if (notify_subdirs)
|
|
|
- pSMB->WatchTree = 1; /* one byte - no le conversion needed */
|
|
|
- pSMB->Reserved2 = 0;
|
|
|
- pSMB->CompletionFilter = cpu_to_le32(filter);
|
|
|
- pSMB->Fid = netfid; /* file handle always le */
|
|
|
- pSMB->ByteCount = 0;
|
|
|
-
|
|
|
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
- (struct smb_hdr *)pSMBr, &bytes_returned,
|
|
|
- CIFS_ASYNC_OP);
|
|
|
- if (rc) {
|
|
|
- cFYI(1, "Error in Notify = %d", rc);
|
|
|
- } else {
|
|
|
- /* Add file to outstanding requests */
|
|
|
- /* BB change to kmem cache alloc */
|
|
|
- dnotify_req = kmalloc(
|
|
|
- sizeof(struct dir_notify_req),
|
|
|
- GFP_KERNEL);
|
|
|
- if (dnotify_req) {
|
|
|
- dnotify_req->Pid = pSMB->hdr.Pid;
|
|
|
- dnotify_req->PidHigh = pSMB->hdr.PidHigh;
|
|
|
- dnotify_req->Mid = pSMB->hdr.Mid;
|
|
|
- dnotify_req->Tid = pSMB->hdr.Tid;
|
|
|
- dnotify_req->Uid = pSMB->hdr.Uid;
|
|
|
- dnotify_req->netfid = netfid;
|
|
|
- dnotify_req->pfile = pfile;
|
|
|
- dnotify_req->filter = filter;
|
|
|
- dnotify_req->multishot = multishot;
|
|
|
- spin_lock(&GlobalMid_Lock);
|
|
|
- list_add_tail(&dnotify_req->lhead,
|
|
|
- &GlobalDnotifyReqList);
|
|
|
- spin_unlock(&GlobalMid_Lock);
|
|
|
- } else
|
|
|
- rc = -ENOMEM;
|
|
|
- }
|
|
|
- cifs_buf_release(pSMB);
|
|
|
- return rc;
|
|
|
-}
|
|
|
-
|
|
|
#ifdef CONFIG_CIFS_XATTR
|
|
|
/*
|
|
|
* Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
|
|
@@ -5560,7 +5503,7 @@ QAllEAsRetry:
|
|
|
pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, byte_count);
|
|
|
pSMB->ByteCount = cpu_to_le16(byte_count);
|
|
|
|
|
|
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
@@ -5576,7 +5519,7 @@ QAllEAsRetry:
|
|
|
of these trans2 responses */
|
|
|
|
|
|
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
|
|
|
- if (rc || (pSMBr->ByteCount < 4)) {
|
|
|
+ if (rc || get_bcc(&pSMBr->hdr) < 4) {
|
|
|
rc = -EIO; /* bad smb */
|
|
|
goto QAllEAsOut;
|
|
|
}
|
|
@@ -5773,7 +5716,7 @@ SetEARetry:
|
|
|
pSMB->ParameterCount = cpu_to_le16(params);
|
|
|
pSMB->TotalParameterCount = pSMB->ParameterCount;
|
|
|
pSMB->Reserved4 = 0;
|
|
|
- pSMB->hdr.smb_buf_length += byte_count;
|
|
|
+ inc_rfc1001_len(pSMB, 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);
|
|
@@ -5787,5 +5730,99 @@ SetEARetry:
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
|
-
|
|
|
#endif
|
|
|
+
|
|
|
+#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
|
|
|
+/*
|
|
|
+ * Years ago the kernel added a "dnotify" function for Samba server,
|
|
|
+ * to allow network clients (such as Windows) to display updated
|
|
|
+ * lists of files in directory listings automatically when
|
|
|
+ * files are added by one user when another user has the
|
|
|
+ * same directory open on their desktop. The Linux cifs kernel
|
|
|
+ * client hooked into the kernel side of this interface for
|
|
|
+ * the same reason, but ironically when the VFS moved from
|
|
|
+ * "dnotify" to "inotify" it became harder to plug in Linux
|
|
|
+ * network file system clients (the most obvious use case
|
|
|
+ * for notify interfaces is when multiple users can update
|
|
|
+ * the contents of the same directory - exactly what network
|
|
|
+ * file systems can do) although the server (Samba) could
|
|
|
+ * still use it. For the short term we leave the worker
|
|
|
+ * function ifdeffed out (below) until inotify is fixed
|
|
|
+ * in the VFS to make it easier to plug in network file
|
|
|
+ * system clients. If inotify turns out to be permanently
|
|
|
+ * incompatible for network fs clients, we could instead simply
|
|
|
+ * expose this config flag by adding a future cifs (and smb2) notify ioctl.
|
|
|
+ */
|
|
|
+int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
|
|
|
+ const int notify_subdirs, const __u16 netfid,
|
|
|
+ __u32 filter, struct file *pfile, int multishot,
|
|
|
+ const struct nls_table *nls_codepage)
|
|
|
+{
|
|
|
+ int rc = 0;
|
|
|
+ struct smb_com_transaction_change_notify_req *pSMB = NULL;
|
|
|
+ struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
|
|
|
+ struct dir_notify_req *dnotify_req;
|
|
|
+ int bytes_returned;
|
|
|
+
|
|
|
+ cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
|
|
|
+ rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
|
|
|
+ (void **) &pSMBr);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ pSMB->TotalParameterCount = 0 ;
|
|
|
+ pSMB->TotalDataCount = 0;
|
|
|
+ pSMB->MaxParameterCount = cpu_to_le32(2);
|
|
|
+ /* BB find exact data count max from sess structure BB */
|
|
|
+ pSMB->MaxDataCount = 0; /* same in little endian or be */
|
|
|
+/* BB VERIFY verify which is correct for above BB */
|
|
|
+ pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
|
|
|
+ MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
|
|
|
+
|
|
|
+ pSMB->MaxSetupCount = 4;
|
|
|
+ pSMB->Reserved = 0;
|
|
|
+ pSMB->ParameterOffset = 0;
|
|
|
+ pSMB->DataCount = 0;
|
|
|
+ pSMB->DataOffset = 0;
|
|
|
+ pSMB->SetupCount = 4; /* single byte does not need le conversion */
|
|
|
+ pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
|
|
|
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
|
|
|
+ if (notify_subdirs)
|
|
|
+ pSMB->WatchTree = 1; /* one byte - no le conversion needed */
|
|
|
+ pSMB->Reserved2 = 0;
|
|
|
+ pSMB->CompletionFilter = cpu_to_le32(filter);
|
|
|
+ pSMB->Fid = netfid; /* file handle always le */
|
|
|
+ pSMB->ByteCount = 0;
|
|
|
+
|
|
|
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
|
|
+ (struct smb_hdr *)pSMBr, &bytes_returned,
|
|
|
+ CIFS_ASYNC_OP);
|
|
|
+ if (rc) {
|
|
|
+ cFYI(1, "Error in Notify = %d", rc);
|
|
|
+ } else {
|
|
|
+ /* Add file to outstanding requests */
|
|
|
+ /* BB change to kmem cache alloc */
|
|
|
+ dnotify_req = kmalloc(
|
|
|
+ sizeof(struct dir_notify_req),
|
|
|
+ GFP_KERNEL);
|
|
|
+ if (dnotify_req) {
|
|
|
+ dnotify_req->Pid = pSMB->hdr.Pid;
|
|
|
+ dnotify_req->PidHigh = pSMB->hdr.PidHigh;
|
|
|
+ dnotify_req->Mid = pSMB->hdr.Mid;
|
|
|
+ dnotify_req->Tid = pSMB->hdr.Tid;
|
|
|
+ dnotify_req->Uid = pSMB->hdr.Uid;
|
|
|
+ dnotify_req->netfid = netfid;
|
|
|
+ dnotify_req->pfile = pfile;
|
|
|
+ dnotify_req->filter = filter;
|
|
|
+ dnotify_req->multishot = multishot;
|
|
|
+ spin_lock(&GlobalMid_Lock);
|
|
|
+ list_add_tail(&dnotify_req->lhead,
|
|
|
+ &GlobalDnotifyReqList);
|
|
|
+ spin_unlock(&GlobalMid_Lock);
|
|
|
+ } else
|
|
|
+ rc = -ENOMEM;
|
|
|
+ }
|
|
|
+ cifs_buf_release(pSMB);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
|