diff options
-rw-r--r-- | source4/librpc/ndr/ndr.c | 36 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 20 |
2 files changed, 53 insertions, 3 deletions
diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 260d445870..26190b199e 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -199,6 +199,21 @@ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, ...) _PRI free(s); } +static void ndr_print_string_helper(struct ndr_print *ndr, const char *format, ...) _PRINTF_ATTRIBUTE(2,3) +{ + va_list ap; + int i; + + for (i=0;i<ndr->depth;i++) { + ndr->private = talloc_asprintf_append(ndr->private, " "); + } + + va_start(ap, format); + ndr->private = talloc_vasprintf_append(ndr->private, format, ap); + va_end(ap); + ndr->private = talloc_asprintf_append(ndr->private, "\n"); +} + /* a useful helper function for printing idl structures via DEBUG() */ @@ -248,6 +263,27 @@ void ndr_print_function_debug(ndr_print_function_t fn, const char *name, int fla talloc_free(ndr); } + +/* + a useful helper function for printing idl function calls to a string +*/ +char *ndr_print_function_string(TALLOC_CTX *mem_ctx, + ndr_print_function_t fn, const char *name, + int flags, void *ptr) +{ + struct ndr_print *ndr; + + ndr = talloc_zero(mem_ctx, struct ndr_print); + if (!ndr) return NULL; + ndr->private = talloc_strdup(mem_ctx, ""); + ndr->print = ndr_print_string_helper; + ndr->depth = 1; + ndr->flags = 0; + fn(ndr, name, flags, ptr); + talloc_free(ndr); + return ndr->private; +} + void ndr_set_flags(uint32_t *pflags, uint32_t new_flags) { /* the big/little endian flags are inter-dependent */ diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 0269eb9919..796511ef00 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -1216,17 +1216,20 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c, bug in either the pull or push side of our code */ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, - TALLOC_CTX *mem_ctx, + struct ndr_pull *pull_in, void *struct_ptr, size_t struct_size, ndr_push_flags_fn_t ndr_push, - ndr_pull_flags_fn_t ndr_pull) + ndr_pull_flags_fn_t ndr_pull, + ndr_print_function_t ndr_print) { void *st; struct ndr_pull *pull; struct ndr_push *push; NTSTATUS status; DATA_BLOB blob, blob2; + TALLOC_CTX *mem_ctx = pull_in; + char *s1, *s2; st = talloc_size(mem_ctx, struct_size); if (!st) { @@ -1285,6 +1288,16 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c, nt_errstr(status)); } + /* this checks the printed forms of the two structures, which effectively + tests all of the value() attributes */ + s1 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", + NDR_OUT, struct_ptr); + s2 = ndr_print_function_string(mem_ctx, ndr_print, "VALIDATE", + NDR_OUT, st); + if (strcmp(s1, s2) != 0) { + printf("VALIDATE ERROR:\nWIRE:\n%s\n GEN:\n%s\n", s1, s2); + } + return NT_STATUS_OK; } @@ -1415,7 +1428,8 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) if (p->conn->flags & DCERPC_DEBUG_VALIDATE_OUT) { status = dcerpc_ndr_validate_out(p->conn, pull, r, call->struct_size, - call->ndr_push, call->ndr_pull); + call->ndr_push, call->ndr_pull, + call->ndr_print); if (!NT_STATUS_IS_OK(status)) { dcerpc_log_packet(table, opnum, NDR_OUT, &response); |