summaryrefslogtreecommitdiff
path: root/librpc/tools
diff options
context:
space:
mode:
authorGary Lockyer <gary@catalyst.net.nz>2019-06-05 08:44:09 +1200
committerAndrew Bartlett <abartlet@samba.org>2019-06-06 03:30:18 +0000
commit3bf05fbfd7106f46b35ee027f57be4c6af72f22e (patch)
treea5def414d7e6517f76299b3cacb38d2a47b19367 /librpc/tools
parent5d67e87d1c4504593f5da712f00de85371f8942f (diff)
downloadsamba-3bf05fbfd7106f46b35ee027f57be4c6af72f22e.tar.gz
ndrdump: print public structures
Add a struct option to ndrdump that will allow it to print public structures. i.e. binn/ndrdump dns dns_name_packet struct data.file Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org> Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org> Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'librpc/tools')
-rw-r--r--librpc/tools/ndrdump.1.xml15
-rw-r--r--librpc/tools/ndrdump.c98
2 files changed, 88 insertions, 25 deletions
diff --git a/librpc/tools/ndrdump.1.xml b/librpc/tools/ndrdump.1.xml
index e148eee0f03..fa6d763d18f 100644
--- a/librpc/tools/ndrdump.1.xml
+++ b/librpc/tools/ndrdump.1.xml
@@ -21,8 +21,8 @@
<command>ndrdump</command>
<arg choice="opt">-c context</arg>
<arg choice="req">pipe</arg>
- <arg choice="req">function</arg>
- <arg choice="req">in|out</arg>
+ <arg choice="req">format</arg>
+ <arg choice="req">in|out|struct</arg>
<arg choice="req">filename</arg>
</cmdsynopsis>
<cmdsynopsis>
@@ -38,15 +38,18 @@
<title>DESCRIPTION</title>
<para>ndrdump tries to parse the specified <replaceable>filename</replaceable>
- using Samba's parser for the specified pipe and function. The
+ using Samba's parser for the specified pipe and format. The
third argument should be
- either <emphasis>in</emphasis> or <emphasis>out</emphasis>, depending
- on whether the data should be parsed as a request or a reply.</para>
+ either <emphasis>in</emphasis>, <emphasis>out</emphasis>
+ or <emphasis>struct</emphasis>depending
+ on whether the data should be parsed as a request, reply or a
+ public structure.</para>
<para>Running ndrdump without arguments will list the pipes for which
parsers are available.</para>
- <para>Running ndrdump with one argument will list the functions that
+ <para>Running ndrdump with one argument will list the functions and
+ public structures that
Samba can parse for the specified pipe.</para>
<para>The primary function of ndrdump is debugging Samba's internal
diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c
index ef7f9c66139..bd4f277607b 100644
--- a/librpc/tools/ndrdump.c
+++ b/librpc/tools/ndrdump.c
@@ -48,6 +48,35 @@ static const struct ndr_interface_call *find_function(
return &p->calls[i];
}
+/*
+ * Find a public structure on the pipe and return it as if it were
+ * a function (as the rest of ndrdump is based around functions)
+ */
+static const struct ndr_interface_call *find_struct(
+ const struct ndr_interface_table *p,
+ const char *struct_name,
+ struct ndr_interface_call *out_buffer)
+{
+ int i;
+ for (i=0;i<p->num_public_structs;i++) {
+ if (strcmp(p->public_structs[i].name, struct_name) == 0) {
+ break;
+ }
+ }
+ if (i == p->num_public_structs) {
+ printf("Public structure '%s' not found\n", struct_name);
+ exit(1);
+ }
+ *out_buffer = (struct ndr_interface_call) {
+ .name = p->public_structs[i].name,
+ .struct_size = p->public_structs[i].struct_size,
+ .ndr_pull = p->public_structs[i].ndr_pull,
+ .ndr_push = p->public_structs[i].ndr_push,
+ .ndr_print = p->public_structs[i].ndr_print
+ };
+ return out_buffer;
+}
+
_NORETURN_ static void show_pipes(void)
{
const struct ndr_interface_list *l;
@@ -71,6 +100,10 @@ _NORETURN_ static void show_functions(const struct ndr_interface_table *p)
for (i=0;i<p->num_calls;i++) {
printf("\t0x%02x (%2d) %s\n", i, i, p->calls[i].name);
}
+ printf("known public structures on '%s' are:\n", p->name);
+ for (i=0;i<p->num_public_structs;i++) {
+ printf("\t%s\n", p->public_structs[i].name);
+ }
exit(1);
}
@@ -194,7 +227,21 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
{
const struct ndr_interface_table *p = NULL;
const struct ndr_interface_call *f;
- const char *pipe_name, *function, *inout, *filename;
+ struct ndr_interface_call f_buffer;
+ const char *pipe_name = NULL;
+ const char *filename = NULL;
+ /*
+ * The format type:
+ * in: a request
+ * out: a response
+ * struct: a public structure
+ */
+ const char *type = NULL;
+ /*
+ * Format is either the name of the decoding function or the
+ * name of a public structure
+ */
+ const char *format = NULL;
uint8_t *data;
size_t size;
DATA_BLOB blob;
@@ -244,7 +291,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
pc = poptGetContext("ndrdump", argc, argv, long_options, 0);
poptSetOtherOptionHelp(
- pc, "<pipe|uuid> <function> <inout> [<filename>]");
+ pc, "<pipe|uuid> <format> <in|out|struct> [<filename>]");
while ((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
@@ -302,29 +349,34 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
exit(1);
}
- function = poptGetArg(pc);
- inout = poptGetArg(pc);
+ format = poptGetArg(pc);
+ type = poptGetArg(pc);
filename = poptGetArg(pc);
- if (!function || !inout) {
+ if (!format || !type) {
poptPrintUsage(pc, stderr, 0);
show_functions(p);
exit(1);
}
- f = find_function(p, function);
-
- if (strcmp(inout, "in") == 0 ||
- strcmp(inout, "request") == 0) {
- flags |= NDR_IN;
- } else if (strcmp(inout, "out") == 0 ||
- strcmp(inout, "response") == 0) {
- flags |= NDR_OUT;
+ if (strcmp(type, "struct") == 0) {
+ flags = 0; /* neither NDR_IN nor NDR_OUT */
+ f = find_struct(p, format, &f_buffer);
} else {
- printf("Bad inout value '%s'\n", inout);
- exit(1);
+ f = find_function(p, format);
+ if (strcmp(type, "in") == 0 ||
+ strcmp(type, "request") == 0) {
+ flags |= NDR_IN;
+ } else if (strcmp(type, "out") == 0 ||
+ strcmp(type, "response") == 0) {
+ flags |= NDR_OUT;
+ } else {
+ printf("Bad type value '%s'\n", type);
+ exit(1);
+ }
}
+
mem_ctx = talloc_init("ndrdump");
st = talloc_zero_size(mem_ctx, f->struct_size);
@@ -442,7 +494,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
TALLOC_FREE(sec_vt);
if (flags & NDR_OUT) {
- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->out_pipes);
+ status = ndrdump_pull_and_print_pipes(format,
+ ndr_pull,
+ ndr_print,
+ &f->out_pipes);
if (!NT_STATUS_IS_OK(status)) {
printf("dump FAILED\n");
exit(1);
@@ -472,7 +527,7 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
ndrdump_data(blob.data, blob.length, dumpdata);
}
- f->ndr_print(ndr_print, function, flags, st);
+ f->ndr_print(ndr_print, format, flags, st);
if (!NT_STATUS_IS_OK(status)) {
printf("dump FAILED\n");
@@ -480,7 +535,10 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
}
if (flags & NDR_IN) {
- status = ndrdump_pull_and_print_pipes(function, ndr_pull, ndr_print, &f->in_pipes);
+ status = ndrdump_pull_and_print_pipes(format,
+ ndr_pull,
+ ndr_print,
+ &f->in_pipes);
if (!NT_STATUS_IS_OK(status)) {
printf("dump FAILED\n");
exit(1);
@@ -554,7 +612,9 @@ static void ndr_print_dummy(struct ndr_print *ndr, const char *format, ...)
ndr_v_print = talloc_zero(mem_ctx, struct ndr_print);
ndr_v_print->print = ndr_print_debug_helper;
ndr_v_print->depth = 1;
- f->ndr_print(ndr_v_print, function, flags, v_st);
+ f->ndr_print(ndr_v_print,
+ format,
+ flags, v_st);
if (blob.length != v_blob.length) {
printf("WARNING! orig bytes:%llu validated pushed bytes:%llu\n",