diff options
-rw-r--r-- | librpc/ndr/libndr.h | 3 | ||||
-rw-r--r-- | librpc/ndr/ndr.c | 6 | ||||
-rw-r--r-- | librpc/ndr/ndr_basic.c | 24 | ||||
-rw-r--r-- | librpc/tools/ndrdump.c | 17 |
4 files changed, 44 insertions, 6 deletions
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h index d01b68ef51..1868af6104 100644 --- a/librpc/ndr/libndr.h +++ b/librpc/ndr/libndr.h @@ -141,6 +141,8 @@ struct ndr_print { /* used to check if alignment padding is zero */ #define LIBNDR_FLAG_PAD_CHECK (1<<28) +#define LIBNDR_FLAG_NDR64 (1<<29) + /* set if an object uuid will be present */ #define LIBNDR_FLAG_OBJECT_PRESENT (1<<30) @@ -465,6 +467,7 @@ NDR_SCALAR_PROTO(int8, int8_t) NDR_SCALAR_PROTO(uint16, uint16_t) NDR_SCALAR_PROTO(int16, int16_t) NDR_SCALAR_PROTO(uint32, uint32_t) +NDR_SCALAR_PROTO(uint3264, uint32_t) NDR_SCALAR_PROTO(int32, int32_t) NDR_SCALAR_PROTO(udlong, uint64_t) NDR_SCALAR_PROTO(udlongr, uint64_t) diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c index 2b3493b2e3..ef318d64d2 100644 --- a/librpc/ndr/ndr.c +++ b/librpc/ndr/ndr.c @@ -736,7 +736,7 @@ _PUBLIC_ uint32_t ndr_token_peek(struct ndr_token_list **list, const void *key) _PUBLIC_ enum ndr_err_code ndr_pull_array_size(struct ndr_pull *ndr, const void *p) { uint32_t size; - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size)); + NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &size)); return ndr_token_store(ndr, &ndr->array_size_list, p, size); } @@ -769,12 +769,12 @@ _PUBLIC_ enum ndr_err_code ndr_check_array_size(struct ndr_pull *ndr, void *p, u _PUBLIC_ enum ndr_err_code ndr_pull_array_length(struct ndr_pull *ndr, const void *p) { uint32_t length, offset; - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &offset)); + NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &offset)); if (offset != 0) { return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "non-zero array offset %u\n", offset); } - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length)); + NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, &length)); return ndr_token_store(ndr, &ndr->array_length_list, p, length); } diff --git a/librpc/ndr/ndr_basic.c b/librpc/ndr/ndr_basic.c index d46590f0cb..fad66687f7 100644 --- a/librpc/ndr/ndr_basic.c +++ b/librpc/ndr/ndr_basic.c @@ -118,6 +118,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, i */ _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v) { + uint32_t v2; NDR_PULL_ALIGN(ndr, 4); NDR_PULL_NEED_BYTES(ndr, 4); *v = NDR_IVAL(ndr, ndr->offset); @@ -126,6 +127,25 @@ _PUBLIC_ enum ndr_err_code ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, } /* + parse a arch dependent uint32/uint64 +*/ +_PUBLIC_ enum ndr_err_code ndr_pull_uint3264(struct ndr_pull *ndr, int ndr_flags, uint32_t *v) +{ + uint64_t v64; + enum ndr_err_code err; + if (!(ndr->flags & LIBNDR_FLAG_NDR64)) { + return ndr_pull_uint32(ndr, ndr_flags, v); + } + err = ndr_pull_hyper(ndr, ndr_flags, &v64); + *v = (uint32_t)v64; + if (v64 != *v) { + DEBUG(0,(__location__ ": non-zero upper 32 bits 0x%016llx\n", + (unsigned long long)v64)); + } + return err; +} + +/* parse a double */ _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, double *v) @@ -142,7 +162,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_double(struct ndr_pull *ndr, int ndr_flags, */ _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v) { - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v)); + NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v)); if (*v != 0) { ndr->ptr_count++; } @@ -154,7 +174,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t * */ _PUBLIC_ enum ndr_err_code ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v) { - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v)); + NDR_CHECK(ndr_pull_uint3264(ndr, NDR_SCALARS, v)); /* ref pointers always point to data */ *v = 1; return NDR_ERR_SUCCESS; diff --git a/librpc/tools/ndrdump.c b/librpc/tools/ndrdump.c index 7126d26c59..fbb0f3ab2a 100644 --- a/librpc/tools/ndrdump.c +++ b/librpc/tools/ndrdump.c @@ -157,19 +157,25 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force) const char *plugin = NULL; bool validate = false; bool dumpdata = false; + bool assume_ndr64 = false; int opt; - enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO}; + enum {OPT_CONTEXT_FILE=1000, OPT_VALIDATE, OPT_DUMP_DATA, OPT_LOAD_DSO, OPT_NDR64}; 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 }, + {"ndr64", 'l', POPT_ARG_NONE, NULL, OPT_NDR64, "Assume NDR64 data", NULL }, POPT_COMMON_SAMBA POPT_COMMON_VERSION { NULL } }; + if (DEBUGLEVEL < 1) { + DEBUGLEVEL = 1; + } + ndr_table_init(); /* Initialise samba stuff */ @@ -200,6 +206,9 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force) case OPT_LOAD_DSO: plugin = poptGetOptArg(pc); break; + case OPT_NDR64: + assume_ndr64 = true; + break; } } @@ -287,6 +296,9 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force) ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + if (assume_ndr64) { + ndr_pull->flags |= LIBNDR_FLAG_NDR64; + } ndr_err = f->ndr_pull(ndr_pull, NDR_IN, st); @@ -320,6 +332,9 @@ static void ndrdump_data(uint8_t *d, uint32_t l, bool force) ndr_pull = ndr_pull_init_blob(&blob, mem_ctx, lp_iconv_convenience(cmdline_lp_ctx)); ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; + if (assume_ndr64) { + ndr_pull->flags |= LIBNDR_FLAG_NDR64; + } ndr_err = f->ndr_pull(ndr_pull, flags, st); status = ndr_map_error2ntstatus(ndr_err); |