Thomas Haller 2023-05-02 11:48:12 +02:00
commit 86e635dd4d
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 53 additions and 11 deletions

2
NEWS
View file

@ -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

View file

@ -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;