summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-05-02 11:48:12 +0200
committerThomas Haller <thaller@redhat.com>2023-05-02 11:48:12 +0200
commit86e635dd4d517c2086aed6352b42fe30b5f8e4fc (patch)
tree8015bffa7a8115d702e72ea7c331eeead409165a
parentcb6f8b987c2b34d1ad325a0faf5a3a9d1d661ce2 (diff)
parent6a4097fe0b9655130ff7803ca6f550ce99d77aa6 (diff)
dns: merge branch 'ts/1281-resolv-conf-non-public-tld'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1281 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1613
-rw-r--r--NEWS2
-rw-r--r--src/core/dns/nm-dns-manager.c62
2 files changed, 53 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 11df54b83f..57bd987e72 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Setting "connection.stable-id=default${CONNECTION}" changed behavior to
be identical to the built-in default value when the stable-id is not set.
+* When configuring hostnames in non-public TLD (like "example.local"), use
+ the TLD as default search domain instead of the full hostname.
=============================================
NetworkManager-1.42
diff --git a/src/core/dns/nm-dns-manager.c b/src/core/dns/nm-dns-manager.c
index fb65afcadc..2eeb48f21a 100644
--- a/src/core/dns/nm-dns-manager.c
+++ b/src/core/dns/nm-dns-manager.c
@@ -173,14 +173,46 @@ NM_DEFINE_SINGLETON_GETTER(NMDnsManager, nm_dns_manager_get, NM_TYPE_DNS_MANAGER
/*****************************************************************************/
static gboolean
-domain_is_valid(const char *domain, gboolean check_public_suffix)
+domain_is_valid(const char *domain,
+ gboolean reject_public_suffix,
+ gboolean assume_any_tld_is_public)
{
if (*domain == '\0')
return FALSE;
-#if WITH_LIBPSL
- if (check_public_suffix && psl_is_public_suffix(psl_builtin(), domain))
- return FALSE;
+
+ if (reject_public_suffix) {
+ int is_pub;
+
+#if !WITH_LIBPSL
+ /* Without libpsl, we cannot detect that the domain is a public suffix, we assume
+ * the domain is not and valid. */
+ is_pub = FALSE;
+#elif defined(PSL_TYPE_NO_STAR_RULE)
+ /*
+ * If we use PSL_TYPE_ANY, any TLD (top-level domain, i.e., domain
+ * with no dots) is considered *public* by the PSL library even if
+ * it is *not* on the official suffix list. This is the implicit
+ * behavior of the older API function psl_is_public_suffix().
+ * To inhibit that and only deem TLDs explicitly listed in the PSL
+ * as public, we need to turn off the "prevailing star rule" with
+ * PSL_TYPE_NO_STAR_RULE.
+ * For documentation on psl_is_public_suffix2(), see:
+ * https://rockdaboot.github.io/libpsl/libpsl-Public-Suffix-List-functions.html#psl-is-public-suffix2
+ * For more on the public suffix format, including wildcards:
+ * https://github.com/publicsuffix/list/wiki/Format#format
+ */
+ is_pub =
+ psl_is_public_suffix2(psl_builtin(),
+ domain,
+ assume_any_tld_is_public ? PSL_TYPE_ANY : PSL_TYPE_NO_STAR_RULE);
+#else
+ is_pub = psl_is_public_suffix(psl_builtin(), domain);
#endif
+
+ if (is_pub)
+ return FALSE;
+ }
+
return TRUE;
}
@@ -533,7 +565,7 @@ add_dns_domains(GPtrArray *array,
str = searches[i];
if (!include_routing && domain_is_routing(str))
continue;
- if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE))
+ if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE))
continue;
add_string_item(array, str, dup);
}
@@ -542,7 +574,7 @@ add_dns_domains(GPtrArray *array,
str = domains[i];
if (!include_routing && domain_is_routing(str))
continue;
- if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE))
+ if (!domain_is_valid(nm_utils_parse_dns_domain(str, NULL), FALSE, TRUE))
continue;
add_string_item(array, str, dup);
}
@@ -1236,7 +1268,7 @@ merge_global_dns_config(NMResolvConfData *rc, NMGlobalDnsConfig *global_conf)
for (i = 0; searches[i]; i++) {
if (domain_is_routing(searches[i]))
continue;
- if (!domain_is_valid(searches[i], FALSE))
+ if (!domain_is_valid(searches[i], FALSE, TRUE))
continue;
add_string_item(rc->searches, searches[i], TRUE);
}
@@ -2100,7 +2132,8 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s
/* Certain hostnames we don't want to include in resolv.conf 'searches' */
if (hostname && nm_utils_is_specific_hostname(hostname)
- && !g_str_has_suffix(hostname, ".in-addr.arpa") && !nm_inet_is_valid(AF_UNSPEC, hostname)) {
+ && !NM_STR_HAS_SUFFIX(hostname, ".in-addr.arpa")
+ && !nm_inet_is_valid(AF_UNSPEC, hostname)) {
domain = strchr(hostname, '.');
if (domain) {
domain++;
@@ -2111,11 +2144,16 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s
* specified, this makes a good default.) However, if the
* hostname is the top level of a domain (eg, "example.com"),
* then use the hostname itself as the search (since the user
- * is unlikely to want "com" as a search domain).a
+ * is unlikely to want "com" as a search domain).
+ *
+ * Because that logic only applies to public domains, the
+ * "assume_any_tld_is_public" parameter is FALSE. For
+ * example, it is likely that the user *does* want "local"
+ * or "localdomain" as a search domain.
*/
- if (domain_is_valid(domain, TRUE)) {
+ if (domain_is_valid(domain, TRUE, FALSE)) {
/* pass */
- } else if (domain_is_valid(hostname, TRUE)) {
+ } else if (domain_is_valid(hostname, TRUE, FALSE)) {
domain = hostname;
}
@@ -2127,6 +2165,8 @@ nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean s
if (!nm_strdup_reset(&priv->hostdomain, domain))
return;
+ _LOGT("set host domain to %s%s%s", NM_PRINT_FMT_QUOTE_STRING(priv->hostdomain));
+
if (skip_update)
return;