/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <resolv.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "alloc-util.h"
#include "dns-domain.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "label.h"
#include "ordered-set.h"
#include "resolved-conf.h"
#include "resolved-dns-server.h"
#include "resolved-resolv-conf.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "strv.h"
#include "tmpfile-util-label.h"

int manager_check_resolv_conf(const Manager *m) {
        struct stat st, own;

        assert(m);

        /* This warns only when our stub listener is disabled and /etc/resolv.conf is a symlink to
         * PRIVATE_STATIC_RESOLV_CONF. */

        if (m->dns_stub_listener_mode != DNS_STUB_LISTENER_NO)
                return 0;

        if (stat("/etc/resolv.conf", &st) < 0) {
                if (errno == ENOENT)
                        return 0;

                return log_warning_errno(errno, "Failed to stat /etc/resolv.conf: %m");
        }

        /* Is it symlinked to our own uplink file? */
        if (stat(PRIVATE_STATIC_RESOLV_CONF, &own) >= 0 &&
            stat_inode_same(&st, &own))
                return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                         "DNSStubListener= is disabled, but /etc/resolv.conf is a symlink to "
                                         PRIVATE_STATIC_RESOLV_CONF " which expects DNSStubListener= to be enabled.");

        return 0;
}

static bool file_is_our_own(const struct stat *st) {
        assert(st);

        FOREACH_STRING(path,
                       PRIVATE_UPLINK_RESOLV_CONF,
                       PRIVATE_STUB_RESOLV_CONF,
                       PRIVATE_STATIC_RESOLV_CONF) {

                struct stat own;

                /* Is it symlinked to our own uplink file? */
                if (stat(path, &own) >= 0 &&
                    stat_inode_same(st, &own))
                        return true;
        }

        return false;
}

int manager_read_resolv_conf(Manager *m) {
        _cleanup_fclose_ FILE *f = NULL;
        struct stat st;
        unsigned n = 0;
        int r;

        assert(m);

        /* Reads the system /etc/resolv.conf, if it exists and is not
         * symlinked to our own resolv.conf instance */

        if (!m->read_resolv_conf)
                return 0;

        r = stat("/etc/resolv.conf", &st);
        if (r < 0) {
                if (errno == ENOENT)
                        return 0;

                r = log_warning_errno(errno, "Failed to stat /etc/resolv.conf: %m");
                goto clear;
        }

        /* Have we already seen the file? */
        if (stat_inode_unmodified(&st, &m->resolv_conf_stat))
                return 0;

        if (file_is_our_own(&st))
                return 0;

        f = fopen("/etc/resolv.conf", "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                r = log_warning_errno(errno, "Failed to open /etc/resolv.conf: %m");
                goto clear;
        }

        if (fstat(fileno(f), &st) < 0) {
                r = log_error_errno(errno, "Failed to stat open file: %m");
                goto clear;
        }

        if (file_is_our_own(&st))
                return 0;

        dns_server_mark_all(m->dns_servers);
        dns_search_domain_mark_all(m->search_domains);

        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);
                if (IN_SET(*l, '#', ';', 0))
                        continue;

                a = first_word(l, "nameserver");
                if (a) {
                        r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_SYSTEM, a);
                        if (r < 0)
                                log_warning_errno(r, "Failed to parse DNS server address '%s', ignoring.", a);

                        continue;
                }

                a = first_word(l, "domain");
                if (!a) /* We treat "domain" lines, and "search" lines as equivalent, and add both to our list. */
                        a = first_word(l, "search");
                if (a) {
                        r = manager_parse_search_domains_and_warn(m, a);
                        if (r < 0)
                                log_warning_errno(r, "Failed to parse search domain string '%s', ignoring.", a);

                        continue;
                }

                log_syntax(NULL, LOG_DEBUG, "/etc/resolv.conf", n, 0, "Ignoring resolv.conf line: %s", l);
        }

        m->resolv_conf_stat = st;

        /* Flush out all servers and search domains that are still
         * marked. Those are then ones that didn't appear in the new
         * /etc/resolv.conf */
        dns_server_unlink_marked(m->dns_servers);
        dns_search_domain_unlink_marked(m->search_domains);

        /* Whenever /etc/resolv.conf changes, start using the first
         * DNS server of it. This is useful to deal with broken
         * network managing implementations (like NetworkManager),
         * that when connecting to a VPN place both the VPN DNS
         * servers and the local ones in /etc/resolv.conf. Without
         * resetting the DNS server to use back to the first entry we
         * will continue to use the local one thus being unable to
         * resolve VPN domains. */
        manager_set_dns_server(m, m->dns_servers);

        /* Unconditionally flush the cache when /etc/resolv.conf is
         * modified, even if the data it contained was completely
         * identical to the previous version we used. We do this
         * because altering /etc/resolv.conf is typically done when
         * the network configuration changes, and that should be
         * enough to flush the global unicast DNS cache. */
        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:
        dns_server_unlink_all(m->dns_servers);
        dns_search_domain_unlink_all(m->search_domains);
        return r;
}

static void write_resolv_conf_server(DnsServer *s, FILE *f, unsigned *count) {
        DnsScope *scope;

        assert(s);
        assert(f);
        assert(count);

        if (!dns_server_string(s)) {
                log_warning("Out of memory, or invalid DNS address. Ignoring server.");
                return;
        }

        /* resolv.conf simply doesn't support any other ports than 53, hence there's nothing much we can
         * do — we have to suppress these entries */
        if (dns_server_port(s) != 53) {
                log_debug("DNS server %s with non-standard UDP port number, suppressing from generated resolv.conf.", dns_server_string(s));
                return;
        }

        /* Check if the scope this DNS server belongs to is suitable as 'default' route for lookups; 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) */
        scope = dns_server_scope(s);
        if (scope && !dns_scope_is_default_route(scope)) {
                log_debug("Scope of DNS server %s has only 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);
        (*count)++;

        fprintf(f, "nameserver %s\n", dns_server_string(s));
}

static void write_resolv_conf_search(
                OrderedSet *domains,
                FILE *f) {
        char *domain;

        assert(domains);
        assert(f);

        fputs("search", f);

        ORDERED_SET_FOREACH(domain, domains) {
                fputc(' ', f);
                fputs(domain, f);
        }

        fputs("\n", f);
}

static int write_uplink_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {

        fputs("# This is "PRIVATE_UPLINK_RESOLV_CONF" managed by man:systemd-resolved(8).\n"
              "# Do not edit.\n"
              "#\n"
              "# This file might be symlinked as /etc/resolv.conf. If you're looking at\n"
              "# /etc/resolv.conf and seeing this text, you have followed the symlink.\n"
              "#\n"
              "# This is a dynamic resolv.conf file for connecting local clients directly to\n"
              "# all known uplink DNS servers. This file lists all configured search domains.\n"
              "#\n"
              "# Third party programs should typically not access this file directly, but only\n"
              "# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a\n"
              "# different way, 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);
        else {
                unsigned count = 0;
                DnsServer *s;

                ORDERED_SET_FOREACH(s, dns)
                        write_resolv_conf_server(s, f, &count);
        }

        if (ordered_set_isempty(domains))
                fputs("search .\n", f); /* Make sure that if the local hostname is chosen as fqdn this does not
                                         * imply a search domain */
        else
                write_resolv_conf_search(domains, f);

        return fflush_and_check(f);
}

static int write_stub_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
        fputs("# This is "PRIVATE_STUB_RESOLV_CONF" managed by man:systemd-resolved(8).\n"
              "# Do not edit.\n"
              "#\n"
              "# This file might be symlinked as /etc/resolv.conf. If you're looking at\n"
              "# /etc/resolv.conf and seeing this text, you have followed the symlink.\n"
              "#\n"
              "# This is a dynamic resolv.conf file for connecting local clients to the\n"
              "# internal DNS stub resolver of systemd-resolved. This file lists all\n"
              "# configured search domains.\n"
              "#\n"
              "# Run \"resolvectl status\" to see details about the uplink DNS servers\n"
              "# currently in use.\n"
              "#\n"
              "# Third party programs should typically not access this file directly, but only\n"
              "# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a\n"
              "# different way, 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"
              "nameserver 127.0.0.53\n"
              "options edns0 trust-ad\n", f);

        if (ordered_set_isempty(domains))
                fputs("search .\n", f); /* Make sure that if the local hostname is chosen as fqdn this does not
                                         * imply a search domain */
        else
                write_resolv_conf_search(domains, f);

        return fflush_and_check(f);
}

int manager_write_resolv_conf(Manager *m) {
        _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL;
        _cleanup_(unlink_and_freep) char *temp_path_uplink = NULL, *temp_path_stub = NULL;
        _cleanup_fclose_ FILE *f_uplink = NULL, *f_stub = NULL;
        int r;

        assert(m);

        /* Read the system /etc/resolv.conf first */
        (void) manager_read_resolv_conf(m);

        /* Add the full list to a set, to filter out duplicates */
        r = manager_compile_dns_servers(m, &dns);
        if (r < 0)
                return log_warning_errno(r, "Failed to compile list of DNS servers, ignoring: %m");

        r = manager_compile_search_domains(m, &domains, false);
        if (r < 0)
                return log_warning_errno(r, "Failed to compile list of search domains, ignoring: %m");

        r = fopen_temporary_label(PRIVATE_UPLINK_RESOLV_CONF, PRIVATE_UPLINK_RESOLV_CONF, &f_uplink, &temp_path_uplink);
        if (r < 0)
                return log_warning_errno(r, "Failed to open new %s for writing, ignoring: %m", PRIVATE_UPLINK_RESOLV_CONF);

        (void) fchmod(fileno(f_uplink), 0644);

        r = write_uplink_resolv_conf_contents(f_uplink, dns, domains);
        if (r < 0)
                return log_warning_errno(r, "Failed to write new %s, ignoring: %m", PRIVATE_UPLINK_RESOLV_CONF);

        if (m->dns_stub_listener_mode != DNS_STUB_LISTENER_NO) {
                r = fopen_temporary_label(PRIVATE_STUB_RESOLV_CONF, PRIVATE_STUB_RESOLV_CONF, &f_stub, &temp_path_stub);
                if (r < 0)
                        return log_warning_errno(r, "Failed to open new %s for writing, ignoring: %m", PRIVATE_STUB_RESOLV_CONF);

                (void) fchmod(fileno(f_stub), 0644);

                r = write_stub_resolv_conf_contents(f_stub, dns, domains);
                if (r < 0)
                        return log_warning_errno(r, "Failed to write new %s, ignoring: %m", PRIVATE_STUB_RESOLV_CONF);

                r = conservative_rename(temp_path_stub, PRIVATE_STUB_RESOLV_CONF);
                if (r < 0)
                        log_warning_errno(r, "Failed to move new %s into place, ignoring: %m", PRIVATE_STUB_RESOLV_CONF);

                temp_path_stub = mfree(temp_path_stub); /* free the string explicitly, so that we don't unlink anymore */
        } else {
                r = symlink_atomic_label(basename(PRIVATE_UPLINK_RESOLV_CONF), PRIVATE_STUB_RESOLV_CONF);
                if (r < 0)
                        log_warning_errno(r, "Failed to symlink %s, ignoring: %m", PRIVATE_STUB_RESOLV_CONF);
        }

        r = conservative_rename(temp_path_uplink, PRIVATE_UPLINK_RESOLV_CONF);
        if (r < 0)
                log_warning_errno(r, "Failed to move new %s into place: %m", PRIVATE_UPLINK_RESOLV_CONF);

        temp_path_uplink = mfree(temp_path_uplink); /* free the string explicitly, so that we don't unlink anymore */
        return r;
}

int resolv_conf_mode(void) {
        static const char * const table[_RESOLV_CONF_MODE_MAX] = {
                [RESOLV_CONF_UPLINK] = PRIVATE_UPLINK_RESOLV_CONF,
                [RESOLV_CONF_STUB] = PRIVATE_STUB_RESOLV_CONF,
                [RESOLV_CONF_STATIC] = PRIVATE_STATIC_RESOLV_CONF,
        };

        struct stat system_st;

        if (stat("/etc/resolv.conf", &system_st) < 0) {
                if (errno == ENOENT)
                        return RESOLV_CONF_MISSING;

                return -errno;
        }

        for (ResolvConfMode m = 0; m < _RESOLV_CONF_MODE_MAX; m++) {
                struct stat our_st;

                if (!table[m])
                        continue;

                if (stat(table[m], &our_st) < 0) {
                        if (errno != ENOENT)
                                log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", table[m]);

                        continue;
                }

                if (stat_inode_same(&system_st, &our_st))
                        return m;
        }

        return RESOLV_CONF_FOREIGN;
}

static const char* const resolv_conf_mode_table[_RESOLV_CONF_MODE_MAX] = {
        [RESOLV_CONF_UPLINK] = "uplink",
        [RESOLV_CONF_STUB] = "stub",
        [RESOLV_CONF_STATIC] = "static",
        [RESOLV_CONF_MISSING] = "missing",
        [RESOLV_CONF_FOREIGN] = "foreign",
};
DEFINE_STRING_TABLE_LOOKUP(resolv_conf_mode, ResolvConfMode);
