diff options
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/ndr/ndr_echo.c | 42 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_echo.h | 19 | ||||
-rw-r--r-- | source4/libcli/rpc/dcerpc.c | 2 | ||||
-rw-r--r-- | source4/libcli/rpc/rpc_echo.c | 52 |
4 files changed, 114 insertions, 1 deletions
diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c index 456b254f3a..a085a6534d 100644 --- a/source4/libcli/ndr/ndr_echo.c +++ b/source4/libcli/ndr/ndr_echo.c @@ -68,3 +68,45 @@ NTSTATUS ndr_push_rpcecho_echodata(struct ndr_push *ndr, NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); return NT_STATUS_OK; } + +/* + parse a sinkdata +*/ +NTSTATUS ndr_pull_rpcecho_sinkdata(struct ndr_pull *ndr, + struct rpcecho_sinkdata *r) +{ + return NT_STATUS_OK; +} + +/* + push a sinkdata +*/ +NTSTATUS ndr_push_rpcecho_sinkdata(struct ndr_push *ndr, + struct rpcecho_sinkdata *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len)); + return NT_STATUS_OK; +} + +/* + parse a sourcedata +*/ +NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr, + struct rpcecho_sourcedata *r) +{ + NDR_CHECK(ndr_pull_u32(ndr, &r->out.len)); + NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len)); + return NT_STATUS_OK; +} + +/* + push a sourcedata +*/ +NTSTATUS ndr_push_rpcecho_sourcedata(struct ndr_push *ndr, + struct rpcecho_sourcedata *r) +{ + NDR_CHECK(ndr_push_u32(ndr, r->in.len)); + return NT_STATUS_OK; +} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h index 4a8a4f5ab5..aecf68c4c0 100644 --- a/source4/libcli/ndr/ndr_echo.h +++ b/source4/libcli/ndr/ndr_echo.h @@ -47,6 +47,25 @@ struct rpcecho_echodata { } out; }; +/* SinkData interface */ +struct rpcecho_sinkdata { + struct { + int len; + char *data; + } in; +}; + +/* SourceData interface */ +struct rpcecho_sourcedata { + struct { + int len; + } in; + struct { + int len; + char *data; + } out; +}; + /* define the command codes */ enum { RPCECHO_CALL_ADDONE=0, diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 96a355c9e1..b620718755 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -199,7 +199,7 @@ static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, stub_len = blob->length - ((*offset) + hdr->auth_length); BLOB_CHECK_BOUNDS(blob, *offset, stub_len); pkt->stub_data = data_blob_talloc(mem_ctx, blob->data + (*offset), stub_len); - if (!pkt->stub_data.data) { + if (stub_len != 0 && !pkt->stub_data.data) { return NT_STATUS_NO_MEMORY; } (*offset) += stub_len; diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c index ab793a1ffa..d73f9bda9c 100644 --- a/source4/libcli/rpc/rpc_echo.c +++ b/source4/libcli/rpc/rpc_echo.c @@ -83,3 +83,55 @@ NTSTATUS dcerpc_rpcecho_echodata(struct dcerpc_pipe *p, return status; } + +/* + sourcedata interface +*/ +NTSTATUS dcerpc_rpcecho_sourcedata(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + int len, + int *out_len, + char **out_data) +{ + struct rpcecho_sourcedata r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.len = len; + + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_SOURCEDATA, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_sourcedata, + (ndr_pull_fn_t) ndr_pull_rpcecho_sourcedata, + &r); + + /* and extract the .out parameters */ + *out_len = r.out.len; + *out_data = r.out.data; + + return status; +} + +/* + sinkdata interface +*/ +NTSTATUS dcerpc_rpcecho_sinkdata(struct dcerpc_pipe *p, + TALLOC_CTX *mem_ctx, + int len, + char *data) +{ + struct rpcecho_sinkdata r; + NTSTATUS status; + + /* fill the .in side of the call */ + r.in.len = len; + r.in.data = data; + + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_SINKDATA, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_sinkdata, + (ndr_pull_fn_t) ndr_pull_rpcecho_sinkdata, + &r); + + return status; +} |