resolve: add DBus method to set DNS server with port number and SNI
This commit is contained in:
parent
4e11ddfdd3
commit
95ce1ba87b
|
@ -1532,6 +1532,10 @@ static int bus_method_set_link_dns_servers(sd_bus_message *message, void *userda
|
||||||
return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
|
return call_link_method(userdata, message, bus_link_method_set_dns_servers, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int bus_method_set_link_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
return call_link_method(userdata, message, bus_link_method_set_dns_servers_ex, error);
|
||||||
|
}
|
||||||
|
|
||||||
static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
static int bus_method_set_link_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
return call_link_method(userdata, message, bus_link_method_set_domains, error);
|
return call_link_method(userdata, message, bus_link_method_set_domains, error);
|
||||||
}
|
}
|
||||||
|
@ -1895,6 +1899,11 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
bus_method_set_link_dns_servers,
|
bus_method_set_link_dns_servers,
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD_WITH_ARGS("SetLinkDNSEx",
|
||||||
|
SD_BUS_ARGS("i", ifindex, "a(iayqs)", addresses),
|
||||||
|
SD_BUS_NO_RESULT,
|
||||||
|
bus_method_set_link_dns_servers_ex,
|
||||||
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
|
SD_BUS_METHOD_WITH_ARGS("SetLinkDomains",
|
||||||
SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
|
SD_BUS_ARGS("i", ifindex, "a(sb)", domains),
|
||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "resolved-bus.h"
|
#include "resolved-bus.h"
|
||||||
#include "resolved-link-bus.h"
|
#include "resolved-link-bus.h"
|
||||||
#include "resolved-resolv-conf.h"
|
#include "resolved-resolv-conf.h"
|
||||||
|
#include "socket-netlink.h"
|
||||||
#include "stdio-util.h"
|
#include "stdio-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
@ -204,11 +205,10 @@ static int verify_unmanaged_link(Link *l, sd_bus_error *error) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, 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) {
|
||||||
_cleanup_free_ struct in_addr_data *dns = NULL;
|
struct in_addr_full **dns = NULL;
|
||||||
size_t allocated = 0, n = 0;
|
size_t allocated = 0, n = 0;
|
||||||
Link *l = userdata;
|
Link *l = userdata;
|
||||||
unsigned i;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(message);
|
assert(message);
|
||||||
|
@ -218,76 +218,106 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = sd_bus_message_enter_container(message, 'a', "(iay)");
|
r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
const char *server_name = NULL;
|
||||||
|
union in_addr_union a;
|
||||||
|
uint16_t port = 0;
|
||||||
|
const void *d;
|
||||||
int family;
|
int family;
|
||||||
size_t sz;
|
size_t sz;
|
||||||
const void *d;
|
|
||||||
|
|
||||||
assert_cc(sizeof(int) == sizeof(int32_t));
|
assert_cc(sizeof(int) == sizeof(int32_t));
|
||||||
|
|
||||||
r = sd_bus_message_enter_container(message, 'r', "iay");
|
r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
r = sd_bus_message_read(message, "i", &family);
|
r = sd_bus_message_read(message, "i", &family);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
|
|
||||||
if (!IN_SET(family, AF_INET, AF_INET6))
|
if (!IN_SET(family, AF_INET, AF_INET6)) {
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
|
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);
|
r = sd_bus_message_read_array(message, 'y', &d, &sz);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
if (sz != FAMILY_ADDRESS_SIZE(family))
|
if (sz != FAMILY_ADDRESS_SIZE(family)) {
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
|
r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dns_server_address_valid(family, d))
|
if (!dns_server_address_valid(family, d)) {
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
|
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);
|
r = sd_bus_message_exit_container(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
|
|
||||||
if (!GREEDY_REALLOC(dns, allocated, n+1))
|
if (!GREEDY_REALLOC(dns, allocated, n+1)) {
|
||||||
return -ENOMEM;
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
dns[n].family = family;
|
memcpy(&a, d, sz);
|
||||||
memcpy(&dns[n].address, d, sz);
|
r = in_addr_full_new(family, &a, port, 0, server_name, dns + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_bus_message_exit_container(message);
|
r = sd_bus_message_exit_container(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
|
|
||||||
r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
"org.freedesktop.resolve1.set-dns-servers",
|
"org.freedesktop.resolve1.set-dns-servers",
|
||||||
NULL, true, UID_INVALID,
|
NULL, true, UID_INVALID,
|
||||||
&l->manager->polkit_registry, error);
|
&l->manager->polkit_registry, error);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
goto finalize;
|
||||||
if (r == 0)
|
if (r == 0) {
|
||||||
return 1; /* Polkit will call us back */
|
r = 1; /* Polkit will call us back */
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
dns_server_mark_all(l->dns_servers);
|
dns_server_mark_all(l->dns_servers);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
DnsServer *s;
|
DnsServer *s;
|
||||||
|
|
||||||
s = dns_server_find(l->dns_servers, dns[i].family, &dns[i].address, 0, 0, NULL);
|
s = dns_server_find(l->dns_servers, dns[i]->family, &dns[i]->address, dns[i]->port, 0, dns[i]->server_name);
|
||||||
if (s)
|
if (s)
|
||||||
dns_server_move_back_and_unmark(s);
|
dns_server_move_back_and_unmark(s);
|
||||||
else {
|
else {
|
||||||
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i].family, &dns[i].address, 0, 0, NULL);
|
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i]->family, &dns[i]->address, dns[i]->port, 0, dns[i]->server_name);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
goto clear;
|
dns_server_unlink_all(l->dns_servers);
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -299,13 +329,24 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
|
||||||
(void) manager_write_resolv_conf(l->manager);
|
(void) manager_write_resolv_conf(l->manager);
|
||||||
(void) manager_send_changed(l->manager, "DNS");
|
(void) manager_send_changed(l->manager, "DNS");
|
||||||
|
|
||||||
return sd_bus_reply_method_return(message, NULL);
|
r = sd_bus_reply_method_return(message, NULL);
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
for (size_t i = 0; i < n; i++)
|
||||||
|
in_addr_full_free(dns[i]);
|
||||||
|
free(dns);
|
||||||
|
|
||||||
clear:
|
|
||||||
dns_server_unlink_all(l->dns_servers);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
return bus_link_method_set_dns_servers_internal(message, userdata, error, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bus_link_method_set_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
|
return bus_link_method_set_dns_servers_internal(message, userdata, error, true);
|
||||||
|
}
|
||||||
|
|
||||||
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||||
Link *l = userdata;
|
Link *l = userdata;
|
||||||
int r;
|
int r;
|
||||||
|
@ -777,6 +818,11 @@ static const sd_bus_vtable link_vtable[] = {
|
||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
bus_link_method_set_dns_servers,
|
bus_link_method_set_dns_servers,
|
||||||
SD_BUS_VTABLE_UNPRIVILEGED),
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD_WITH_ARGS("SetDNSEx",
|
||||||
|
SD_BUS_ARGS("a(iayqs)", addresses),
|
||||||
|
SD_BUS_NO_RESULT,
|
||||||
|
bus_link_method_set_dns_servers_ex,
|
||||||
|
SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
SD_BUS_METHOD_WITH_ARGS("SetDomains",
|
SD_BUS_METHOD_WITH_ARGS("SetDomains",
|
||||||
SD_BUS_ARGS("a(sb)", domains),
|
SD_BUS_ARGS("a(sb)", domains),
|
||||||
SD_BUS_NO_RESULT,
|
SD_BUS_NO_RESULT,
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern const BusObjectImplementation link_object;
|
||||||
char *link_bus_path(const Link *link);
|
char *link_bus_path(const Link *link);
|
||||||
|
|
||||||
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
|
int bus_link_method_set_dns_servers_ex(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_error *error);
|
||||||
|
|
Loading…
Reference in a new issue