summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/ndr/ndr.c36
-rw-r--r--source4/librpc/rpc/dcerpc.c20
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);