librpc/tools/ndrdump: add support for dcerpc 'pipe' elements in functions
authorStefan Metzmacher <metze@samba.org>
Tue, 21 Sep 2010 06:34:31 +0000 (08:34 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 10 Mar 2011 13:31:15 +0000 (14:31 +0100)
metze

librpc/tools/ndrdump.c

index f0f4eaff4e62d9910e78c8cf3310d6487cefa470..284dbcedf9c0dcea3f94d26bdd25691401a697d8 100644 (file)
@@ -137,6 +137,53 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
        dump_data_cb(d, l, !force, printf_cb, NULL);
 }
 
+static NTSTATUS ndrdump_pull_and_print_pipes(const char *function,
+                               struct ndr_pull *ndr_pull,
+                               struct ndr_print *ndr_print,
+                               const struct ndr_interface_call_pipes *pipes)
+{
+       NTSTATUS status;
+       enum ndr_err_code ndr_err;
+       uint32_t i;
+
+       for (i=0; i < pipes->num_pipes; i++) {
+               uint64_t idx = 0;
+               while (true) {
+                       uint32_t *count;
+                       void *c;
+                       char *n;
+
+                       c = talloc_zero_size(ndr_pull, pipes->pipes[i].chunk_struct_size);
+                       talloc_set_name(c, "struct %s", pipes->pipes[i].name);
+                       /*
+                        * Note: the first struct member is always
+                        * 'uint32_t count;'
+                        */
+                       count = (uint32_t *)c;
+
+                       n = talloc_asprintf(c, "%s: %s[%llu]",
+                                       function, pipes->pipes[i].name,
+                                       (unsigned long long)idx);
+
+                       ndr_err = pipes->pipes[i].ndr_pull(ndr_pull, NDR_SCALARS, c);
+                       status = ndr_map_error2ntstatus(ndr_err);
+
+                       printf("pull returned %s\n", nt_errstr(status));
+                       if (!NT_STATUS_IS_OK(status)) {
+                               return status;
+                       }
+                       pipes->pipes[i].ndr_print(ndr_print, n, c);
+
+                       if (*count == 0) {
+                               break;
+                       }
+                       idx++;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
  int main(int argc, const char *argv[])
 {
        const struct ndr_interface_table *p = NULL;
@@ -172,6 +219,8 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
                POPT_COMMON_VERSION
                { NULL }
        };
+       struct ndr_interface_call_pipes *in_pipes = NULL;
+       struct ndr_interface_call_pipes *out_pipes = NULL;
 
        ndr_table_init();
 
@@ -247,19 +296,21 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
                exit(1);
        }
 
+       f = find_function(p, function);
+
        if (strcmp(inout, "in") == 0 ||
            strcmp(inout, "request") == 0) {
                flags = NDR_IN;
+               in_pipes = &f->in_pipes;
        } else if (strcmp(inout, "out") == 0 ||
                   strcmp(inout, "response") == 0) {
                flags = NDR_OUT;
+               out_pipes = &f->out_pipes;
        } else {
                printf("Bad inout value '%s'\n", inout);
                exit(1);
        }
 
-       f = find_function(p, function);
-
        mem_ctx = talloc_init("ndrdump");
 
        st = talloc_zero_size(mem_ctx, f->struct_size);
@@ -331,6 +382,18 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
                ndr_pull->flags |= LIBNDR_FLAG_NDR64;
        }
 
+       ndr_print = talloc_zero(mem_ctx, struct ndr_print);
+       ndr_print->print = ndr_print_printf_helper;
+       ndr_print->depth = 1;
+
+       if (out_pipes) {
+               status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, out_pipes);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("dump FAILED\n");
+                       exit(1);
+               }
+       }
+
        ndr_err = f->ndr_pull(ndr_pull, flags, st);
        status = ndr_map_error2ntstatus(ndr_err);
 
@@ -348,9 +411,6 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
                ndrdump_data(blob.data, blob.length, dumpdata);
        }
 
-       ndr_print = talloc_zero(mem_ctx, struct ndr_print);
-       ndr_print->print = ndr_print_printf_helper;
-       ndr_print->depth = 1;
        f->ndr_print(ndr_print, function, flags, st);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -358,6 +418,14 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force)
                exit(1);
        }
 
+       if (in_pipes) {
+               status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, in_pipes);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("dump FAILED\n");
+                       exit(1);
+               }
+       }
+
        if (validate) {
                DATA_BLOB v_blob;
                struct ndr_push *ndr_v_push;