diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-04 02:28:08 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-04 02:28:08 +0000 |
commit | 994301bfec372f0b929a61425fc1eb180d16cbb1 (patch) | |
tree | 21e43de4ef765bbbcf28fbc2f8ca02c6cd86a572 /source4/libcli/rpc | |
parent | 0a427a43c4464c05bdceb662fd6d3895790ea581 (diff) | |
download | samba-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.c | 52 |
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; |