compound_related = true;
}
} else if (idx > 4) {
+#if 0
+ /*
+ * It seems the this tests are wrong
+ * see the SMB2-COMPOUND test
+ */
+
/*
* all other requests should match the 2nd one
*/
return NT_STATUS_OK;
}
}
+#endif
}
}
for (idx=1; idx < count; idx += 3) {
const uint8_t *inhdr = NULL;
+ uint32_t in_flags;
uint8_t *outhdr = NULL;
uint8_t *outbody = NULL;
uint32_t next_command_ofs = 0;
}
inhdr = (const uint8_t *)req->in.vector[idx].iov_base;
+ in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
outhdr = talloc_array(vector, uint8_t,
SMB2_HDR_BODY + 8);
SVAL(inhdr, SMB2_HDR_OPCODE));
/* Make up a number for now... JRA. FIXME ! FIXME !*/
SSVAL(outhdr, SMB2_HDR_CREDIT, 20);
- SIVAL(outhdr, SMB2_HDR_FLAGS, SMB2_HDR_FLAG_REDIRECT);
+ SIVAL(outhdr, SMB2_HDR_FLAGS,
+ IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
}
- /*
- * This check is mostly for giving the correct error code
- * for compounded requests.
- *
- * TODO: we may need to move this after the session and tcon checks.
- */
- if (!NT_STATUS_IS_OK(req->next_status)) {
- return smbd_smb2_request_error(req, req->next_status);
+ if (flags & SMB2_HDR_FLAG_CHAINED) {
+ /*
+ * This check is mostly for giving the correct error code
+ * for compounded requests.
+ *
+ * TODO: we may need to move this after the session
+ * and tcon checks.
+ */
+ if (!NT_STATUS_IS_OK(req->next_status)) {
+ return smbd_smb2_request_error(req, req->next_status);
+ }
+ } else {
+ req->compat_chain_fsp = NULL;
}
switch (opcode) {
next_command_ofs += req->out.vector[i+2].iov_len;
}
- /* TODO: we need to add padding ... */
if ((next_command_ofs % 8) != 0) {
- return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
+ size_t pad_size = 8 - (next_command_ofs % 8);
+ if (req->out.vector[i+2].iov_len == 0) {
+ /*
+ * if the dyn buffer is empty
+ * we can use it to add padding
+ */
+ uint8_t *pad;
+
+ pad = talloc_zero_array(req->out.vector,
+ uint8_t, pad_size);
+ if (pad == NULL) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_NO_MEMORY);
+ }
+
+ req->out.vector[i+2].iov_base = (void *)pad;
+ req->out.vector[i+2].iov_len = pad_size;
+ } else {
+ /*
+ * For now we copy the dynamic buffer
+ * and add the padding to the new buffer
+ */
+ size_t old_size;
+ uint8_t *old_dyn;
+ size_t new_size;
+ uint8_t *new_dyn;
+
+ old_size = req->out.vector[i+2].iov_len;
+ old_dyn = (uint8_t *)req->out.vector[i+2].iov_base;
+
+ new_size = old_size + pad_size;
+ new_dyn = talloc_array(req->out.vector,
+ uint8_t, new_size);
+ if (new_dyn == NULL) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_NO_MEMORY);
+ }
+
+ memcpy(new_dyn, old_dyn, old_size);
+ memset(new_dyn + old_size, 0, pad_size);
+
+ req->out.vector[i+2].iov_base = (void *)new_dyn;
+ req->out.vector[i+2].iov_len = new_size;
+
+ TALLOC_FREE(old_dyn);
+ }
+ next_command_ofs += pad_size;
}
SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);