summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-06-03 11:16:03 +0200
committerThomas Haller <thaller@redhat.com>2016-06-03 12:18:47 +0200
commit47118679151ac1296ed9b8e2b3edcf90a38004fe (patch)
tree6251f2f2a5d03e4cfec183c60b3158747cb5c0fe
parent718fd2243690b8c72dd1cb32f67114f304542082 (diff)
downloadNetworkManager-47118679151ac1296ed9b8e2b3edcf90a38004fe.tar.gz
dns: update detection of immutable resolv.conf
Before, we would first check whether the file is immuable before parsing main.rc-manager setting. That means, if you configured [main] dns=default rc-manager=unmanged we would still first try to detect whether the file is immutable. The result of course is only minor, e.g. showing up in logging as rc-manager=immutable instead of rc-manager=unmanged. Also, an immutable resolv.conf would suppress a warning about a bogus rc-manager setting. Also, when selecting rc-manager=symlink and resolv.conf is a symlink to an immutable file, we don't actually care about that. The reason is, that if the link-target is not /var/run/NetworkManager/resolv.conf, we anyway wouldn't modify the file. The effect of this change is pretty minor, now in logging you would see: dns-mgr: init: dns=default, rc-manager=symlink dns-mgr: update-resolv-conf: write internal file /var/run/NetworkManager/resolv.conf succeeded but don't update /etc/resolv.conf as it points to /some/where/else instead of dns-mgr: init: dns=default, rc-manager=immutable dns-mgr: update-resolv-conf: write internal file /var/run/NetworkManager/resolv.conf succeeded Which feels slightly more right. Note that symlinks cannot have file attributes.
-rw-r--r--src/dns-manager/nm-dns-manager.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 8134f2f4a4..8690be8a36 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -1508,19 +1508,53 @@ _clear_plugin (NMDnsManager *self)
return FALSE;
}
-static bool
-_get_resconf_immutable (void)
+static NMDnsManagerResolvConfManager
+_check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
{
+ struct stat st;
int fd, flags;
bool immutable = FALSE;
- fd = open (_PATH_RESCONF, O_RDONLY);
- if (fd != -1) {
- if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1)
- immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL);
- close (fd);
+ switch (rc_manager) {
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE:
+ nm_assert_not_reached ();
+ /* fall-through */
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED:
+ return NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
+ default:
+
+ if (lstat (_PATH_RESCONF, &st) != 0)
+ return rc_manager;
+
+ if (S_ISLNK (st.st_mode)) {
+ /* only regular files and directories can have extended file attributes. */
+ switch (rc_manager) {
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK:
+ /* we don't care whether the link-target is immutable.
+ * If the symlink points to another file, rc-manager=symlink anyway backs off.
+ * Otherwise, we would only check whether our internal resolv.conf is immutable. */
+ return NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE:
+ nm_assert_not_reached ();
+ /* fall-through */
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
+ case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
+ break;
+ }
+ }
+
+ fd = open (_PATH_RESCONF, O_RDONLY);
+ if (fd != -1) {
+ if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1)
+ immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL);
+ close (fd);
+ }
+ return immutable ? NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE : rc_manager;
}
- return immutable;
}
NM_DEFINE_SINGLETON_GETTER (NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER);
@@ -1537,8 +1571,6 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
if (nm_streq0 (mode, "none"))
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
- else if (_get_resconf_immutable ())
- rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE;
else {
const char *man;
@@ -1570,6 +1602,8 @@ again:
}
}
+ rc_manager = _check_resconf_immutable (rc_manager);
+
if (nm_streq0 (mode, "dnsmasq")) {
if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) {
_clear_plugin (self);