mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-07 04:58:01 +02:00
dns: better detect systemd-resolved when checking for resolv.conf symlink
We autodetect systemd-resolved based on whether /etc/resolv.conf points to one of the well known files of systemd-resolved. Extend the check by also - follow symlinks and compare the absolute link target - open the file and compare the inodes for hard-linking Note that when NetworkManager starts, systemd-resolved might not have started yet. So, while comparing the inode is the best check, we also compare symlinks (g_file_read_link() and realpath()). Based-on-patch-by: Sam Morris <sam@robots.org.uk> https://github.com/NetworkManager/NetworkManager/pull/16 https://bugzilla.gnome.org/show_bug.cgi?id=779269
This commit is contained in:
parent
e70dfb4df7
commit
fae84b16f8
1 changed files with 53 additions and 17 deletions
|
|
@ -1642,32 +1642,68 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
|
||||||
static gboolean
|
static gboolean
|
||||||
_resolvconf_resolved_managed (void)
|
_resolvconf_resolved_managed (void)
|
||||||
{
|
{
|
||||||
static const char *const resolved_paths[] = {
|
static const char *const RESOLVED_PATHS[] = {
|
||||||
"/run/systemd/resolve/resolv.conf",
|
"/run/systemd/resolve/resolv.conf",
|
||||||
"/lib/systemd/resolv.conf",
|
"/lib/systemd/resolv.conf",
|
||||||
"/usr/lib/systemd/resolv.conf",
|
"/usr/lib/systemd/resolv.conf",
|
||||||
};
|
};
|
||||||
GFile *f;
|
struct stat st, st_test;
|
||||||
GFileInfo *info;
|
guint i;
|
||||||
gboolean ret = FALSE;
|
|
||||||
|
|
||||||
f = g_file_new_for_path (_PATH_RESCONF);
|
if (lstat (_PATH_RESCONF, &st) != 0)
|
||||||
info = g_file_query_info (f,
|
return FALSE;
|
||||||
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","\
|
|
||||||
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
|
|
||||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
if (info && g_file_info_get_is_symlink (info)) {
|
if (S_ISLNK (st.st_mode)) {
|
||||||
ret = nm_utils_strv_find_first ((gchar **) resolved_paths,
|
gs_free char *full_path = NULL;
|
||||||
G_N_ELEMENTS (resolved_paths),
|
nm_auto_free char *real_path = NULL;
|
||||||
g_file_info_get_symlink_target (info)) >= 0;
|
|
||||||
|
/* see if resolv.conf is a symlink with a target that is
|
||||||
|
* exactly like one of the candidates.
|
||||||
|
*
|
||||||
|
* This check will work for symlinks, even if the target
|
||||||
|
* does not exist and realpath() cannot resolve anything.
|
||||||
|
*
|
||||||
|
* We want to handle that, because systemd-resolved might not
|
||||||
|
* have started yet. */
|
||||||
|
full_path = g_file_read_link (_PATH_RESCONF, NULL);
|
||||||
|
if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS,
|
||||||
|
G_N_ELEMENTS (RESOLVED_PATHS),
|
||||||
|
full_path) >= 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* see if resolv.conf is a symlink that resolves exactly one
|
||||||
|
* of the candidate paths.
|
||||||
|
*
|
||||||
|
* This check will work for symlinks that can be resolved
|
||||||
|
* to a realpath, but the actual file might not exist.
|
||||||
|
*
|
||||||
|
* We want to handle that, because systemd-resolved might not
|
||||||
|
* have started yet. */
|
||||||
|
real_path = realpath (_PATH_RESCONF, NULL);
|
||||||
|
if (nm_utils_strv_find_first ((char **) RESOLVED_PATHS,
|
||||||
|
G_N_ELEMENTS (RESOLVED_PATHS),
|
||||||
|
real_path) >= 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* fall-through and resolve the symlink, to check the file
|
||||||
|
* it points to (below).
|
||||||
|
*
|
||||||
|
* This check is the most reliable, but it only works if
|
||||||
|
* systemd-resolved already started and created the file. */
|
||||||
|
if (stat (_PATH_RESCONF, &st) != 0)
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_clear_object(&info);
|
/* see if resolv.conf resolves to one of the candidate
|
||||||
g_clear_object(&f);
|
* paths (or whether it is hard-linked). */
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (RESOLVED_PATHS); i++) {
|
||||||
|
if ( stat (RESOLVED_PATHS[i], &st_test) == 0
|
||||||
|
&& st.st_dev == st_test.st_dev
|
||||||
|
&& st.st_ino == st_test.st_ino)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue