diff --git a/NEWS b/NEWS
index 533b46a18..62f6be58e 100644
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,8 @@ Notable changes included in this snapshot so far include:
documentation. This represents a change in behavior since previous
versions where the first character of the string was used as
type. The internal client is not affected by the change.
+* DNS setting rc-manager=file now always follows dangling symlinks
+ instead of replacing /etc/resolv.conf with a plain file.
The following features were backported to 1.10.x releases from 1.10.0 to
1.10.8 are also present in NetworkManager-1.12:
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 6f333acd6..8a1b04bc0 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -367,8 +367,10 @@ no-auto-default=*
file: NetworkManager will write
/etc/resolv.conf as file. If it finds
a symlink to an existing target, it will follow the symlink and
- update the target instead. If the symlink's target does not exist,
- the symlink will be replaced by a file.
+ update the target instead. In no case will an existing symlink
+ be replaced by a file. Note that older versions of NetworkManager
+ behaved differently and would replace dangling symlinks with a
+ plain file.
resolvconf: NetworkManager will run
resolvconf to update the DNS configuration.
netconfig: NetworkManager will run
diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c
index 354520b3a..a29fd81f4 100644
--- a/src/dns/nm-dns-manager.c
+++ b/src/dns/nm-dns-manager.c
@@ -792,18 +792,27 @@ update_resolv_conf (NMDnsManager *self,
if ( rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE
|| ( rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK
&& !_read_link_cached (_PATH_RESCONF, &resconf_link_cached, &resconf_link))) {
+ gs_free char *rc_path_syml = NULL;
nm_auto_free char *rc_path_real = NULL;
const char *rc_path = _PATH_RESCONF;
GError *local = NULL;
if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE) {
- /* Note that if /etc/resolv.conf is a dangling symlink, realpath()
- * will return %NULL, and thus below we will replace the symlink
- * with a file. This is the only case, in which NetworkManager
- * replaces an existing symlink with a file.*/
- rc_path_real = realpath (rc_path, NULL);
+ rc_path_real = realpath (_PATH_RESCONF, NULL);
if (rc_path_real)
rc_path = rc_path_real;
+ else {
+ /* realpath did not resolve a path-name. That either means,
+ * _PATH_RESCONF:
+ * - does not exist
+ * - is a plain file
+ * - is a dangling symlink
+ *
+ * Handle the case, where it is a dangling symlink... */
+ rc_path_syml = nm_utils_read_link_absolute (_PATH_RESCONF, NULL);
+ if (rc_path_syml)
+ rc_path = rc_path_syml;
+ }
}
/* we first write to /etc/resolv.conf directly. If that fails,