]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolve: query the parent zone for DS records
authorMaxHearnden <maxoscarhearnden@gmail.com>
Tue, 15 Apr 2025 00:16:48 +0000 (01:16 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 16 Apr 2025 18:24:11 +0000 (03:24 +0900)
RFC 4035 Section 4.2 requires that missing DS records are queried for in
the parent zone rather than the child zone, the old behaviour could
cause subdomains under home.arpa (RFC 8375) to fail validation.

This commit assumes that QDCOUNT = 1 as per RFC 9619

Fixes https://github.com/systemd/systemd/issues/19496

src/resolve/resolved-dns-question.c
src/resolve/resolved-dns-question.h
src/resolve/resolved-dns-scope.c

index 6832a4766c5dd5e89f8b2c435ac3dbbf02092b2f..84ddb999f44e49c5b70942be5bf3825692614543 100644 (file)
@@ -548,3 +548,12 @@ int dns_question_merge(DnsQuestion *a, DnsQuestion *b, DnsQuestion **ret) {
         *ret = TAKE_PTR(k);
         return 0;
 }
+
+bool dns_question_contains_key_type(DnsQuestion *q, uint16_t type) {
+        DnsResourceKey *t;
+        DNS_QUESTION_FOREACH(t, q)
+                if (t->type == type)
+                        return true;
+
+        return false;
+}
index a2fe219886c01e9b1de22b843a176718e106e318..b986c429975832c050886807d7eb41f9e503aa2f 100644 (file)
@@ -61,6 +61,8 @@ static inline bool dns_question_isempty(DnsQuestion *q) {
 
 int dns_question_merge(DnsQuestion *a, DnsQuestion *b, DnsQuestion **ret);
 
+bool dns_question_contains_key_type(DnsQuestion *q, uint16_t type);
+
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuestion*, dns_question_unref);
 
 #define _DNS_QUESTION_FOREACH(u, k, q)                                     \
index 33e17321832e664aa742847b194019a2ee157c56..78fa6015d2019bb9d0909a89a589b0a8ce394f4f 100644 (file)
@@ -713,6 +713,11 @@ DnsScopeMatch dns_scope_good_domain(
                 if (!dns_scope_get_dns_server(s))
                         return DNS_SCOPE_NO;
 
+                /* Route DS requests to the parent */
+                const char *route_domain = domain;
+                if (dns_question_contains_key_type(question, DNS_TYPE_DS))
+                        (void) dns_name_parent(&route_domain);
+
                 /* Always honour search domains for routing queries, except if this scope lacks DNS servers. Note that
                  * we return DNS_SCOPE_YES here, rather than just DNS_SCOPE_MAYBE, which means other wildcard scopes
                  * won't be considered anymore. */
@@ -721,7 +726,7 @@ DnsScopeMatch dns_scope_good_domain(
                         if (!d->route_only && !dns_name_is_root(d->name))
                                 has_search_domains = true;
 
-                        if (dns_name_endswith(domain, d->name) > 0) {
+                        if (dns_name_endswith(route_domain, d->name) > 0) {
                                 int c;
 
                                 c = dns_name_count_labels(d->name);