diff options
author | Thomas Haller <thaller@redhat.com> | 2018-09-21 11:15:09 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-09-21 11:15:09 +0200 |
commit | 121e2dea12031e05e69d139d2036915f031a5d47 (patch) | |
tree | 2ed9d504bcd3f263f4d79ddfd22974c0b67385e5 | |
parent | bbc88cd07f6385ebfea1204b76b9f2d52f052c63 (diff) | |
parent | cddb91324c4d7c86fe9f21a1fc97f92dd47a1ee5 (diff) | |
download | NetworkManager-121e2dea12031e05e69d139d2036915f031a5d47.tar.gz |
dns: merge branch 'th/dns-stub-resolv-conf'
https://github.com/NetworkManager/NetworkManager/pull/200
-rw-r--r-- | clients/cli/connections.c | 3 | ||||
-rw-r--r-- | man/NetworkManager.conf.xml | 16 | ||||
-rw-r--r-- | shared/nm-utils/nm-io-utils.c | 2 | ||||
-rw-r--r-- | src/dns/nm-dns-manager.c | 104 |
4 files changed, 70 insertions, 55 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index eae50afc39..f2a0d1e4bc 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -30,6 +30,7 @@ #include <netinet/ether.h> #include <readline/readline.h> #include <readline/history.h> +#include <fcntl.h> #include "nm-client-utils.h" #include "nm-vpn-helpers.h" @@ -8864,7 +8865,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv) else { nm_auto_close int fd = -1; - fd = g_mkstemp (tmpfile); + fd = g_mkstemp_full (tmpfile, O_RDWR | O_CLOEXEC, 0600); if (fd == -1) { g_string_printf (nmc->return_text, _("Error: failed to create temporary file %s."), tmpfile); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 87cf001621..6735af5fd4 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -306,8 +306,8 @@ no-auto-default=* </varlistentry> <varlistentry> <term><varname>dns</varname></term> - <listitem><para>Set the DNS (<filename>resolv.conf</filename>) processing mode. - If the key is unspecified, <literal>default</literal> is used, + <listitem><para>Set the DNS processing mode.</para> + <para>If the key is unspecified, <literal>default</literal> is used, unless <filename>/etc/resolv.conf</filename> is a symlink to <filename>/run/systemd/resolve/stub-resolv.conf</filename>, <filename>/run/systemd/resolve/resolv.conf</filename>, @@ -331,15 +331,23 @@ no-auto-default=* after some time. This behavior can be modified passing the 'all-servers' or 'strict-order' options to dnsmasq (see the manual page for more details).</para> + <para><literal>systemd-resolved</literal>: NetworkManager will + push the DNS configuration to systemd-resolved</para> <para><literal>unbound</literal>: NetworkManager will talk to unbound and dnssec-triggerd, providing a "split DNS" configuration with DNSSEC support. <filename>/etc/resolv.conf</filename> will be managed by dnssec-trigger daemon.</para> - <para><literal>systemd-resolved</literal>: NetworkManager will - push the DNS configuration to systemd-resolved</para> <para><literal>none</literal>: NetworkManager will not modify resolv.conf. This implies <literal>rc-manager</literal> <literal>unmanaged</literal></para> + + <para>Note that the plugins <literal>dnsmasq</literal>, <literal>systemd-resolved</literal> + and <literal>unbound</literal> are caching local nameservers. + Hence, when NetworkManager writes <filename>&nmrundir;/resolv.conf</filename> + and <filename>/etc/resolv.conf</filename> (according to <literal>rc-manager</literal> + setting below), the name server there will be localhost only. + NetworkManager also writes a file <filename>&nmrundir;/no-stub-resolv.conf</filename> + that contains the original name servers pushed to the DNS plugin.</para> </listitem> </varlistentry> diff --git a/shared/nm-utils/nm-io-utils.c b/shared/nm-utils/nm-io-utils.c index 88cb13ff18..b64c09dece 100644 --- a/shared/nm-utils/nm-io-utils.c +++ b/shared/nm-utils/nm-io-utils.c @@ -351,7 +351,7 @@ nm_utils_file_set_contents (const char *filename, length = strlen (contents); tmp_name = g_strdup_printf ("%s.XXXXXX", filename); - fd = g_mkstemp_full (tmp_name, O_RDWR, mode); + fd = g_mkstemp_full (tmp_name, O_RDWR | O_CLOEXEC, mode); if (fd < 0) { errsv = errno; g_set_error (error, diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 6a59b41c7b..62ea02b755 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -586,49 +586,42 @@ create_resolv_conf (char **searches, char **nameservers, char **options) { - gs_free char *searches_str = NULL; - gs_free char *nameservers_str = NULL; - gs_free char *options_str = NULL; - char *tmp_str; GString *str; - int i; + gsize i; - if (searches) { - tmp_str = g_strjoinv (" ", searches); - searches_str = g_strconcat ("search ", tmp_str, "\n", NULL); - g_free (tmp_str); - } + str = g_string_new_len ("# Generated by NetworkManager\n", 245); - if (options) { - tmp_str = g_strjoinv (" ", options); - options_str = g_strconcat ("options ", tmp_str, "\n", NULL); - g_free (tmp_str); + if (searches && searches[0]) { + g_string_append (str, "search"); + for (i = 0; searches[i]; i++) { + g_string_append_c (str, ' '); + g_string_append (str, searches[i]); + } + g_string_append_c (str, '\n'); } - if (nameservers) { - int num = g_strv_length (nameservers); - - str = g_string_new (""); - for (i = 0; i < num; i++) { + if (nameservers && nameservers[0]) { + for (i = 0; nameservers[i]; i++) { if (i == 3) { - g_string_append (str, "# "); - g_string_append (str, "NOTE: the libc resolver may not support more than 3 nameservers."); - g_string_append (str, "\n# "); - g_string_append (str, "The nameservers listed below may not be recognized."); - g_string_append_c (str, '\n'); + g_string_append (str, "# NOTE: the libc resolver may not support more than 3 nameservers.\n"); + g_string_append (str, "# The nameservers listed below may not be recognized.\n"); } - g_string_append (str, "nameserver "); g_string_append (str, nameservers[i]); g_string_append_c (str, '\n'); } - nameservers_str = g_string_free (str, FALSE); } - return g_strdup_printf ("# Generated by NetworkManager\n%s%s%s", - searches_str ?: "", - nameservers_str ?: "", - options_str ?: ""); + if (options && options[0]) { + g_string_append (str, "options"); + for (i = 0; options[i]; i++) { + g_string_append_c (str, ' '); + g_string_append (str, options[i]); + } + g_string_append_c (str, '\n'); + } + + return g_string_free (str, FALSE); } static gboolean @@ -751,9 +744,36 @@ _read_link_cached (const char *path, gboolean *is_cached, char **cached) return (*cached = g_file_read_link (path, NULL)); } -#define MY_RESOLV_CONF NMRUNDIR "/resolv.conf" -#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF ".tmp" -#define RESOLV_CONF_TMP "/etc/.resolv.conf.NetworkManager" +#define MY_RESOLV_CONF NMRUNDIR"/resolv.conf" +#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF".tmp" +#define RESOLV_CONF_TMP "/etc/.resolv.conf.NetworkManager" + +#define NO_STUB_RESOLV_CONF NMRUNDIR "/no-stub-resolv.conf" + +static void +update_resolv_conf_no_stub (NMDnsManager *self, + char **searches, + char **nameservers, + char **options) +{ + gs_free char *content = NULL; + GError *local = NULL; + + content = create_resolv_conf (searches, nameservers, options); + + if (!g_file_set_contents (NO_STUB_RESOLV_CONF, + content, + -1, + &local)) { + _LOGD ("update-resolv-no-stub: failure to write file: %s", + local->message); + g_error_free (local); + return; + } + + _LOGT ("update-resolv-no-stub: '%s' successfully written", + NO_STUB_RESOLV_CONF); +} static SpawnResult update_resolv_conf (NMDnsManager *self, @@ -771,22 +791,6 @@ update_resolv_conf (NMDnsManager *self, gboolean resconf_link_cached = FALSE; gs_free char *resconf_link = NULL; - /* If we are not managing /etc/resolv.conf and it points to - * MY_RESOLV_CONF, don't write the private DNS configuration to - * MY_RESOLV_CONF otherwise we would overwrite the changes done by - * some external application. - * - * This is the only situation, where we don't try to update our - * internal resolv.conf file. */ - if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED) { - if (nm_streq0 (_read_link_cached (_PATH_RESCONF, &resconf_link_cached, &resconf_link), - MY_RESOLV_CONF)) { - _LOGD ("update-resolv-conf: not updating " _PATH_RESCONF - " since it points to " MY_RESOLV_CONF); - return SR_SUCCESS; - } - } - content = create_resolv_conf (searches, nameservers, options); if ( rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE @@ -1428,6 +1432,8 @@ update_dns (NMDnsManager *self, ; } + update_resolv_conf_no_stub (self, searches, nameservers, options); + /* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf * to ensure that the glibc resolver doesn't try to round-robin nameservers, * but only uses the local caching nameserver. |