}
}
-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
- * sense in our method call context. Specifically:
- *
- * 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive
- *
- * 2. Only the protocols flags and a bunch of NO_XYZ flags are set, at most. Plus additional flags
- * specific to our method, passed in the "ok" parameter.
- *
- * 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way
- * clients can simply pass 0 as flags and all will work as it should. They can also use this so
- * that clients don't have to know all the protocols resolved implements, but can just specify 0
- * to mean "all supported protocols".
- */
-
- if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|
- SD_RESOLVED_NO_CNAME|
- SD_RESOLVED_NO_VALIDATE|
- SD_RESOLVED_NO_SYNTHESIZE|
- SD_RESOLVED_NO_CACHE|
- SD_RESOLVED_NO_ZONE|
- SD_RESOLVED_NO_TRUST_ANCHOR|
- SD_RESOLVED_NO_NETWORK|
- SD_RESOLVED_NO_STALE|
- SD_RESOLVED_RELAX_SINGLE_LABEL|
- ok))
- return sd_bus_error_set(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;
-}
-
static int parse_as_address(sd_bus_message *m, int ifindex, const char *hostname, int family, uint64_t flags) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_free_ char *canonical = NULL;
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_flags(hostname, &flags, SD_RESOLVED_NO_SEARCH, error);
- if (r < 0)
- return r;
+ if (validate_and_mangle_query_flags(m, &flags, hostname, SD_RESOLVED_NO_SEARCH) < 0)
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
r = parse_as_address(message, ifindex, hostname, family, flags);
if (r != 0)
if (ifindex < 0)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
- r = validate_and_mangle_flags(NULL, &flags, 0, error);
- if (r < 0)
- return r;
+ if (validate_and_mangle_query_flags(m, &flags, /* name = */ NULL, /* ok = */ 0) < 0)
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
r = dns_question_new_reverse(&question, family, &a);
if (r < 0)
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_flags(name, &flags, 0, error);
- if (r < 0)
- return r;
+ if (validate_and_mangle_query_flags(m, &flags, name, /* ok = */ 0) < 0)
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
question = dns_question_new(1);
if (!question)
if (name && !type)
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
- r = validate_and_mangle_flags(name, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
- if (r < 0)
- return r;
+ if (validate_and_mangle_query_flags(m, &flags, name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0)
+ return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
r = dns_question_new_service(&question_utf8, name, type, domain, !(flags & SD_RESOLVED_NO_TXT), false);
if (r < 0)
* explicitly check previous redirects here.) */
return (q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~(SD_RESOLVED_FROM_TRUST_ANCHOR | SD_RESOLVED_FROM_ZONE)) == 0;
}
+
+int validate_and_mangle_query_flags(
+ Manager *manager,
+ uint64_t *flags,
+ const char *name,
+ uint64_t ok) {
+
+ assert(manager);
+ assert(flags);
+
+ /* Checks that the client supplied interface index and flags parameter actually are valid and make
+ * sense in our method call context. Specifically:
+ *
+ * 1. Checks that the interface index is either 0 (meaning *all* interfaces) or positive
+ *
+ * 2. Only the protocols flags and a bunch of NO_XYZ flags are set, at most. Plus additional flags
+ * specific to our method, passed in the "ok" parameter.
+ *
+ * 3. If zero protocol flags are specified it is automatically turned into *all* protocols. This way
+ * clients can simply pass 0 as flags and all will work as it should. They can also use this so
+ * that clients don't have to know all the protocols resolved implements, but can just specify 0
+ * to mean "all supported protocols".
+ */
+
+ if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|
+ SD_RESOLVED_NO_CNAME|
+ SD_RESOLVED_NO_VALIDATE|
+ SD_RESOLVED_NO_SYNTHESIZE|
+ SD_RESOLVED_NO_CACHE|
+ SD_RESOLVED_NO_ZONE|
+ SD_RESOLVED_NO_TRUST_ANCHOR|
+ SD_RESOLVED_NO_NETWORK|
+ SD_RESOLVED_NO_STALE|
+ SD_RESOLVED_RELAX_SINGLE_LABEL|
+ ok))
+ return -EINVAL;
+
+ 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;
+}
bool dns_query_fully_confidential(DnsQuery *q);
bool dns_query_fully_authoritative(DnsQuery *q);
+int validate_and_mangle_query_flags(Manager *manager, uint64_t *flags, const char *name, uint64_t ok);
+
static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
assert(q);
}
}
-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
- * it slightly. Specifically:
- *
- * 1. We check that only the protocol flags and a bunch of NO_XYZ flags are on at most, plus the
- * method-specific flags specified in 'ok'.
- *
- * 2. If no protocols are enabled we automatically convert that to "all protocols are enabled".
- *
- * The second rule means that clients can just pass 0 as flags for the common case, and all supported
- * protocols are enabled. Moreover it's useful so that client's do not have to be aware of all
- * protocols implemented in resolved, but can use 0 as protocols flags set as indicator for
- * "everything".
- */
-
- if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|
- SD_RESOLVED_NO_CNAME|
- SD_RESOLVED_NO_VALIDATE|
- SD_RESOLVED_NO_SYNTHESIZE|
- SD_RESOLVED_NO_CACHE|
- SD_RESOLVED_NO_ZONE|
- SD_RESOLVED_NO_TRUST_ANCHOR|
- SD_RESOLVED_NO_NETWORK|
- SD_RESOLVED_NO_STALE|
- SD_RESOLVED_RELAX_SINGLE_LABEL|
- ok))
- return false;
-
- 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;
-}
-
static int find_addr_records(
sd_json_variant **array,
DnsQuestion *question,
if (!IN_SET(p.family, AF_UNSPEC, AF_INET, AF_INET6))
return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family"));
- if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH))
+ if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_SEARCH) < 0)
return sd_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 sd_varlink_error(link, "io.systemd.Resolve.BadAddressSize", NULL);
- if (!validate_and_mangle_flags(NULL, &p.flags, 0))
+ if (validate_and_mangle_query_flags(m, &p.flags, /* name = */ NULL, /* ok = */ 0) < 0)
return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
r = dns_question_new_reverse(&question, p.family, &p.address);
if (p.name && !p.type) /* Service name cannot be specified without service type. */
return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("type"));
- if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS))
+ if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS) < 0)
return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
r = dns_question_new_service(&question_utf8, p.name, p.type, p.domain, !(p.flags & SD_RESOLVED_NO_TXT), false);
if (dns_type_is_obsolete(p.type))
return sd_varlink_error(link, "io.systemd.Resolve.ResourceRecordTypeObsolete", NULL);
- if (!validate_and_mangle_flags(p.name, &p.flags, SD_RESOLVED_NO_SEARCH))
+ if (validate_and_mangle_query_flags(m, &p.flags, p.name, SD_RESOLVED_NO_SEARCH) < 0)
return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
_cleanup_(dns_question_unrefp) DnsQuestion *question = dns_question_new(1);