summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-09-21 11:15:09 +0200
committerThomas Haller <thaller@redhat.com>2018-09-21 11:15:09 +0200
commit121e2dea12031e05e69d139d2036915f031a5d47 (patch)
tree2ed9d504bcd3f263f4d79ddfd22974c0b67385e5
parentbbc88cd07f6385ebfea1204b76b9f2d52f052c63 (diff)
parentcddb91324c4d7c86fe9f21a1fc97f92dd47a1ee5 (diff)
downloadNetworkManager-121e2dea12031e05e69d139d2036915f031a5d47.tar.gz
dns: merge branch 'th/dns-stub-resolv-conf'
https://github.com/NetworkManager/NetworkManager/pull/200
-rw-r--r--clients/cli/connections.c3
-rw-r--r--man/NetworkManager.conf.xml16
-rw-r--r--shared/nm-utils/nm-io-utils.c2
-rw-r--r--src/dns/nm-dns-manager.c104
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>&nbsp;<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.