resolved: expose a new bus property that informs about the /etc/resolv.conf mode

It can be one of "foreign", "missing", "stub", "static", "uplink",
depending on how /etc/resolv.conf is set up:

foreign → someone/something else manages /etc/resolv.conf,
    systemd-resolved is just the consumer

missing → /etc/resolv.conf is missing altogether

stub/static/uplink → the file is managed by resolved, with the
    well-known modes

Fixes: #17159
This commit is contained in:
Lennart Poettering
2020-09-30 10:27:50 +02:00
parent 60b254ca1a
commit 4261ab654c
4 changed files with 96 additions and 3 deletions
+24
View File
@@ -15,6 +15,7 @@
#include "resolved-dnssd-bus.h"
#include "resolved-dnssd.h"
#include "resolved-link-bus.h"
#include "resolved-resolv-conf.h"
#include "socket-netlink.h"
#include "stdio-util.h"
#include "strv.h"
@@ -1620,6 +1621,28 @@ static BUS_DEFINE_PROPERTY_GET(bus_property_get_dnssec_supported, "b", Manager,
static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dnssec_mode, "s", Manager, manager_get_dnssec_mode, dnssec_mode_to_string);
static BUS_DEFINE_PROPERTY_GET2(bus_property_get_dns_over_tls_mode, "s", Manager, manager_get_dns_over_tls_mode, dns_over_tls_mode_to_string);
static int bus_property_get_resolv_conf_mode(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
int r;
assert(reply);
r = resolv_conf_mode();
if (r < 0) {
log_warning_errno(r, "Failed to test /etc/resolv.conf mode, ignoring: %m");
return sd_bus_message_append(reply, "s", NULL);
}
return sd_bus_message_append(reply, "s", resolv_conf_mode_to_string(r));
}
static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = userdata;
DnsScope *s;
@@ -2000,6 +2023,7 @@ static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_PROPERTY("DNSSECSupported", "b", bus_property_get_dnssec_supported, 0, 0),
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", bus_property_get_ntas, 0, 0),
SD_BUS_PROPERTY("DNSStubListener", "s", bus_property_get_dns_stub_listener_mode, offsetof(Manager, dns_stub_listener_mode), 0),
SD_BUS_PROPERTY("ResolvConfMode", "s", bus_property_get_resolv_conf_mode, 0, 0),
SD_BUS_METHOD_WITH_ARGS("ResolveHostname",
SD_BUS_ARGS("i", ifindex, "s", name, "i", family, "t", flags),
+47
View File
@@ -15,6 +15,7 @@
#include "resolved-dns-server.h"
#include "resolved-resolv-conf.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "tmpfile-util-label.h"
@@ -371,3 +372,49 @@ int manager_write_resolv_conf(Manager *m) {
return r;
}
int resolv_conf_mode(void) {
static const char * const table[_RESOLV_CONF_MODE_MAX] = {
[RESOLV_CONF_UPLINK] = PRIVATE_UPLINK_RESOLV_CONF,
[RESOLV_CONF_STUB] = PRIVATE_STUB_RESOLV_CONF,
[RESOLV_CONF_STATIC] = PRIVATE_STATIC_RESOLV_CONF,
};
struct stat system_st;
if (stat("/etc/resolv.conf", &system_st) < 0) {
if (errno == ENOENT)
return RESOLV_CONF_MISSING;
return -errno;
}
for (ResolvConfMode m = 0; m < _RESOLV_CONF_MODE_MAX; m++) {
struct stat our_st;
if (!table[m])
continue;
if (stat(table[m], &our_st) < 0) {
if (errno != ENOENT)
log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", table[m]);
continue;
}
if (system_st.st_dev == our_st.st_dev &&
system_st.st_ino == our_st.st_ino)
return m;
}
return RESOLV_CONF_FOREIGN;
}
static const char* const resolv_conf_mode_table[_RESOLV_CONF_MODE_MAX] = {
[RESOLV_CONF_UPLINK] = "uplink",
[RESOLV_CONF_STUB] = "stub",
[RESOLV_CONF_STATIC] = "static",
[RESOLV_CONF_MISSING] = "missing",
[RESOLV_CONF_FOREIGN] = "foreign",
};
DEFINE_STRING_TABLE_LOOKUP(resolv_conf_mode, ResolvConfMode);
+15
View File
@@ -6,3 +6,18 @@
int manager_check_resolv_conf(const Manager *m);
int manager_read_resolv_conf(Manager *m);
int manager_write_resolv_conf(Manager *m);
typedef enum ResolvConfMode {
RESOLV_CONF_UPLINK,
RESOLV_CONF_STUB,
RESOLV_CONF_STATIC,
RESOLV_CONF_FOREIGN,
RESOLV_CONF_MISSING,
_RESOLV_CONF_MODE_MAX,
_RESOLV_CONF_MODE_INVALID = -1,
} ResolvConfMode;
int resolv_conf_mode(void);
const char* resolv_conf_mode_to_string(ResolvConfMode m) _const_;
ResolvConfMode resolv_conf_mode_from_string(const char *s) _pure_;