]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-resolv-conf.c
util-lib: don't include fileio.h from fileio-label.h
[thirdparty/systemd.git] / src / resolve / resolved-resolv-conf.c
index b0942b701ce115769bf656c559c669c9eb031b63..42225572f251206b68d38758d2f10d904363b1ed 100644 (file)
@@ -1,9 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-  This file is part of systemd.
-
-  Copyright 2014 Tom Gundersen <teg@jklm.no>
- ***/
 
 #include <resolv.h>
 #include <stdio_ext.h>
@@ -11,7 +6,6 @@
 #include "alloc-util.h"
 #include "dns-domain.h"
 #include "fd-util.h"
-#include "fileio-label.h"
 #include "fileio.h"
 #include "ordered-set.h"
 #include "resolved-conf.h"
 /* A resolv.conf file containing the domain data we learnt from uplink, but our own DNS server address. */
 #define PRIVATE_STUB_RESOLV_CONF "/run/systemd/resolve/stub-resolv.conf"
 
-/* A static resolv.conf file containing no domains, but only our own DNS sever address */
+/* A static resolv.conf file containing no domains, but only our own DNS server address */
 #define PRIVATE_STATIC_RESOLV_CONF ROOTLIBEXECDIR "/resolv.conf"
 
+int manager_check_resolv_conf(const Manager *m) {
+        const char *path;
+        struct stat st;
+        int r;
+
+        assert(m);
+
+        /* This warns only when our stub listener is disabled and /etc/resolv.conf is a symlink to
+         * PRIVATE_STATIC_RESOLV_CONF or PRIVATE_STUB_RESOLV_CONF. */
+
+        if (m->dns_stub_listener_mode != DNS_STUB_LISTENER_NO)
+                return 0;
+
+        r = stat("/etc/resolv.conf", &st);
+        if (r < 0) {
+                if (errno == ENOENT)
+                        return 0;
+
+                return log_warning_errno(errno, "Failed to stat /etc/resolv.conf: %m");
+        }
+
+        FOREACH_STRING(path,
+                       PRIVATE_STUB_RESOLV_CONF,
+                       PRIVATE_STATIC_RESOLV_CONF) {
+
+                struct stat own;
+
+                /* Is it symlinked to our own uplink file? */
+                if (stat(path, &own) >= 0 &&
+                    st.st_dev == own.st_dev &&
+                    st.st_ino == own.st_ino) {
+                        log_warning("DNSStubListener= is disabled, but /etc/resolv.conf is a symlink to %s "
+                                    "which expects DNSStubListener= to be enabled.", path);
+                        return -EOPNOTSUPP;
+                }
+        }
+
+        return 0;
+}
+
 static bool file_is_our_own(const struct stat *st) {
         const char *path;
 
@@ -54,7 +88,6 @@ static bool file_is_our_own(const struct stat *st) {
 int manager_read_resolv_conf(Manager *m) {
         _cleanup_fclose_ FILE *f = NULL;
         struct stat st;
-        char line[LINE_MAX];
         unsigned n = 0;
         int r;
 
@@ -102,10 +135,19 @@ int manager_read_resolv_conf(Manager *m) {
         dns_server_mark_all(m->dns_servers);
         dns_search_domain_mark_all(m->search_domains);
 
-        FOREACH_LINE(line, f, r = -errno; goto clear) {
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
                 const char *a;
                 char *l;
 
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to read /etc/resolv.conf: %m");
+                        goto clear;
+                }
+                if (r == 0)
+                        break;
+
                 n++;
 
                 l = strstrip(line);
@@ -179,7 +221,7 @@ static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
         assert(count);
 
         if (!dns_server_string(s)) {
-                log_warning("Our of memory, or invalid DNS address. Ignoring server.");
+                log_warning("Out of memory, or invalid DNS address. Ignoring server.");
                 return;
         }