diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-03-30 13:29:55 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-30 13:29:55 +0200 |
commit | 414f59dad7502b1ca0ea492c47a48fd6914e08b6 (patch) | |
tree | 2a42339a813e4742688ed877c8e414e14cddbe41 | |
parent | selinux: do not crash if policy becomes unavailable after reload (diff) | |
parent | resolvectl: suppress warning about --type for names with a dot (diff) | |
download | systemd-414f59dad7502b1ca0ea492c47a48fd6914e08b6.tar.xz systemd-414f59dad7502b1ca0ea492c47a48fd6914e08b6.zip |
Merge pull request #19131 from keszybz/resolvectl-warn-less
Suppress warnings in resolvectl about --type=
-rw-r--r-- | src/resolve/meson.build | 2 | ||||
-rw-r--r-- | src/resolve/resolvectl.c | 29 | ||||
-rw-r--r-- | src/resolve/resolved-manager.c | 73 | ||||
-rw-r--r-- | src/resolve/resolved-util.c | 84 | ||||
-rw-r--r-- | src/resolve/resolved-util.h | 4 |
5 files changed, 124 insertions, 68 deletions
diff --git a/src/resolve/meson.build b/src/resolve/meson.build index e0568d71ac..b1d97736a3 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -13,6 +13,8 @@ basic_dns_sources = files(''' resolved-dns-answer.h resolved-dns-question.c resolved-dns-question.h + resolved-util.c + resolved-util.h dns-type.c dns-type.h '''.split()) diff --git a/src/resolve/resolvectl.c b/src/resolve/resolvectl.c index 2bd18d2c6d..52bbae3293 100644 --- a/src/resolve/resolvectl.c +++ b/src/resolve/resolvectl.c @@ -19,6 +19,7 @@ #include "format-table.h" #include "format-util.h" #include "gcrypt-util.h" +#include "hostname-util.h" #include "main-func.h" #include "missing_network.h" #include "netlink-util.h" @@ -31,6 +32,7 @@ #include "resolvectl.h" #include "resolved-def.h" #include "resolved-dns-packet.h" +#include "resolved-util.h" #include "socket-netlink.h" #include "sort-util.h" #include "stdio-util.h" @@ -441,6 +443,25 @@ static int idna_candidate(const char *name, char **ret) { return false; } +static bool single_label_nonsynthetic(const char *name) { + _cleanup_free_ char *first_label = NULL; + int r; + + if (!dns_name_is_single_label(name)) + return false; + + if (is_localhost(name) || is_gateway_hostname(name)) + return false; + + r = resolve_system_hostname(NULL, &first_label); + if (r < 0) { + log_warning_errno(r, "Failed to determine the hostname: %m"); + return false; + } + + return !streq(name, first_label); +} + static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_t type, bool warn_missing) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *req = NULL, *reply = NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -455,15 +476,15 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_ log_debug("Resolving %s %s %s (interface %s).", name, dns_class_to_string(class), dns_type_to_string(type), isempty(arg_ifname) ? "*" : arg_ifname); - if (dns_name_is_single_label(name)) - log_notice("(Note that search domains are not appended when resolving raw record types. " - "Please specify fully qualified domain names when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.)"); + if (dns_name_dot_suffixed(name) == 0 && single_label_nonsynthetic(name)) + log_notice("(Note that search domains are not appended when --type= is specified. " + "Please specify fully qualified domain names, or remove --type= switch from invocation in order to request regular hostname resolution.)"); r = idna_candidate(name, &idnafied); if (r < 0) return r; if (r > 0) - log_notice("(Note that IDNA translation is not applied when resolving raw record types. " + log_notice("(Note that IDNA translation is not applied when --type= is specified. " "Please specify translated domain names — i.e. '%s' — when resolving raw records, or remove --type= switch from invocation in order to request regular hostname resolution.", idnafied); diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index e815dacd7f..21154a7f85 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -33,6 +33,7 @@ #include "resolved-manager.h" #include "resolved-mdns.h" #include "resolved-resolv-conf.h" +#include "resolved-util.h" #include "resolved-varlink.h" #include "socket-util.h" #include "string-table.h" @@ -362,75 +363,17 @@ static int manager_clock_change_listen(Manager *m) { return 0; } -static int determine_hostname(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) { +static int determine_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) { _cleanup_free_ char *h = NULL, *n = NULL; -#if HAVE_LIBIDN2 - _cleanup_free_ char *utf8 = NULL; -#elif HAVE_LIBIDN - int k; -#endif - char label[DNS_LABEL_MAX]; - const char *p, *decoded; int r; assert(full_hostname); assert(llmnr_hostname); assert(mdns_hostname); - /* Extract and normalize the first label of the locally configured hostname, and check it's not "localhost". */ - - r = gethostname_strict(&h); - if (r < 0) - return log_debug_errno(r, "Can't determine system hostname: %m"); - - p = h; - r = dns_label_unescape(&p, label, sizeof label, 0); - if (r < 0) - return log_error_errno(r, "Failed to unescape hostname: %m"); - if (r == 0) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Couldn't find a single label in hostname."); - -#if HAVE_LIBIDN || HAVE_LIBIDN2 - r = dlopen_idn(); - if (r < 0) { - log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m"); - decoded = label; /* no decoding */ - } else -#endif - { -#if HAVE_LIBIDN2 - r = sym_idn2_to_unicode_8z8z(label, &utf8, 0); - if (r != IDN2_OK) - return log_error_errno(SYNTHETIC_ERRNO(EUCLEAN), - "Failed to undo IDNA: %s", sym_idn2_strerror(r)); - assert(utf8_is_valid(utf8)); - - r = strlen(utf8); - decoded = utf8; -#elif HAVE_LIBIDN - k = dns_label_undo_idna(label, r, label, sizeof label); - if (k < 0) - return log_error_errno(k, "Failed to undo IDNA: %m"); - if (k > 0) - r = k; - - if (!utf8_is_valid(label)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "System hostname is not UTF-8 clean."); - decoded = label; -#else - decoded = label; /* no decoding */ -#endif - } - - r = dns_label_escape_new(decoded, r, &n); + r = resolve_system_hostname(&h, &n); if (r < 0) - return log_error_errno(r, "Failed to escape hostname: %m"); - - if (is_localhost(n)) - return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), - "System hostname is 'localhost', ignoring."); + return r; r = dns_name_concat(n, "local", 0, mdns_hostname); if (r < 0) @@ -501,9 +444,11 @@ static int on_hostname_change(sd_event_source *es, int fd, uint32_t revents, voi assert(m); - r = determine_hostname(&full_hostname, &llmnr_hostname, &mdns_hostname); - if (r < 0) + r = determine_hostnames(&full_hostname, &llmnr_hostname, &mdns_hostname); + if (r < 0) { + log_warning_errno(r, "Failed to determine the local hostname and LLMNR/mDNS names, ignoring: %m"); return 0; /* ignore invalid hostnames */ + } llmnr_hostname_changed = !streq(llmnr_hostname, m->llmnr_hostname); if (streq(full_hostname, m->full_hostname) && @@ -546,7 +491,7 @@ static int manager_watch_hostname(Manager *m) { (void) sd_event_source_set_description(m->hostname_event_source, "hostname"); - r = determine_hostname(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname); + r = determine_hostnames(&m->full_hostname, &m->llmnr_hostname, &m->mdns_hostname); if (r < 0) { _cleanup_free_ char *d = NULL; diff --git a/src/resolve/resolved-util.c b/src/resolve/resolved-util.c new file mode 100644 index 0000000000..00abada426 --- /dev/null +++ b/src/resolve/resolved-util.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "dns-def.h" +#include "dns-domain.h" +#include "hostname-util.h" +#include "idn-util.h" +#include "resolved-util.h" +#include "utf8.h" + +int resolve_system_hostname(char **full_hostname, char **first_label) { + _cleanup_free_ char *h = NULL, *n = NULL; +#if HAVE_LIBIDN2 + _cleanup_free_ char *utf8 = NULL; +#elif HAVE_LIBIDN + int k; +#endif + char label[DNS_LABEL_MAX]; + const char *p, *decoded; + int r; + + /* Return the full hostname in *full_hostname, if nonnull. + * + * Extract and normalize the first label of the locally configured hostname, check it's not + * "localhost", and return it in *first_label, if nonnull. */ + + r = gethostname_strict(&h); + if (r < 0) + return log_debug_errno(r, "Can't determine system hostname: %m"); + + p = h; + r = dns_label_unescape(&p, label, sizeof label, 0); + if (r < 0) + return log_debug_errno(r, "Failed to unescape hostname: %m"); + if (r == 0) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Couldn't find a single label in hostname."); + +#if HAVE_LIBIDN || HAVE_LIBIDN2 + r = dlopen_idn(); + if (r < 0) { + log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m"); + decoded = label; /* no decoding */ + } else +#endif + { +#if HAVE_LIBIDN2 + r = sym_idn2_to_unicode_8z8z(label, &utf8, 0); + if (r != IDN2_OK) + return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN), + "Failed to undo IDNA: %s", sym_idn2_strerror(r)); + assert(utf8_is_valid(utf8)); + + r = strlen(utf8); + decoded = utf8; +#elif HAVE_LIBIDN + k = dns_label_undo_idna(label, r, label, sizeof label); + if (k < 0) + return log_debug_errno(k, "Failed to undo IDNA: %m"); + if (k > 0) + r = k; + + if (!utf8_is_valid(label)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "System hostname is not UTF-8 clean."); + decoded = label; +#else + decoded = label; /* no decoding */ +#endif + } + + r = dns_label_escape_new(decoded, r, &n); + if (r < 0) + return log_debug_errno(r, "Failed to escape hostname: %m"); + + if (is_localhost(n)) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "System hostname is 'localhost', ignoring."); + + if (full_hostname) + *full_hostname = TAKE_PTR(h); + if (first_label) + *first_label = TAKE_PTR(n); + return 0; +} diff --git a/src/resolve/resolved-util.h b/src/resolve/resolved-util.h new file mode 100644 index 0000000000..446b7c9f1b --- /dev/null +++ b/src/resolve/resolved-util.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +int resolve_system_hostname(char **full_hostname, char **first_label); |