From 994301bfec372f0b929a61425fc1eb180d16cbb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Nov 2003 02:28:08 +0000 Subject: 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) --- source4/libcli/rpc/dcerpc.c | 52 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'source4/libcli/rpc/dcerpc.c') 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; -- cgit