r12634: make the [validate] binding string switch also check to see if the
authorAndrew Tridgell <tridge@samba.org>
Sat, 31 Dec 2005 04:29:34 +0000 (04:29 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:49:10 +0000 (13:49 -0500)
string form of the structure we receive matches the generated
form. This has the effect of checking things like value() attributes.
(This used to be commit f2e68ec649658976e5bf4887713a92c14850c277)

source4/librpc/ndr/ndr.c
source4/librpc/rpc/dcerpc.c

index 260d44587089566573c7c7489b9bc8dc02afe83d..26190b199e5665a51899daaae7831110c905fc53 100644 (file)
@@ -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 */
index 0269eb9919a3b54c215ff86cdf39cfeda641cd2c..796511ef002cae9293b91c059273e19b2df08e19 100644 (file)
@@ -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);