]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolve: unify two validate_and_mangle_flags()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Feb 2025 12:08:58 +0000 (21:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Feb 2025 13:39:52 +0000 (22:39 +0900)
The argument `Manager *manager`, is currently unused, but will be used
later.

src/resolve/resolved-bus.c
src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-varlink.c

index b81b9358d54b018ac0804c8bfcd2d5d2962045cd..96cfd32257a225586ff85f44f8ef92cc49e396cf 100644 (file)
@@ -361,51 +361,6 @@ finish:
         }
 }
 
-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;
@@ -519,9 +474,8 @@ static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata,
         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)
@@ -674,9 +628,8 @@ static int bus_method_resolve_address(sd_bus_message *message, void *userdata, s
         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)
@@ -843,9 +796,8 @@ 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_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)
@@ -1378,9 +1330,8 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
         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)
index 78c57da18199d7d1f13d864535af37392744493e..5698511b805dd29258a86a208dd6d8c2fa7f5f21 100644 (file)
@@ -1440,3 +1440,49 @@ bool dns_query_fully_authoritative(DnsQuery *q) {
          * 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;
+}
index 1097e90dc093906bf81f62afb3cd62f258916fa3..3a93ff7f1ab5d2e71d8754d3837e238d72d69747 100644 (file)
@@ -158,6 +158,8 @@ bool dns_query_fully_authenticated(DnsQuery *q);
 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);
 
index d04bcc332eeb4ae8062402c7e5d15bf22c922df8..c687dd694ff6a6a82e0c9028da7df4a1e9d2a958 100644 (file)
@@ -166,52 +166,6 @@ static void vl_on_notification_disconnect(sd_varlink_server *s, sd_varlink *link
         }
 }
 
-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,
@@ -387,7 +341,7 @@ static int vl_method_resolve_hostname(sd_varlink *link, sd_json_variant *paramet
         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);
@@ -550,7 +504,7 @@ static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *paramete
         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);
@@ -1044,7 +998,7 @@ static int vl_method_resolve_service(sd_varlink* link, sd_json_variant* paramete
         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);
@@ -1184,7 +1138,7 @@ static int vl_method_resolve_record(sd_varlink *link, sd_json_variant *parameter
         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);