diff options
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/ndr/libndr.h | 4 | ||||
-rw-r--r-- | source4/libcli/rpc/dcerpc.c | 55 | ||||
-rw-r--r-- | source4/libcli/rpc/rpc_echo.c | 39 |
3 files changed, 66 insertions, 32 deletions
diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h index d9d18299ab..0205a64552 100644 --- a/source4/libcli/ndr/libndr.h +++ b/source4/libcli/ndr/libndr.h @@ -84,6 +84,10 @@ struct ndr_push { } \ } while (0) +/* these are used when generic fn pointers are needed for ndr push/pull fns */ +typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *); +typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *); + /* now pull in the individual parsers */ #include "libcli/ndr/ndr_sec.h" #include "libcli/ndr/ndr_echo.h" diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c index 3f95bd914c..7980b77757 100644 --- a/source4/libcli/rpc/dcerpc.c +++ b/source4/libcli/rpc/dcerpc.c @@ -656,3 +656,58 @@ NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p, return status; } + + +/* + a useful helper function for synchronous rpc requests +*/ +NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, + uint32 opnum, + TALLOC_CTX *mem_ctx, + NTSTATUS (*ndr_push)(struct ndr_push *, void *), + NTSTATUS (*ndr_pull)(struct ndr_pull *, void *), + void *struct_ptr) +{ + struct ndr_push *push; + struct ndr_pull *pull; + NTSTATUS status; + DATA_BLOB request, response; + + /* setup for a ndr_push_* call */ + push = ndr_push_init(); + if (!push) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + /* push the structure into a blob */ + status = ndr_push_rpcecho_addone(push, struct_ptr); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + /* retrieve the blob */ + request = ndr_push_blob(push); + + /* make the actual dcerpc request */ + status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + /* prepare for ndr_pull_* */ + pull = ndr_pull_init_blob(&response, mem_ctx); + if (!pull) { + goto failed; + } + + /* pull the structure from the blob */ + status = ndr_pull_rpcecho_addone(pull, struct_ptr); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + +failed: + ndr_push_free(push); + return status; +} diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c index d2b2227823..c3075ecedc 100644 --- a/source4/libcli/rpc/rpc_echo.c +++ b/source4/libcli/rpc/rpc_echo.c @@ -30,50 +30,25 @@ NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, { struct rpcecho_addone r; NTSTATUS status; - DATA_BLOB request, response; TALLOC_CTX *mem_ctx; - struct ndr_push *push; - struct ndr_pull *pull; mem_ctx = talloc_init("dcerpc_rpcecho_addone"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } - push = ndr_push_init(); - if (!push) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - + /* fill the .in side of the call */ r.in.data = in_data; - status = ndr_push_rpcecho_addone(push, &r); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - request = ndr_push_blob(push); - - status = cli_dcerpc_request(p, RPCECHO_CALL_ADDONE, mem_ctx, &request, &response); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - pull = ndr_pull_init_blob(&response, mem_ctx); - if (!pull) { - goto failed; - } - - status = ndr_pull_rpcecho_addone(pull, &r); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } + /* make the call */ + status = dcerpc_ndr_request(p, RPCECHO_CALL_ADDONE, mem_ctx, + (ndr_push_fn_t) ndr_push_rpcecho_addone, + (ndr_pull_fn_t) ndr_pull_rpcecho_addone, + &r); + /* and extract the .out parameters */ *out_data = r.out.data; -failed: - ndr_push_free(push); talloc_destroy(mem_ctx); return status; } |