From: Lennart Poettering Date: Tue, 29 Sep 2020 09:53:31 +0000 (+0200) Subject: resolved: imply SD_RESOLVED_NO_SEARCH when looking up trailing dot domains X-Git-Tag: v247-rc1~157^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3354f5003cc162bd5b549b23b92265874a0842b0;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index b60a0fd1f24..afe67d9e6cc 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 2a65293c2a6..2f11a780911 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);