summaryrefslogtreecommitdiffstats
path: root/src/resolve
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-09-29 11:53:31 +0200
committerLennart Poettering <lennart@poettering.net>2020-09-29 12:12:03 +0200
commit3354f5003cc162bd5b549b23b92265874a0842b0 (patch)
tree3aee91fa448a92e8690532e6f64931dc3eca3683 /src/resolve
parentdns-domain: add helper that checks whether domain is dot suffixed (diff)
downloadsystemd-3354f5003cc162bd5b549b23b92265874a0842b0.tar.xz
systemd-3354f5003cc162bd5b549b23b92265874a0842b0.zip
resolved: imply SD_RESOLVED_NO_SEARCH when looking up trailing dot domains
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.
Diffstat (limited to 'src/resolve')
-rw-r--r--src/resolve/resolved-bus.c34
-rw-r--r--src/resolve/resolved-varlink.c16
2 files changed, 39 insertions, 11 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index b60a0fd1f2..afe67d9e6c 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -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;
diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c
index 2a65293c2a..2f11a78091 100644
--- a/src/resolve/resolved-varlink.c
+++ b/src/resolve/resolved-varlink.c
@@ -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);