]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: imply SD_RESOLVED_NO_SEARCH when looking up trailing dot domains 17194/head
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Sep 2020 09:53:31 +0000 (11:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 29 Sep 2020 10:12:03 +0000 (12:12 +0200)
Let's turn off the search domain logic if a trailing dot is specified
when looking up hostnames and RRs via the Varlink + D-Bus APIs (and thus
also when doing so via nss-resolve). (This doesn't affect lookups via
the stub, since for the any search path logic is done client side
anyway)

It might make sense to force the DNS protocol in this case too (and
disable LLMR + mDNS), but we'll leave that for a different PR — if it
even makes sense. It might also make sense to disable the logic of never
routing single-label lookups to the Internet if a trailing to is
specified, but this needs more discussion too.

src/resolve/resolved-bus.c
src/resolve/resolved-varlink.c

index b60a0fd1f24f0f3ffbe54e22b187d84877577c7e..afe67d9e6cc789c98faeb55bfc4cde6f2a3887b6 100644 (file)
@@ -260,7 +260,12 @@ finish:
         dns_query_free(q);
 }
 
-static int validate_and_mangle_ifindex_and_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
+static int validate_and_mangle_flags(
+                const char *name,
+                uint64_t *flags,
+                uint64_t ok,
+                sd_bus_error *error) {
+
         assert(flags);
 
         /* Checks that the client supplied interface index and flags parameter actually are valid and make
@@ -277,15 +282,16 @@ static int validate_and_mangle_ifindex_and_flags(int ifindex, uint64_t *flags, u
          *    to mean "all supported protocols".
          */
 
-        if (ifindex < 0)
-                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
-
         if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
 
         if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
                 *flags |= SD_RESOLVED_PROTOCOLS_ALL;
 
+        /* Imply SD_RESOLVED_NO_SEARCH if permitted and name is dot suffixed. */
+        if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0)
+                *flags |= SD_RESOLVED_NO_SEARCH;
+
         return 0;
 }
 
@@ -371,10 +377,13 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
         if (r < 0)
                 return r;
 
+        if (ifindex < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
+
         if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
 
-        r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
+        r = validate_and_mangle_flags(hostname, &flags, SD_RESOLVED_NO_SEARCH, error);
         if (r < 0)
                 return r;
 
@@ -527,7 +536,10 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
         if (r < 0)
                 return r;
 
-        r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error);
+        if (ifindex < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
+
+        r = validate_and_mangle_flags(NULL, &flags, 0, error);
         if (r < 0)
                 return r;
 
@@ -679,6 +691,9 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
         if (r < 0)
                 return r;
 
+        if (ifindex < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
+
         r = dns_name_is_valid(name);
         if (r < 0)
                 return r;
@@ -692,7 +707,7 @@ static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd
         if (dns_type_is_obsolete(type))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Specified DNS resource record type %" PRIu16 " is obsolete.", type);
 
-        r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, 0, error);
+        r = validate_and_mangle_flags(name, &flags, 0, error);
         if (r < 0)
                 return r;
 
@@ -1205,6 +1220,9 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
         if (r < 0)
                 return r;
 
+        if (ifindex < 0)
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
+
         if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
 
@@ -1227,7 +1245,7 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
         if (name && !type)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
 
-        r = validate_and_mangle_ifindex_and_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
+        r = validate_and_mangle_flags(name, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
         if (r < 0)
                 return r;
 
index 2a65293c2a64720cf8216d385faa8feed8cb7841..2f11a780911d5882dade7361817b8de964b38660 100644 (file)
@@ -93,7 +93,11 @@ static void vl_on_disconnect(VarlinkServer *s, Varlink *link, void *userdata) {
         dns_query_complete(q, DNS_TRANSACTION_ABORTED);
 }
 
-static bool validate_and_mangle_flags(uint64_t *flags, uint64_t ok) {
+static bool validate_and_mangle_flags(
+                const char *name,
+                uint64_t *flags,
+                uint64_t ok) {
+
         assert(flags);
 
         /* This checks that the specified client-provided flags parameter actually makes sense, and mangles
@@ -116,6 +120,12 @@ static bool validate_and_mangle_flags(uint64_t *flags, uint64_t ok) {
         if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
                 *flags |= SD_RESOLVED_PROTOCOLS_ALL;
 
+        /* If the SD_RESOLVED_NO_SEARCH flag is acceptable, and the query name is dot-suffixed, turn off
+         * search domains. Note that DNS name normalization drops the dot suffix, hence we propagate this
+         * into the flags field as early as we can. */
+        if (name && FLAGS_SET(ok, SD_RESOLVED_NO_SEARCH) && dns_name_dot_suffixed(name) > 0)
+                *flags |= SD_RESOLVED_NO_SEARCH;
+
         return true;
 }
 
@@ -285,7 +295,7 @@ static int vl_method_resolve_hostname(Varlink *link, JsonVariant *parameters, Va
         if (!IN_SET(p.family, AF_UNSPEC, AF_INET, AF_INET6))
                 return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family"));
 
-        if (!validate_and_mangle_flags(&p.flags, SD_RESOLVED_NO_SEARCH))
+        if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH))
                 return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
 
         r = parse_as_address(link, &p);
@@ -460,7 +470,7 @@ static int vl_method_resolve_address(Varlink *link, JsonVariant *parameters, Var
         if (FAMILY_ADDRESS_SIZE(p.family) != p.address_size)
                 return varlink_error(link, "io.systemd.UserDatabase.BadAddressSize", NULL);
 
-        if (!validate_and_mangle_flags(&p.flags, 0))
+        if (!validate_and_mangle_flags(NULL, &p.flags, 0))
                 return varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
 
         r = dns_question_new_reverse(&question, p.family, &p.address);