librpc/dns: don't compress strings in TKEY and TSIG responses
authorRalph Boehme <slow@samba.org>
Tue, 17 May 2016 12:34:52 +0000 (14:34 +0200)
committerGarming Sam <garming@samba.org>
Wed, 15 Jun 2016 22:06:27 +0000 (00:06 +0200)
Certain DNS clients fail TSIG record MAC validation if the TSIG record
contains compressed strings.

Windows DNS server behaviour seems to be to not send compressed names in
TKEY and TSIG records.

This patch ensures we conform to this behaviour.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11520

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
librpc/idl/dns.idl
librpc/ndr/ndr_dns.c

index 5435fcf38e69e8a330bf12a5167ed251d0d26967..13dd53bfcd3e6cf3af8bbdbba8fe4fdaa26cccef 100644 (file)
@@ -179,7 +179,7 @@ interface dns
                uint8      option_data[option_length];
        } dns_opt_record;
 
-       typedef [public] struct {
+       typedef [flag(NDR_NO_COMP),public] struct {
                dns_string     algorithm;
                uint32         inception;
                uint32         expiration;
@@ -191,7 +191,7 @@ interface dns
                uint8          other_data[other_size];
        } dns_tkey_record;
 
-       typedef [public] struct {
+       typedef [flag(NDR_NO_COMP),public] struct {
                dns_string algorithm_name;
                uint16     time_prefix; /* 0 until February 2106*/
                uint32     time;
@@ -204,7 +204,7 @@ interface dns
                uint8      other_data[other_size];
        } dns_tsig_record;
 
-       typedef [flag(NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
+       typedef [flag(NDR_NO_COMP|NDR_NOALIGN|NDR_BIG_ENDIAN|NDR_PAHEX),public] struct {
                dns_string      name;
                dns_qclass      rr_class;
                uint32          ttl;
index fcc1315f8e0bbe226e33c4fcbaf94e8a591ca571..7e6286a9f8ed11cf02f86c17bb4323613af65a74 100644 (file)
@@ -268,8 +268,21 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_res_rec(struct ndr_push *ndr,
        ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX |
                                   LIBNDR_FLAG_NOALIGN);
        if (ndr_flags & NDR_SCALARS) {
+               uint32_t _flags_save_name = ndr->flags;
+
                NDR_CHECK(ndr_push_align(ndr, 4));
+
+               switch (r->rr_type) {
+               case DNS_QTYPE_TKEY:
+               case DNS_QTYPE_TSIG:
+                       ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NO_COMPRESSION);
+                       break;
+               default:
+                       break;
+               }
                NDR_CHECK(ndr_push_dns_string(ndr, NDR_SCALARS, r->name));
+               ndr->flags = _flags_save_name;
+
                NDR_CHECK(ndr_push_dns_qtype(ndr, NDR_SCALARS, r->rr_type));
                NDR_CHECK(ndr_push_dns_qclass(ndr, NDR_SCALARS, r->rr_class));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl));