From: Yu Watanabe Date: Sun, 19 Jul 2020 02:32:18 +0000 (+0900) Subject: util: introduce bus_mesage_read_dns_servers() X-Git-Tag: v246-rc2~32^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10d4620467bc9b967d5d6446ecf1bd127e1d81f4;p=thirdparty%2Fsystemd.git util: introduce bus_mesage_read_dns_servers() --- diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c index 8b271f9693a..be196715053 100644 --- a/src/network/networkd-link-bus.c +++ b/src/network/networkd-link-bus.c @@ -7,6 +7,7 @@ #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-get-properties.h" +#include "bus-message-util.h" #include "bus-polkit.h" #include "dns-domain.h" #include "networkd-link-bus.h" @@ -115,9 +116,9 @@ int bus_link_method_set_ntp_servers(sd_bus_message *message, void *userdata, sd_ } static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, void *userdata, sd_bus_error *error, bool extended) { - struct in_addr_full **dns = NULL; - size_t allocated = 0, n = 0; + struct in_addr_full **dns; Link *l = userdata; + size_t n; int r; assert(message); @@ -127,82 +128,10 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi if (r < 0) return r; - r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)"); + r = bus_message_read_dns_servers(message, error, extended, &dns, &n); if (r < 0) return r; - for (;;) { - const char *server_name = NULL; - union in_addr_union a; - uint16_t port = 0; - const void *d; - int family; - size_t sz; - - assert_cc(sizeof(int) == sizeof(int32_t)); - - r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay"); - if (r < 0) - goto finalize; - if (r == 0) - break; - - r = sd_bus_message_read(message, "i", &family); - if (r < 0) - goto finalize; - - if (!IN_SET(family, AF_INET, AF_INET6)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family); - goto finalize; - } - - r = sd_bus_message_read_array(message, 'y', &d, &sz); - if (r < 0) - goto finalize; - if (sz != FAMILY_ADDRESS_SIZE(family)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size"); - goto finalize; - } - - if (!dns_server_address_valid(family, d)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address"); - goto finalize; - } - - if (extended) { - r = sd_bus_message_read(message, "q", &port); - if (r < 0) - goto finalize; - - if (IN_SET(port, 53, 853)) - port = 0; - - r = sd_bus_message_read(message, "s", &server_name); - if (r < 0) - goto finalize; - } - - r = sd_bus_message_exit_container(message); - if (r < 0) - goto finalize; - - if (!GREEDY_REALLOC(dns, allocated, n+1)) { - r = -ENOMEM; - goto finalize; - } - - memcpy(&a, d, sz); - r = in_addr_full_new(family, &a, port, 0, server_name, dns + n); - if (r < 0) - goto finalize; - - n++; - } - - r = sd_bus_message_exit_container(message); - if (r < 0) - goto finalize; - r = bus_verify_polkit_async(message, CAP_NET_ADMIN, "org.freedesktop.network1.set-dns-servers", NULL, true, UID_INVALID, diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c index 117f8a378a3..42d4ae7aaf8 100644 --- a/src/resolve/resolved-link-bus.c +++ b/src/resolve/resolved-link-bus.c @@ -7,6 +7,7 @@ #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-get-properties.h" +#include "bus-message-util.h" #include "bus-polkit.h" #include "parse-util.h" #include "resolve-util.h" @@ -252,9 +253,9 @@ static int verify_unmanaged_link(Link *l, sd_bus_error *error) { } static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, void *userdata, sd_bus_error *error, bool extended) { - struct in_addr_full **dns = NULL; - size_t allocated = 0, n = 0; + struct in_addr_full **dns; Link *l = userdata; + size_t n; int r; assert(message); @@ -264,81 +265,10 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi if (r < 0) return r; - r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)"); + r = bus_message_read_dns_servers(message, error, extended, &dns, &n); if (r < 0) return r; - for (;;) { - const char *server_name = NULL; - union in_addr_union a; - uint16_t port = 0; - const void *d; - int family; - size_t sz; - - assert_cc(sizeof(int) == sizeof(int32_t)); - - r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay"); - if (r < 0) - goto finalize; - if (r == 0) - break; - - r = sd_bus_message_read(message, "i", &family); - if (r < 0) - goto finalize; - - if (!IN_SET(family, AF_INET, AF_INET6)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family); - goto finalize; - } - - r = sd_bus_message_read_array(message, 'y', &d, &sz); - if (r < 0) - goto finalize; - if (sz != FAMILY_ADDRESS_SIZE(family)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size"); - goto finalize; - } - - if (!dns_server_address_valid(family, d)) { - r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address"); - goto finalize; - } - - if (extended) { - r = sd_bus_message_read(message, "q", &port); - if (r < 0) - goto finalize; - - if (IN_SET(port, 53, 853)) - port = 0; - - r = sd_bus_message_read(message, "s", &server_name); - if (r < 0) - goto finalize; - } - - r = sd_bus_message_exit_container(message); - if (r < 0) - goto finalize; - - if (!GREEDY_REALLOC(dns, allocated, n+1)) { - r = -ENOMEM; - goto finalize; - } - - memcpy(&a, d, sz); - r = in_addr_full_new(family, &a, port, 0, server_name, dns + n); - if (r < 0) - goto finalize; - n++; - } - - r = sd_bus_message_exit_container(message); - if (r < 0) - goto finalize; - r = bus_verify_polkit_async(message, CAP_NET_ADMIN, "org.freedesktop.resolve1.set-dns-servers", NULL, true, UID_INVALID, diff --git a/src/shared/bus-message-util.c b/src/shared/bus-message-util.c index 2b13001c32c..4151b91aec7 100644 --- a/src/shared/bus-message-util.c +++ b/src/shared/bus-message-util.c @@ -2,6 +2,8 @@ #include "bus-message-util.h" +#include "resolve-util.h" + int bus_message_read_family(sd_bus_message *message, sd_bus_error *error, int *ret) { int family, r; @@ -48,3 +50,113 @@ int bus_message_read_in_addr_auto(sd_bus_message *message, sd_bus_error *error, memcpy(ret_addr, d, sz); return 0; } + +static int bus_message_read_dns_one( + sd_bus_message *message, + sd_bus_error *error, + bool extended, + int *ret_family, + union in_addr_union *ret_address, + uint16_t *ret_port, + const char **ret_server_name) { + const char *server_name = NULL; + union in_addr_union a; + uint16_t port = 0; + int family, r; + + assert(message); + assert(ret_family); + assert(ret_address); + assert(ret_port); + assert(ret_server_name); + + r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay"); + if (r <= 0) + return r; + + r = bus_message_read_in_addr_auto(message, error, &family, &a); + if (r < 0) + return r; + + if (!dns_server_address_valid(family, &a)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address"); + + if (extended) { + r = sd_bus_message_read(message, "q", &port); + if (r < 0) + return r; + + if (IN_SET(port, 53, 853)) + port = 0; + + r = sd_bus_message_read(message, "s", &server_name); + if (r < 0) + return r; + } + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + *ret_family = family; + *ret_address = a; + *ret_port = port; + *ret_server_name = server_name; + + return 1; +} + +int bus_message_read_dns_servers( + sd_bus_message *message, + sd_bus_error *error, + bool extended, + struct in_addr_full ***ret_dns, + size_t *ret_n_dns) { + + struct in_addr_full **dns = NULL; + size_t n = 0, allocated = 0; + int r; + + assert(message); + assert(ret_dns); + assert(ret_n_dns); + + r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)"); + if (r < 0) + return r; + + for (;;) { + const char *server_name; + union in_addr_union a; + uint16_t port; + int family; + + r = bus_message_read_dns_one(message, error, extended, &family, &a, &port, &server_name); + if (r < 0) + goto clear; + if (r == 0) + break; + + if (!GREEDY_REALLOC(dns, allocated, n+1)) { + r = -ENOMEM; + goto clear; + } + + r = in_addr_full_new(family, &a, port, 0, server_name, dns + n); + if (r < 0) + goto clear; + + n++; + } + + *ret_dns = TAKE_PTR(dns); + *ret_n_dns = n; + return 0; + +clear: + for (size_t i = 0; i < n; i++) + in_addr_full_free(dns[i]); + free(dns); + + return r; +} diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h index 79bef325e3b..90b78f415f5 100644 --- a/src/shared/bus-message-util.h +++ b/src/shared/bus-message-util.h @@ -4,6 +4,14 @@ #include "sd-bus.h" #include "in-addr-util.h" +#include "socket-netlink.h" int bus_message_read_family(sd_bus_message *message, sd_bus_error *error, int *ret); int bus_message_read_in_addr_auto(sd_bus_message *message, sd_bus_error *error, int *ret_family, union in_addr_union *ret_addr); + +int bus_message_read_dns_servers( + sd_bus_message *message, + sd_bus_error *error, + bool extended, + struct in_addr_full ***ret_dns, + size_t *ret_n_dns);