From d4cf68c5ae780fad51696d12dfd9d7546cc42f03 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 17 May 2016 12:30:46 +0200 Subject: [PATCH] librpc/ndr: add flag LIBNDR_FLAG_NO_COMPRESSION This flag can be used to change marshalling behaviour with regard to compression. Example: DNS packets make use of so called DNS name compression which means that for identical strings in a DNS packet, the second string is replaced with a reference (an offset) to the first. Setting this flag requests to turns off the marshalling compression. This will be used in the next commit to prevent name compression in DNS TSIG records. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11520 Signed-off-by: Ralph Boehme Reviewed-by: Garming Sam (cherry picked from commit df079962ef708de96e54ded13da04b6e12ac00d0) --- librpc/idl/idl_types.h | 1 + librpc/ndr/libndr.h | 3 +++ librpc/ndr/ndr_dns.c | 50 +++++++++++++++++++++++++++----------------------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/librpc/idl/idl_types.h b/librpc/idl/idl_types.h index 838c2192515..72a5d857852 100644 --- a/librpc/idl/idl_types.h +++ b/librpc/idl/idl_types.h @@ -40,6 +40,7 @@ #define NDR_ALIGN2 LIBNDR_FLAG_ALIGN2 #define NDR_ALIGN4 LIBNDR_FLAG_ALIGN4 #define NDR_ALIGN8 LIBNDR_FLAG_ALIGN8 +#define NDR_NO_COMP LIBNDR_FLAG_NO_COMPRESSION /* this flag is used to force a section of IDL as little endian. It is needed for the epmapper IDL, which is defined as always being LE */ diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h index c6116ed8119..2275f162b37 100644 --- a/librpc/ndr/libndr.h +++ b/librpc/ndr/libndr.h @@ -125,6 +125,9 @@ struct ndr_print { #define LIBNDR_FLAG_STR_RAW8 (1<<13) #define LIBNDR_STRING_FLAGS (0x7FFC) +/* Disable string token compression */ +#define LIBNDR_FLAG_NO_COMPRESSION (1<<15) + /* * don't debug NDR_ERR_BUFSIZE failures, * as the available buffer might be incomplete. diff --git a/librpc/ndr/ndr_dns.c b/librpc/ndr/ndr_dns.c index ab0c83a7e84..fcc1315f8e0 100644 --- a/librpc/ndr/ndr_dns.c +++ b/librpc/ndr/ndr_dns.c @@ -169,28 +169,30 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_string(struct ndr_push *ndr, size_t complen; uint32_t offset; - /* see if we have pushed the remaining string already, - * if so we use a label pointer to this string - */ - ndr_err = ndr_token_retrieve_cmp_fn(&ndr->dns_string_list, s, - &offset, - (comparison_fn_t)strcmp, - false); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - uint8_t b[2]; - - if (offset > 0x3FFF) { - return ndr_push_error(ndr, NDR_ERR_STRING, - "offset for dns string " \ - "label pointer " \ - "%u[%08X] > 0x00003FFF", - offset, offset); + if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) { + /* see if we have pushed the remaining string already, + * if so we use a label pointer to this string + */ + ndr_err = ndr_token_retrieve_cmp_fn(&ndr->dns_string_list, s, + &offset, + (comparison_fn_t)strcmp, + false); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + uint8_t b[2]; + + if (offset > 0x3FFF) { + return ndr_push_error(ndr, NDR_ERR_STRING, + "offset for dns string " \ + "label pointer " \ + "%u[%08X] > 0x00003FFF", + offset, offset); + } + + b[0] = 0xC0 | (offset>>8); + b[1] = (offset & 0xFF); + + return ndr_push_bytes(ndr, b, 2); } - - b[0] = 0xC0 | (offset>>8); - b[1] = (offset & 0xFF); - - return ndr_push_bytes(ndr, b, 2); } complen = strcspn(s, "."); @@ -213,8 +215,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_string(struct ndr_push *ndr, /* remember the current componemt + the rest of the string * so it can be reused later */ - NDR_CHECK(ndr_token_store(ndr, &ndr->dns_string_list, s, - ndr->offset)); + if (!(ndr->flags & LIBNDR_FLAG_NO_COMPRESSION)) { + NDR_CHECK(ndr_token_store(ndr, &ndr->dns_string_list, s, + ndr->offset)); + } /* push just this component into the blob */ NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, -- 2.11.4.GIT