summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/librpc/idl/idl_types.h2
-rw-r--r--source4/librpc/ndr/libndr.h4
-rw-r--r--source4/librpc/ndr/ndr.c16
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;
}