X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fresolve%2Fresolved-resolv-conf.c;h=e3d6a3340934a7ce63e4f5b48241f00477d2e2fc;hb=59c0fd0e17e485d551daa9cd26fa0cfc726085b0;hp=ae17aef3ab78936cc404691fd12a14fd2b7ee45a;hpb=7207052d252615b2e991b1f1e8eda79869193f09;p=thirdparty%2Fsystemd.git diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c index ae17aef3ab7..e3d6a334093 100644 --- a/src/resolve/resolved-resolv-conf.c +++ b/src/resolve/resolved-resolv-conf.c @@ -26,6 +26,7 @@ #include "fileio.h" #include "ordered-set.h" #include "resolved-conf.h" +#include "resolved-dns-server.h" #include "resolved-resolv-conf.h" #include "string-util.h" #include "strv.h" @@ -60,7 +61,7 @@ int manager_read_resolv_conf(Manager *m) { return 0; /* Is it symlinked to our own file? */ - if (stat("/run/systemd/resolve/resolv.conf", &own) >= 0 && + if (stat(PRIVATE_RESOLV_CONF, &own) >= 0 && st.st_dev == own.st_dev && st.st_ino == own.st_ino) return 0; @@ -87,7 +88,7 @@ int manager_read_resolv_conf(Manager *m) { char *l; l = strstrip(line); - if (*l == '#' || *l == ';') + if (IN_SET(*l, '#', ';')) continue; a = first_word(l, "nameserver"); @@ -136,6 +137,11 @@ int manager_read_resolv_conf(Manager *m) { if (m->unicast_scope) dns_cache_flush(&m->unicast_scope->cache); + /* If /etc/resolv.conf changed, make sure to forget everything we learned about the DNS servers. After all we + * might now talk to a very different DNS server that just happens to have the same IP address as an old one + * (think 192.168.1.1). */ + dns_server_reset_features_all(m->dns_servers); + return 0; clear: @@ -154,8 +160,18 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) { return; } + /* Check if the DNS server is limited to particular domains; + * resolv.conf does not have a syntax to express that, so it must not + * appear as a global name server to avoid routing unrelated domains to + * it (which is a privacy violation, will most probably fail anyway, + * and adds unnecessary load) */ + if (dns_server_limited_domains(s)) { + log_debug("DNS server %s has route-only domains, not using as global name server", dns_server_string(s)); + return; + } + if (*count == MAXNS) - fputs("# Too many DNS servers configured, the following entries may be ignored.\n", f); + fputs_unlocked("# Too many DNS servers configured, the following entries may be ignored.\n", f); (*count)++; fprintf(f, "nameserver %s\n", dns_server_string(s)); @@ -171,36 +187,39 @@ static void write_resolv_conf_search( assert(domains); assert(f); - fputs("search", f); + fputs_unlocked("search", f); ORDERED_SET_FOREACH(domain, domains, i) { if (++count > MAXDNSRCH) { - fputs("\n# Too many search domains configured, remaining ones ignored.", f); + fputs_unlocked("\n# Too many search domains configured, remaining ones ignored.", f); break; } length += strlen(domain) + 1; if (length > 256) { - fputs("\n# Total length of all search domains is too long, remaining ones ignored.", f); + fputs_unlocked("\n# Total length of all search domains is too long, remaining ones ignored.", f); break; } - fputc(' ', f); - fputs(domain, f); + fputc_unlocked(' ', f); + fputs_unlocked(domain, f); } - fputs("\n", f); + fputs_unlocked("\n", f); } static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) { Iterator i; - fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n" - "# Third party programs must not access this file directly, but\n" - "# only through the symlink at /etc/resolv.conf. To manage\n" - "# resolv.conf(5) in a different way, replace the symlink by a\n" - "# static file or a different symlink.\n\n", f); + fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n" + "# This is a dynamic resolv.conf file for connecting local clients directly to\n" + "# all known DNS servers.\n#\n" + "# Third party programs must not access this file directly, but only through the\n" + "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n" + "# replace this symlink by a static file or a different symlink.\n#\n" + "# See man:systemd-resolved.service(8) for details about the supported modes of\n" + "# operation for /etc/resolv.conf.\n\n", f); if (ordered_set_isempty(dns)) - fputs("# No DNS servers known.\n", f); + fputs_unlocked("# No DNS servers known.\n", f); else { unsigned count = 0; DnsServer *s; @@ -232,7 +251,7 @@ int manager_write_resolv_conf(Manager *m) { if (r < 0) return log_warning_errno(r, "Failed to compile list of DNS servers: %m"); - r = manager_compile_search_domains(m, &domains); + r = manager_compile_search_domains(m, &domains, false); if (r < 0) return log_warning_errno(r, "Failed to compile list of search domains: %m");