summaryrefslogtreecommitdiff
path: root/source4/libcli/rpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-11-04 02:28:08 +0000
committerAndrew Tridgell <tridge@samba.org>2003-11-04 02:28:08 +0000
commit994301bfec372f0b929a61425fc1eb180d16cbb1 (patch)
tree21e43de4ef765bbbcf28fbc2f8ca02c6cd86a572 /source4/libcli/rpc
parent0a427a43c4464c05bdceb662fd6d3895790ea581 (diff)
downloadsamba-994301bfec372f0b929a61425fc1eb180d16cbb1.tar.gz
samba-994301bfec372f0b929a61425fc1eb180d16cbb1.tar.bz2
samba-994301bfec372f0b929a61425fc1eb180d16cbb1.zip
added fragmentation support on receive for dcerpc packets. I have
successfully used SourceData with 200M of data in rpcecho (This used to be commit a9aa7954fe84c925bb158af8b73aa71b7ea84e2b)
Diffstat (limited to 'source4/libcli/rpc')
-rw-r--r--source4/libcli/rpc/dcerpc.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c
index b620718755..d4f21f969a 100644
--- a/source4/libcli/rpc/dcerpc.c
+++ b/source4/libcli/rpc/dcerpc.c
@@ -620,7 +620,7 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p,
struct dcerpc_packet pkt;
NTSTATUS status;
- DATA_BLOB blob_in, blob_out;
+ DATA_BLOB blob_in, blob_out, payload;
init_dcerpc_hdr(&pkt.hdr);
@@ -647,11 +647,57 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p,
}
if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) {
- status = NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
+ /* something is badly wrong! */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ payload = pkt.out.response.stub_data;
+
+ /* continue receiving fragments */
+ while (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
+ uint32 length;
+
+ status = dcerpc_raw_packet_secondary(p, mem_ctx, &blob_out);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = dcerpc_pull(&blob_out, mem_ctx, &pkt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
+ /* start of another packet!? */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ length = pkt.out.response.stub_data.length;
+
+ payload.data = talloc_realloc(mem_ctx,
+ payload.data,
+ payload.length + length);
+ if (!payload.data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ memcpy(payload.data + payload.length,
+ pkt.out.response.stub_data.data,
+ length);
+
+ payload.length += length;
}
if (stub_data_out) {
- *stub_data_out = pkt.out.response.stub_data;
+ *stub_data_out = payload;
}
return status;