diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-10-13 15:58:45 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-10-13 15:58:45 +0200 |
commit | 2fddd2e2d5fb32ff15a170acc443218481986b91 (patch) | |
tree | ffc988ebf2fc876afc754830f1a8595d4b1f3d66 /source4 | |
parent | 6d02f0805a001ae4ac19219c7fff5247e470b0fd (diff) | |
download | samba-2fddd2e2d5fb32ff15a170acc443218481986b91.tar.gz samba-2fddd2e2d5fb32ff15a170acc443218481986b91.tar.bz2 samba-2fddd2e2d5fb32ff15a170acc443218481986b91.zip |
Share ndrdump implementation.
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/config.mk | 4 | ||||
-rw-r--r-- | source4/librpc/tools/ndrdump.1.xml | 83 | ||||
-rw-r--r-- | source4/librpc/tools/ndrdump.c | 459 |
3 files changed, 2 insertions, 544 deletions
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 4e1ccbb1a7..a481b97a11 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -36,9 +36,9 @@ PRIVATE_DEPENDENCIES = \ # End BINARY ndrdump ################################# -ndrdump_OBJ_FILES = $(librpcsrcdir)/tools/ndrdump.o +ndrdump_OBJ_FILES = ../librpc/tools/ndrdump.o -MANPAGES += $(librpcsrcdir)/tools/ndrdump.1 +MANPAGES += ../librpc/tools/ndrdump.1 ################################################ # Start SUBSYSTEM NDR_COMPRESSION diff --git a/source4/librpc/tools/ndrdump.1.xml b/source4/librpc/tools/ndrdump.1.xml deleted file mode 100644 index 9d66102682..0000000000 --- a/source4/librpc/tools/ndrdump.1.xml +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> -<refentry id="ndrdump.1"> - -<refmeta> - <refentrytitle>ndrdump</refentrytitle> - <manvolnum>1</manvolnum> -</refmeta> - - -<refnamediv> - <refname>ndrdump</refname> - <refpurpose>DCE/RPC Packet Parser and Dumper</refpurpose> -</refnamediv> - -<refsynopsisdiv> - <cmdsynopsis> - <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">filename</arg> - </cmdsynopsis> - <cmdsynopsis> - <command>ndrdump</command> - <arg choice="opt">pipe</arg> - </cmdsynopsis> - <cmdsynopsis> - <command>ndrdump</command> - </cmdsynopsis> -</refsynopsisdiv> - -<refsect1> - <title>DESCRIPTION</title> - - <para>ndrdump tries to parse the specified <replaceable>filename</replaceable> - using Samba's parser for the specified pipe and function. 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> - - <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 - Samba can parse for the specified pipe.</para> - - <para>The primary function of ndrdump is debugging Samba's internal - DCE/RPC parsing functions. The file being parsed is usually - one exported by wiresharks <quote>Export selected packet bytes</quote> - function.</para> - - <para>The context argument can be used to load context data from the request - packet when parsing reply packets (such as array lengths).</para> - -</refsect1> - -<refsect1> - <title>VERSION</title> - - <para>This man page is correct for version 4.0 of the Samba suite.</para> -</refsect1> - -<refsect1> - <title>SEE ALSO</title> - - <para>wireshark, pidl</para> - -</refsect1> - -<refsect1> - <title>AUTHOR</title> - - <para>This utility is part of the <ulink url="http://www.samba.org/">Samba</ulink> suite, which is developed by the global <ulink url="http://www.samba.org/samba/team/">Samba Team</ulink>.</para> - - <para>ndrdump was written by Andrew Tridgell. </para> - - <para>This manpage was written by Jelmer Vernooij. </para> - -</refsect1> - -</refentry> diff --git a/source4/librpc/tools/ndrdump.c b/source4/librpc/tools/ndrdump.c deleted file mode 100644 index b24868eace..0000000000 --- a/source4/librpc/tools/ndrdump.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB torture tester - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Jelmer Vernooij 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#if (_SAMBA_BUILD_ >= 4) -#include "lib/cmdline/popt_common.h" -#include "system/filesys.h" -#include "system/locale.h" -#include "librpc/ndr/libndr.h" -#include "librpc/ndr/ndr_table.h" -#include "param/param.h" -#endif - -static const struct ndr_interface_call *find_function( - const struct ndr_interface_table *p, - const char *function) -{ - int i; - if (isdigit(function[0])) { - i = strtol(function, NULL, 0); - return &p->calls[i]; - } - for (i=0;i<p->num_calls;i++) { - if (strcmp(p->calls[i].name, function) == 0) { - break; - } - } - if (i == p->num_calls) { - printf("Function '%s' not found\n", function); - exit(1); - } - return &p->calls[i]; -} - -#if (_SAMBA_BUILD_ >= 4) - -_NORETURN_ static void show_pipes(void) -{ - const struct ndr_interface_list *l; - printf("\nYou must specify a pipe\n"); - printf("known pipes are:\n"); - for (l=ndr_table_list();l;l=l->next) { - if(l->table->helpstring) { - printf("\t%s - %s\n", l->table->name, l->table->helpstring); - } else { - printf("\t%s\n", l->table->name); - } - } - exit(1); -} - -#endif - -_NORETURN_ static void show_functions(const struct ndr_interface_table *p) -{ - int i; - printf("\nYou must specify a function\n"); - printf("known functions on '%s' are:\n", p->name); - for (i=0;i<p->num_calls;i++) { - printf("\t0x%02x (%2d) %s\n", i, i, p->calls[i].name); - } - exit(1); -} - -static char *stdin_load(TALLOC_CTX *mem_ctx, size_t *size) -{ - int num_read, total_len = 0; - char buf[255]; - char *result = NULL; - - while((num_read = read(STDIN_FILENO, buf, 255)) > 0) { - - if (result) { - result = talloc_realloc( - mem_ctx, result, char, total_len + num_read); - } else { - result = talloc_array(mem_ctx, char, num_read); - } - - memcpy(result + total_len, buf, num_read); - - total_len += num_read; - } - - if (size) - *size = total_len; - - return result; -} - -static const struct ndr_interface_table *load_iface_from_plugin(const char *plugin, const char *pipe_name) -{ - const struct ndr_interface_table *p; - void *handle; - char *symbol; - - handle = dlopen(plugin, RTLD_NOW); - if (handle == NULL) { - printf("%s: Unable to open: %s\n", plugin, dlerror()); - return NULL; - } - - symbol = talloc_asprintf(NULL, "ndr_table_%s", pipe_name); - p = (const struct ndr_interface_table *)dlsym(handle, symbol); - - if (!p) { - printf("%s: Unable to find DCE/RPC interface table for '%s': %s\n", plugin, pipe_name, dlerror()); - talloc_free(symbol); - return NULL; - } - - talloc_free(symbol); - - return p; -} - -static void ndrdump_data(uint8_t *d, uint32_t l, bool force) -{ - if (force) { - dump_data(0, d, l); - } else { - dump_data_skip_zeros(0, d, l); - } -} - - int main(int argc, const char *argv[]) -{ - const struct ndr_interface_table *p = NULL; - const struct ndr_interface_call *f; - const char *pipe_name, *function, *inout, *filename; - uint8_t *data; - size_t size; - DATA_BLOB blob; - struct ndr_pull *ndr_pull; - struct ndr_print *ndr_print; - TALLOC_CTX *mem_ctx; - int flags; - poptContext pc; - NTSTATUS status; - enum ndr_err_code ndr_err; - void *st; - void *v_st; - const char *ctx_filename = NULL; - const char *plugin = NULL; - bool validate = false; - bool dumpdata = false; - int opt; - enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO}; - struct poptOption long_options[] = { - POPT_AUTOHELP - {"context-file", 'c', POPT_ARG_STRING, NULL, OPT_CONTEXT_FILE, "In-filename to parse first", "CTX-FILE" }, - {"validate", 0, POPT_ARG_NONE, NULL, OPT_VALIDATE, "try to validate the data", NULL }, - {"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMP_DATA, "dump the hex data", NULL }, - {"load-dso", 'l', POPT_ARG_STRING, NULL, OPT_LOAD_DSO, "load from shared object file", NULL }, - POPT_COMMON_SAMBA - POPT_COMMON_VERSION - { NULL } - }; - -#if (_SAMBA_BUILD_ >= 4) - ndr_table_init(); -#else - /* Initialise samba stuff */ - load_case_tables(); - - setlinebuf(stdout); - - dbf = x_stderr; - - setup_logging(argv[0],True); -#endif - - pc = poptGetContext("ndrdump", argc, argv, long_options, 0); - - poptSetOtherOptionHelp( - pc, "<pipe|uuid> <function> <inout> [<filename>]"); - - while ((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case OPT_CONTEXT_FILE: - ctx_filename = poptGetOptArg(pc); - break; - case OPT_VALIDATE: - validate = true; - break; - case OPT_DUMP_DATA: - dumpdata = true; - break; - case OPT_LOAD_DSO: - plugin = poptGetOptArg(pc); - break; - } - } - - pipe_name = poptGetArg(pc); - - if (!pipe_name) { - poptPrintUsage(pc, stderr, 0); -#if (_SAMBA_BUILD_ >= 4) - show_pipes(); -#endif - exit(1); - } - - if (plugin != NULL) { - p = load_iface_from_plugin(plugin, pipe_name); - } -#if (_SAMBA_BUILD_ <= 3) - else { - fprintf(stderr, "Only loading from DSO's supported in Samba 3\n"); - exit(1); - } -#else - if (!p) { - p = ndr_table_by_name(pipe_name); - } - - if (!p) { - struct GUID uuid; - - status = GUID_from_string(pipe_name, &uuid); - - if (NT_STATUS_IS_OK(status)) { - p = ndr_table_by_uuid(&uuid); - } - } -#endif - - if (!p) { - printf("Unknown pipe or UUID '%s'\n", pipe_name); - exit(1); - } - - function = poptGetArg(pc); - inout = poptGetArg(pc); - filename = poptGetArg(pc); - - if (!function || !inout) { - poptPrintUsage(pc, stderr, 0); - show_functions(p); - exit(1); - } - - 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; - } 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); - if (!st) { - printf("Unable to allocate %d bytes\n", (int)f->struct_size); - exit(1); - } - - v_st = talloc_zero_size(mem_ctx, f->struct_size); - if (!v_st) { - printf("Unable to allocate %d bytes\n", (int)f->struct_size); - exit(1); - } - - if (ctx_filename) { - if (flags == NDR_IN) { - printf("Context file can only be used for \"out\" packages\n"); - exit(1); - } - - data = (uint8_t *)file_load(ctx_filename, &size, 0, mem_ctx); - if (!data) { - perror(ctx_filename); - exit(1); - } - - blob.data = data; - blob.length = size; - - ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); - ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; - - ndr_err = f->ndr_pull(ndr_pull, NDR_IN, st); - - if (ndr_pull->offset != ndr_pull->data_size) { - printf("WARNING! %d unread bytes while parsing context file\n", ndr_pull->data_size - ndr_pull->offset); - } - - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - status = ndr_map_error2ntstatus(ndr_err); - printf("pull for context file returned %s\n", nt_errstr(status)); - exit(1); - } - memcpy(v_st, st, f->struct_size); - } - - if (filename) - data = (uint8_t *)file_load(filename, &size, 0, mem_ctx); - else - data = (uint8_t *)stdin_load(mem_ctx, &size); - - if (!data) { - if (filename) - perror(filename); - else - perror("stdin"); - exit(1); - } - - blob.data = data; - blob.length = size; - - ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); - ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; - - ndr_err = f->ndr_pull(ndr_pull, flags, st); - status = ndr_map_error2ntstatus(ndr_err); - - printf("pull returned %s\n", nt_errstr(status)); - - if (ndr_pull->offset != ndr_pull->data_size) { - printf("WARNING! %d unread bytes\n", ndr_pull->data_size - ndr_pull->offset); - ndrdump_data(ndr_pull->data+ndr_pull->offset, - ndr_pull->data_size - ndr_pull->offset, - dumpdata); - } - - if (dumpdata) { - printf("%d bytes consumed\n", ndr_pull->offset); - ndrdump_data(blob.data, blob.length, dumpdata); - } - - ndr_print = talloc_zero(mem_ctx, struct ndr_print); - ndr_print->print = ndr_print_debug_helper; - ndr_print->depth = 1; - f->ndr_print(ndr_print, function, flags, st); - - if (!NT_STATUS_IS_OK(status)) { - printf("dump FAILED\n"); - exit(1); - } - - if (validate) { - DATA_BLOB v_blob; - struct ndr_push *ndr_v_push; - struct ndr_pull *ndr_v_pull; - struct ndr_print *ndr_v_print; - uint32_t i; - uint8_t byte_a, byte_b; - bool differ; - - ndr_v_push = ndr_push_init_ctx(mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); - - ndr_err = f->ndr_push(ndr_v_push, flags, st); - status = ndr_map_error2ntstatus(ndr_err); - printf("push returned %s\n", nt_errstr(status)); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - printf("validate push FAILED\n"); - exit(1); - } - - v_blob = ndr_push_blob(ndr_v_push); - - if (dumpdata) { - printf("%ld bytes generated (validate)\n", (long)v_blob.length); - ndrdump_data(v_blob.data, v_blob.length, dumpdata); - } - - ndr_v_pull = ndr_pull_init_blob(&v_blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); - ndr_v_pull->flags |= LIBNDR_FLAG_REF_ALLOC; - - ndr_err = f->ndr_pull(ndr_v_pull, flags, v_st); - status = ndr_map_error2ntstatus(ndr_err); - printf("pull returned %s\n", nt_errstr(status)); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - printf("validate pull FAILED\n"); - exit(1); - } - - - if (ndr_v_pull->offset != ndr_v_pull->data_size) { - printf("WARNING! %d unread bytes in validation\n", ndr_v_pull->data_size - ndr_v_pull->offset); - ndrdump_data(ndr_v_pull->data+ndr_v_pull->offset, - ndr_v_pull->data_size - ndr_v_pull->offset, - dumpdata); - } - - 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); - - if (blob.length != v_blob.length) { - printf("WARNING! orig bytes:%llu validated pushed bytes:%llu\n", - (unsigned long long)blob.length, (unsigned long long)v_blob.length); - } - - if (ndr_pull->offset != ndr_v_pull->offset) { - printf("WARNING! orig pulled bytes:%llu validated pulled bytes:%llu\n", - (unsigned long long)ndr_pull->offset, (unsigned long long)ndr_v_pull->offset); - } - - differ = false; - byte_a = 0x00; - byte_b = 0x00; - for (i=0; i < blob.length; i++) { - byte_a = blob.data[i]; - - if (i == v_blob.length) { - byte_b = 0x00; - differ = true; - break; - } - - byte_b = v_blob.data[i]; - - if (byte_a != byte_b) { - differ = true; - break; - } - } - if (differ) { - printf("WARNING! orig and validated differ at byte 0x%02X (%u)\n", i, i); - printf("WARNING! orig byte[0x%02X] = 0x%02X validated byte[0x%02X] = 0x%02X\n", - i, byte_a, i, byte_b); - } - } - - printf("dump OK\n"); - - talloc_free(mem_ctx); - - poptFreeContext(pc); - - return 0; -} |