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
* 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;
}
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;
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;
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;
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;
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);
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;
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
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;
}
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);
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);