diff options
-rw-r--r-- | source4/librpc/idl/idl_types.h | 2 | ||||
-rw-r--r-- | source4/librpc/ndr/libndr.h | 4 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr.c | 16 |
3 files changed, 16 insertions, 6 deletions
diff --git a/source4/librpc/idl/idl_types.h b/source4/librpc/idl/idl_types.h index 2140d44b20..86f4e17959 100644 --- a/source4/librpc/idl/idl_types.h +++ b/source4/librpc/idl/idl_types.h @@ -80,5 +80,7 @@ */ #define NDR_PAHEX LIBNDR_PRINT_ARRAY_HEX +/* this enables spoolss style relative ptrs */ +#define RELATIVE_CURRENT LIBNDR_FLAG_RELATIVE_CURRENT #define bool8 uint8 diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h index 9940dc2c05..8894877721 100644 --- a/source4/librpc/ndr/libndr.h +++ b/source4/librpc/ndr/libndr.h @@ -115,6 +115,10 @@ struct ndr_print { /* used to check if alignment padding is zero */ #define LIBNDR_FLAG_PAD_CHECK (1<<18) +/* used to indicate spoolss style relative pointers (relative to current + offset, not base) */ +#define LIBNDR_FLAG_RELATIVE_CURRENT (1<<19) + /* useful macro for debugging */ #define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p) diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c index 1cc96ca976..2f1c9ef47f 100644 --- a/source4/librpc/ndr/ndr.c +++ b/source4/librpc/ndr/ndr.c @@ -639,11 +639,11 @@ NTSTATUS ndr_pull_relative(struct ndr_pull *ndr, const void **buf, size_t size, return NT_STATUS_OK; } ndr_pull_save(ndr, &save); - /* the old way of handling relative pointers appears to be - wrong, and there doesn't seem to be anything relying on it, - but I am keeping the code around in case I missed a - critical use for it (tridge, august 2004) */ - NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); + if (ndr->flags & LIBNDR_FLAG_RELATIVE_CURRENT) { + NDR_CHECK(ndr_pull_set_offset(ndr, ofs + ndr->offset - 4)); + } else { + NDR_CHECK(ndr_pull_set_offset(ndr, ofs)); + } NDR_CHECK(ndr_pull_subcontext(ndr, ndr2, ndr->data_size - ndr->offset)); /* strings must be allocated by the backend functions */ if (ndr->flags & LIBNDR_STRING_FLAGS) { @@ -748,7 +748,11 @@ NTSTATUS ndr_push_relative2(struct ndr_push *ndr, const void *p) if (ndr->offset == 0) { return NT_STATUS_INTERNAL_ERROR; } - NDR_CHECK(ndr_push_uint32(ndr, save.offset)); + if (ndr->flags & LIBNDR_FLAG_RELATIVE_CURRENT) { + NDR_CHECK(ndr_push_uint32(ndr, save.offset - ndr->offset)); + } else { + NDR_CHECK(ndr_push_uint32(ndr, save.offset)); + } ndr_push_restore(ndr, &save); return NT_STATUS_OK; } |