summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--source4/torture/rpc/echo.c43
4 files changed, 97 insertions, 44 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;
}
diff --git a/source4/torture/rpc/echo.c b/source4/torture/rpc/echo.c
index eee192e37a..5469854116 100644
--- a/source4/torture/rpc/echo.c
+++ b/source4/torture/rpc/echo.c
@@ -21,12 +21,36 @@
#include "includes.h"
+
+/*
+ test the AddOne interface
+*/
+static BOOL test_addone(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+ int i;
+ NTSTATUS status;
+
+ printf("\nTesting AddOne\n");
+
+ for (i=0;i<10;i++) {
+ int n;
+ status = dcerpc_rpcecho_addone(p, i, &n);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("AddOne(%d) failed - %s\n", i, nt_errstr(status));
+ return False;
+ }
+ printf("%d + 1 = %d\n", i, n);
+ }
+
+ return True;
+}
+
BOOL torture_rpc_echo(int dummy)
{
NTSTATUS status;
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
- int i;
+ BOOL ret = True;
mem_ctx = talloc_init("torture_rpc_echo");
@@ -34,18 +58,13 @@ BOOL torture_rpc_echo(int dummy)
if (!NT_STATUS_IS_OK(status)) {
return False;
}
-
- for (i=0;i<10;i++) {
- int n;
- status = dcerpc_rpcecho_addone(p, i, &n);
- if (!NT_STATUS_IS_OK(status)) {
- printf("AddOne(%d) failed - %s\n", i, nt_errstr(status));
- goto done;
- }
- printf("%d + 1 = %d\n", i, n);
+
+ if (!test_addone(p, mem_ctx)) {
+ ret = False;
}
-done:
+ printf("\n");
+
torture_rpc_close(p);
- return NT_STATUS_IS_OK(status);
+ return ret;
}