diff options
-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 | ||||
-rw-r--r-- | source4/torture/rpc/echo.c | 43 |
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; } |