summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/ndr/libndr.h4
-rw-r--r--source4/libcli/rpc/dcerpc.c55
-rw-r--r--source4/libcli/rpc/rpc_echo.c39
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;
}