core: preserve the domain when system hostname is truncated

Pass the full hostname to the DNS manager, so that the domain gets
added to resolv.conf even when the hostname was truncated.

Note that "hostname" argument for plugins's update() function is
currently unused. Don't remove that because it can be potentially
useful to set a global search domain based on the hostname, but change
it to carry the domain directly.
This commit is contained in:
Beniamino Galvani 2022-03-04 09:31:49 +01:00
parent 59f57e8a0b
commit 143f7b1df7
7 changed files with 44 additions and 38 deletions

View file

@ -848,7 +848,7 @@ static GVariant *
create_update_args(NMDnsDnsmasq *self,
const NMGlobalDnsConfig *global_config,
const CList *ip_data_lst_head,
const char *hostname)
const char *hostdomain)
{
GVariantBuilder servers;
const NMDnsConfigIPData *ip_data;
@ -1124,7 +1124,7 @@ static gboolean
update(NMDnsPlugin *plugin,
const NMGlobalDnsConfig *global_config,
const CList *ip_data_lst_head,
const char *hostname,
const char *hostdomain,
GError **error)
{
NMDnsDnsmasq *self = NM_DNS_DNSMASQ(plugin);
@ -1135,7 +1135,7 @@ update(NMDnsPlugin *plugin,
nm_clear_pointer(&priv->set_server_ex_args, g_variant_unref);
priv->set_server_ex_args =
g_variant_ref_sink(create_update_args(self, global_config, ip_data_lst_head, hostname));
g_variant_ref_sink(create_update_args(self, global_config, ip_data_lst_head, hostdomain));
send_dnsmasq_update(self);
return TRUE;

View file

@ -26,6 +26,7 @@
#include "libnm-core-intern/nm-core-internal.h"
#include "libnm-glib-aux/nm-str-buf.h"
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
#include "NetworkManagerUtils.h"
#include "devices/nm-device.h"
@ -97,7 +98,7 @@ typedef struct {
bool config_changed : 1;
char *hostname;
char *hostdomain;
guint updates_queue;
guint8 hash[HASH_LEN]; /* SHA1 hash of current DNS config */
@ -1260,24 +1261,8 @@ _collect_resolv_conf_data(NMDnsManager *self,
}
}
/* If the hostname is a FQDN ("dcbw.example.com"), then add the domain part of it
* ("example.com") to the searches list, to ensure that we can still resolve its
* non-FQ form ("dcbw") too. (Also, if there are no other search domains 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).
*/
if (priv->hostname) {
const char *hostdomain = strchr(priv->hostname, '.');
if (hostdomain && !nm_utils_ipaddr_is_valid(AF_UNSPEC, priv->hostname)) {
hostdomain++;
if (domain_is_valid(hostdomain, TRUE))
add_string_item(rc.searches, hostdomain, TRUE);
else if (domain_is_valid(priv->hostname, TRUE))
add_string_item(rc.searches, priv->hostname, TRUE);
}
}
if (priv->hostdomain)
add_string_item(rc.searches, priv->hostdomain, TRUE);
if (rc.has_trust_ad == NM_TERNARY_TRUE)
g_ptr_array_add(rc.options, g_strdup(NM_SETTING_DNS_OPTION_TRUST_AD));
@ -1695,7 +1680,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, gboolean force_emit, GError
nm_dns_plugin_update(priv->sd_resolve_plugin,
global_config,
_mgr_get_ip_data_lst_head(self),
priv->hostname,
priv->hostdomain,
NULL);
}
@ -1717,7 +1702,7 @@ update_dns(NMDnsManager *self, gboolean no_caching, gboolean force_emit, GError
if (!nm_dns_plugin_update(plugin,
global_config,
_mgr_get_ip_data_lst_head(self),
priv->hostname,
priv->hostdomain,
&plugin_error)) {
_LOGW("update-dns: plugin %s update failed: %s", plugin_name, plugin_error->message);
@ -2005,16 +1990,37 @@ done:
void
nm_dns_manager_set_hostname(NMDnsManager *self, const char *hostname, gboolean skip_update)
{
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self);
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self);
const char *domain = NULL;
/* Certain hostnames we don't want to include in resolv.conf 'searches' */
if (hostname && nm_utils_is_specific_hostname(hostname) && !strstr(hostname, ".in-addr.arpa")
&& strchr(hostname, '.')) {
/* pass */
} else
hostname = NULL;
if (hostname && nm_utils_is_specific_hostname(hostname)
&& !g_str_has_suffix(hostname, ".in-addr.arpa")
&& !nm_utils_ipaddr_is_valid(AF_UNSPEC, hostname)) {
domain = strchr(hostname, '.');
if (domain) {
domain++;
/* If the hostname is a FQDN ("dcbw.example.com"), then add
* the domain part of it ("example.com") to the searches list,
* to ensure that we can still resolve its non-FQ form
* ("dcbw") too. (Also, if there are no other search domains
* 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
*/
if (domain_is_valid(domain, TRUE)) {
/* pass */
} else if (domain_is_valid(hostname, TRUE)) {
domain = hostname;
}
if (!nm_strdup_reset(&priv->hostname, hostname))
if (!nm_sd_hostname_is_valid(domain, FALSE))
domain = NULL;
}
}
if (!nm_strdup_reset(&priv->hostdomain, domain))
return;
if (skip_update)
@ -2659,7 +2665,7 @@ finalize(GObject *object)
NMDnsManager *self = NM_DNS_MANAGER(object);
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE(self);
g_free(priv->hostname);
g_free(priv->hostdomain);
g_free(priv->mode);
G_OBJECT_CLASS(nm_dns_manager_parent_class)->finalize(object);

View file

@ -60,7 +60,7 @@ gboolean
nm_dns_plugin_update(NMDnsPlugin *self,
const NMGlobalDnsConfig *global_config,
const CList *ip_config_lst_head,
const char *hostname,
const char *hostdomain,
GError **error)
{
g_return_val_if_fail(NM_DNS_PLUGIN_GET_CLASS(self)->update != NULL, FALSE);
@ -68,7 +68,7 @@ nm_dns_plugin_update(NMDnsPlugin *self,
return NM_DNS_PLUGIN_GET_CLASS(self)->update(self,
global_config,
ip_config_lst_head,
hostname,
hostdomain,
error);
}

View file

@ -34,7 +34,7 @@ typedef struct {
gboolean (*update)(NMDnsPlugin *self,
const NMGlobalDnsConfig *global_config,
const CList *ip_config_lst_head,
const char *hostname,
const char *hostdomain,
GError **error);
void (*stop)(NMDnsPlugin *self);

View file

@ -551,7 +551,7 @@ static gboolean
update(NMDnsPlugin *plugin,
const NMGlobalDnsConfig *global_config,
const CList *ip_data_lst_head,
const char *hostname,
const char *hostdomain,
GError **error)
{
NMDnsSystemdResolved *self = NM_DNS_SYSTEMD_RESOLVED(plugin);

View file

@ -28,7 +28,7 @@ static gboolean
update(NMDnsPlugin *plugin,
const NMGlobalDnsConfig *global_config,
const CList *ip_config_lst_head,
const char *hostname,
const char *hostdomain,
GError **error)
{
char *argv[] = {DNSSEC_TRIGGER_PATH, "--async", "--update", NULL};

View file

@ -606,7 +606,7 @@ _set_hostname(NMPolicy *self, const char *new_hostname, const char *msg)
*/
priv->updating_dns = TRUE;
nm_dns_manager_set_hostname(priv->dns_manager,
priv->cur_hostname,
priv->cur_hostname_full,
all_devices_not_active(self));
priv->updating_dns = FALSE;
}