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,