diff --git a/CHANGES b/CHANGES index f25baa4608..c9b444fd80 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4191. [protocol] Accept DNS-SD non LDH PTR records in reverse zones + as per RFC 6763. [RT #37889] + 4190. [protocol] Accept Active Diretory gc._msdcs. name as valid with check-names. still needs to be LDH. [RT #40399] diff --git a/bin/tests/system/checkzone/tests.sh b/bin/tests/system/checkzone/tests.sh index 61e8c90d31..4fffa3e988 100644 --- a/bin/tests/system/checkzone/tests.sh +++ b/bin/tests/system/checkzone/tests.sh @@ -26,6 +26,9 @@ do zones/good-gc-msdcs.db) $CHECKZONE -k fail -i local example $db > test.out.$n 2>&1 || ret=1 ;; + zones/good-dns-sd-reverse.db) + $CHECKZONE -k fail -i local 0.0.0.0.in-addr.arpa $db > test.out.$n 2>&1 || ret=1 + ;; *) $CHECKZONE -i local example $db > test.out.$n 2>&1 || ret=1 ;; @@ -39,7 +42,14 @@ for db in zones/bad*.db do echo "I:checking $db ($n)" ret=0 - $CHECKZONE -i local example $db > test.out.$n 2>&1 && ret=1 + case $db in + zones/bad-dns-sd-reverse.db) + $CHECKZONE -k fail -i local 0.0.0.0.in-addr.arpa $db > test.out.$n 2>&1 && ret=1 + ;; + *) + $CHECKZONE -i local example $db > test.out.$n 2>&1 && ret=1 + ;; + esac n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` diff --git a/bin/tests/system/checkzone/zones/bad-dns-sd-reverse.db b/bin/tests/system/checkzone/zones/bad-dns-sd-reverse.db new file mode 100644 index 0000000000..3e69f23cde --- /dev/null +++ b/bin/tests/system/checkzone/zones/bad-dns-sd-reverse.db @@ -0,0 +1,10 @@ +$TTL 60 +@ IN SOA . . 0 0 0 0 0 +@ IN NS . +; +; The following are *not* Service Discovery Prefixes from RFC 6763 and the +; PTR check-names rules for IN-ADDR.ARPA and IP6.ARPA do still apply. +; +b._fail._udp IN PTR !@#3. +db._wrong._udp IN PTR !@#3. +lb._dns-sd._tcp IN PTR !@#3. diff --git a/bin/tests/system/checkzone/zones/good-dns-sd-reverse.db b/bin/tests/system/checkzone/zones/good-dns-sd-reverse.db new file mode 100644 index 0000000000..5b9963d681 --- /dev/null +++ b/bin/tests/system/checkzone/zones/good-dns-sd-reverse.db @@ -0,0 +1,12 @@ +$TTL 60 +@ IN SOA . . 0 0 0 0 0 +@ IN NS . +; +; The following are Service Discovery Prefixes from RFC 6763 and the +; PTR check-names rules for IN-ADDR.ARPA and IP6.ARPA do not apply. +; +b._dns-sd._udp IN PTR !@#3. +db._dns-sd._udp IN PTR !@#3. +r._dns-sd._udp IN PTR !@#3. +dr._dns-sd._udp IN PTR !@#3. +lb._dns-sd._udp IN PTR !@#3. diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h index 784e7eb973..d3d466a886 100644 --- a/lib/dns/include/dns/name.h +++ b/lib/dns/include/dns/name.h @@ -1286,6 +1286,12 @@ dns_name_destroy(void); * non-NULL argument prior to calling dns_name_destroy(); */ +isc_boolean_t +dns_name_isdnssd(const dns_name_t *owner); +/*%< + * Determine if the 'owner' is a DNS-SD prefix. + */ + ISC_LANG_ENDDECLS /* diff --git a/lib/dns/master.c b/lib/dns/master.c index cb51991a5a..e2d4d6bc2f 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -364,7 +364,6 @@ static const dns_name_t ip6_arpa = {NULL, NULL} }; - static inline isc_result_t gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token, isc_boolean_t eol, dns_rdatacallbacks_t *callbacks) @@ -1799,6 +1798,7 @@ load_text(dns_loadctx_t *lctx) { } } if (type == dns_rdatatype_ptr && + !dns_name_isdnssd(name) && (dns_name_issubdomain(name, &in_addr_arpa) || dns_name_issubdomain(name, &ip6_arpa) || dns_name_issubdomain(name, &ip6_int))) diff --git a/lib/dns/name.c b/lib/dns/name.c index 2d335bac68..6e1726ab44 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -2542,3 +2542,76 @@ dns_name_destroy(void) { #endif } + +/* + * Service Discovery Prefixes RFC 6763. + */ +static unsigned char b_dns_sd_udp_data[] = "\001b\007_dns-sd\004_udp"; +static unsigned char b_dns_sd_udp_offsets[] = { 0, 2, 10 }; +static unsigned char db_dns_sd_udp_data[] = "\002db\007_dns-sd\004_udp"; +static unsigned char db_dns_sd_udp_offsets[] = { 0, 3, 11 }; +static unsigned char r_dns_sd_udp_data[] = "\001r\007_dns-sd\004_udp"; +static unsigned char r_dns_sd_udp_offsets[] = { 0, 2, 10 }; +static unsigned char dr_dns_sd_udp_data[] = "\002dr\007_dns-sd\004_udp"; +static unsigned char dr_dns_sd_udp_offsets[] = { 0, 3, 11 }; +static unsigned char lb_dns_sd_udp_data[] = "\002lb\007_dns-sd\004_udp"; +static unsigned char lb_dns_sd_udp_offsets[] = { 0, 3, 11 }; + +static const dns_name_t dns_sd[] = { + { + DNS_NAME_MAGIC, + b_dns_sd_udp_data, 15, 3, + DNS_NAMEATTR_READONLY, + b_dns_sd_udp_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} + }, + { + DNS_NAME_MAGIC, + db_dns_sd_udp_data, 16, 3, + DNS_NAMEATTR_READONLY, + db_dns_sd_udp_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} + }, + { + DNS_NAME_MAGIC, + r_dns_sd_udp_data, 15, 3, + DNS_NAMEATTR_READONLY, + r_dns_sd_udp_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} + }, + { + DNS_NAME_MAGIC, + dr_dns_sd_udp_data, 16, 3, + DNS_NAMEATTR_READONLY, + dr_dns_sd_udp_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} + }, + { + DNS_NAME_MAGIC, + lb_dns_sd_udp_data, 16, 3, + DNS_NAMEATTR_READONLY, + lb_dns_sd_udp_offsets, NULL, + {(void *)-1, (void *)-1}, + {NULL, NULL} + } +}; + +isc_boolean_t +dns_name_isdnssd(const dns_name_t *name) { + size_t i; + dns_name_t prefix; + + if (dns_name_countlabels(name) > 3U) { + dns_name_init(&prefix, NULL); + dns_name_getlabelsequence(name, 0, 3, &prefix); + for (i = 0; i < (sizeof(dns_sd)/sizeof(dns_sd[0])); i++) + if (dns_name_equal(&prefix, &dns_sd[i])) + return (ISC_TRUE); + } + + return (ISC_FALSE); +} diff --git a/lib/dns/rdata/generic/ptr_12.c b/lib/dns/rdata/generic/ptr_12.c index 2707ae3d58..e3f65cf285 100644 --- a/lib/dns/rdata/generic/ptr_12.c +++ b/lib/dns/rdata/generic/ptr_12.c @@ -273,6 +273,9 @@ checknames_ptr(ARGS_CHECKNAMES) { if (rdata->rdclass != dns_rdataclass_in) return (ISC_TRUE); + if (dns_name_isdnssd(owner)) + return (ISC_TRUE); + if (dns_name_issubdomain(owner, &in_addr_arpa) || dns_name_issubdomain(owner, &ip6_arpa) || dns_name_issubdomain(owner, &ip6_int)) { diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 52a4329756..06b1911527 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -523,6 +523,7 @@ dns_name_init dns_name_internalwildcard dns_name_invalidate dns_name_isabsolute +dns_name_isdnssd dns_name_ishostname dns_name_ismailbox dns_name_issubdomain