summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2017-03-24 17:00:48 +0100
committerFrancesco Giudici <fgiudici@redhat.com>2017-03-24 17:00:48 +0100
commit017b7c2bb6545f48bfc9c0357769801a488a619a (patch)
treee41fae7c721bbea71576d93d1eb149e2231f57d6
parentf20bdebae9b8979953938599f9f45ecc00f9cd6a (diff)
parent70c768901b66cd14188c4def5470cd16b91c40ae (diff)
downloadNetworkManager-017b7c2bb6545f48bfc9c0357769801a488a619a.tar.gz
merge: branch 'fg/keep_externally_set_hostname-rh1422610'
https://bugzilla.redhat.com/show_bug.cgi?id=1422610 https://bugzilla.redhat.com/show_bug.cgi?id=1405275
-rw-r--r--man/NetworkManager.conf.xml28
-rw-r--r--src/nm-config.c2
-rw-r--r--src/nm-config.h1
-rw-r--r--src/nm-policy.c244
-rw-r--r--src/nm-policy.h17
-rw-r--r--src/settings/nm-settings.c22
-rw-r--r--src/settings/nm-settings.h3
7 files changed, 259 insertions, 58 deletions
diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml
index 251a2a36b6..1230347d83 100644
--- a/man/NetworkManager.conf.xml
+++ b/man/NetworkManager.conf.xml
@@ -277,6 +277,34 @@ no-auto-default=*
</varlistentry>
<varlistentry>
+ <term><varname>hostname-mode</varname></term>
+ <listitem>
+ <para>
+ Set the management mode of the hostname. This parameter will
+ affect only the transient hostname. If a valid static hostname is set,
+ NetworkManager will skip the update of the hostname despite the value of
+ this option. An hostname empty or equal to 'localhost', 'localhost6',
+ 'localhost.localdomain' or 'localhost6.localdomain' is considered invalid.
+ </para>
+ <para><literal>default</literal>: NetworkManager will update the hostname
+ with the one provided via DHCP on the main connection (the one with a default
+ route). If not present, the hostname will be updated to the last one set
+ outside NetworkManager. If it is not valid, NetworkManager will try to recover
+ the hostname from the reverse lookup of the IP address of the main connection.
+ If this fails too, the hostname will be set to 'localhost.localdomain'.
+ </para>
+ <para><literal>dhcp</literal>: NetworkManager will update the transient hostname
+ only with information coming from DHCP. No fallback nor reverse lookup will be
+ performed, but when the dhcp connection providing the hostname is deactivated,
+ the hostname is reset to the last hostname set outside NetworkManager or
+ 'localhost' if none valid is there.
+ </para>
+ <para><literal>none</literal>: NetworkManager will not manage the transient
+ hostname and will never set it.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>dns</varname></term>
<listitem><para>Set the DNS (<filename>resolv.conf</filename>) processing mode.
If the key is unspecified, <literal>default</literal> is used,
diff --git a/src/nm-config.c b/src/nm-config.c
index 32faace562..cb4e0853cf 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -659,7 +659,7 @@ read_config (GKeyFile *keyfile, gboolean is_base_config, const char *dirname, co
}
/* the config-group is internal to every configuration snippets. It doesn't make sense
- * to merge the into the global configuration, and it doesn't make sense to preserve the
+ * to merge it into the global configuration, and it doesn't make sense to preserve the
* group beyond this point. */
g_key_file_remove_group (kf, NM_CONFIG_KEYFILE_GROUP_CONFIG, NULL);
diff --git a/src/nm-config.h b/src/nm-config.h
index 9930df33e2..933d0b40d4 100644
--- a/src/nm-config.h
+++ b/src/nm-config.h
@@ -62,6 +62,7 @@
#define NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT "auth-polkit"
#define NM_CONFIG_KEYFILE_KEY_MAIN_DHCP "dhcp"
#define NM_CONFIG_KEYFILE_KEY_MAIN_DEBUG "debug"
+#define NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE "hostname-mode"
#define NM_CONFIG_KEYFILE_KEY_LOGGING_BACKEND "backend"
#define NM_CONFIG_KEYFILE_KEY_CONFIG_ENABLE "enable"
#define NM_CONFIG_KEYFILE_KEY_ATOMIC_SECTION_WAS ".was"
diff --git a/src/nm-policy.c b/src/nm-policy.c
index d8e083572b..80f9caedfa 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -47,6 +47,7 @@
#include "settings/nm-settings-connection.h"
#include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
+#include "nm-config.h"
/*****************************************************************************/
@@ -85,9 +86,12 @@ typedef struct {
guint schedule_activate_all_id; /* idle handler for schedule_activate_all(). */
+ NMPolicyHostnameMode hostname_mode;
char *orig_hostname; /* hostname at NM start time */
char *cur_hostname; /* hostname we want to assign */
- gboolean hostname_changed; /* TRUE if NM ever set the hostname */
+ char *last_hostname; /* last hostname NM set (to detect if someone else changed it in the meanwhile) */
+ gboolean changing_hostname; /* hostname set operation still in progress */
+ gboolean dhcp_hostname; /* current hostname was set from dhcp */
GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */
} NMPolicyPrivate;
@@ -413,22 +417,76 @@ settings_set_hostname_cb (const char *hostname,
gboolean result,
gpointer user_data)
{
+ NMPolicy *self = NM_POLICY (user_data);
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
int ret = 0;
if (!result) {
+ _LOGT (LOGD_DNS, "set-hostname: hostname set via dbus failed, fallback to \"sethostname\"");
ret = sethostname (hostname, strlen (hostname));
if (ret != 0) {
int errsv = errno;
- _LOGW (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
+ _LOGW (LOGD_DNS, "set-hostname: couldn't set the system hostname to '%s': (%d) %s",
hostname, errsv, strerror (errsv));
if (errsv == EPERM)
- _LOGW (LOGD_DNS, "you should use hostnamed when systemd hardening is in effect!");
+ _LOGW (LOGD_DNS, "set-hostname: you should use hostnamed when systemd hardening is in effect!");
}
}
+ priv->changing_hostname = FALSE;
if (!ret)
nm_dispatcher_call_hostname (NULL, NULL, NULL);
+ g_object_unref (self);
+}
+
+#define HOST_NAME_BUFSIZE (HOST_NAME_MAX + 2)
+
+static char *
+_get_hostname (NMPolicy *self, char **hostname)
+{
+ NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
+ char *buf;
+
+ g_assert (hostname && *hostname == NULL);
+
+ /* If there is an in-progress hostname change, return
+ * the last hostname set as would be set soon...
+ */
+ if (priv->changing_hostname) {
+ _LOGT (LOGD_DNS, "get-hostname: \"%s\" (last on set)", priv->last_hostname);
+ *hostname = g_strdup (priv->last_hostname);
+ return *hostname;
+ }
+
+ /* try to get the hostname via dbus... */
+ if (nm_settings_get_transient_hostname (priv->settings, hostname)) {
+ _LOGT (LOGD_DNS, "get-hostname: \"%s\" (from dbus)", *hostname);
+ return *hostname;
+ }
+
+ /* ...or retrieve it by yourself */
+ buf = g_malloc (HOST_NAME_BUFSIZE);
+ if (gethostname (buf, HOST_NAME_BUFSIZE -1) != 0) {
+ int errsv = errno;
+
+ _LOGT (LOGD_DNS, "get-hostname: couldn't get the system hostname: (%d) %s",
+ errsv, g_strerror (errsv));
+ g_free (buf);
+ return NULL;
+ }
+
+ /* the name may be truncated... */
+ buf[HOST_NAME_BUFSIZE - 1] = '\0';
+ if (strlen (buf) >= HOST_NAME_BUFSIZE -1) {
+ _LOGT (LOGD_DNS, "get-hostname: system hostname too long: \"%s\"", buf);
+ g_free (buf);
+ return NULL;
+ }
+
+ _LOGT (LOGD_DNS, "get-hostname: \"%s\"", buf);
+ *hostname = buf;
+ return *hostname;
}
static void
@@ -437,9 +495,8 @@ _set_hostname (NMPolicy *self,
const char *msg)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- char old_hostname[HOST_NAME_MAX + 1];
+ gs_free char *old_hostname = NULL;
const char *name;
- int ret;
/* The incoming hostname *can* be NULL, which will get translated to
* 'localhost.localdomain' or such in the hostname policy code, but we
@@ -453,20 +510,12 @@ _set_hostname (NMPolicy *self,
if (new_hostname)
g_clear_object (&priv->lookup_addr);
- if ( priv->orig_hostname
- && (priv->hostname_changed == FALSE)
- && g_strcmp0 (priv->orig_hostname, new_hostname) == 0) {
- /* Don't change the hostname or update DNS this is the first time we're
- * trying to change the hostname, and it's not actually changing.
- */
- } else if (g_strcmp0 (priv->cur_hostname, new_hostname) == 0) {
- /* Don't change the hostname or update DNS if the hostname isn't actually
- * going to change.
- */
- } else {
+ /* Update the DNS only if the hostname is actually
+ * going to change.
+ */
+ if (!nm_streq0 (priv->cur_hostname, new_hostname)) {
g_free (priv->cur_hostname);
priv->cur_hostname = g_strdup (new_hostname);
- priv->hostname_changed = TRUE;
/* Notify the DNS manager of the hostname change so that the domain part, if
* present, can be added to the search list.
@@ -484,26 +533,26 @@ _set_hostname (NMPolicy *self,
} else
name = new_hostname;
- old_hostname[HOST_NAME_MAX] = '\0';
- errno = 0;
- ret = gethostname (old_hostname, HOST_NAME_MAX);
- if (ret != 0) {
- _LOGW (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
- errno, strerror (errno));
- } else {
- /* Don't set the hostname if it isn't actually changing */
- if (nm_streq (name, old_hostname))
- return;
+ /* Don't set the hostname if it isn't actually changing */
+ if ( _get_hostname (self, &old_hostname)
+ && (nm_streq (name, old_hostname))) {
+ _LOGT (LOGD_DNS, "set-hostname: hostname already set to '%s' (%s)", name, msg);
+ return;
}
- _LOGI (LOGD_DNS, "setting system hostname to '%s' (%s)", name, msg);
+ /* Keep track of the last set hostname */
+ g_free (priv->last_hostname);
+ priv->last_hostname = g_strdup (name);
+ priv->changing_hostname = TRUE;
+
+ _LOGI (LOGD_DNS, "set-hostname: set hostname to '%s' (%s)", name, msg);
/* Ask NMSettings to update the transient hostname using its
* systemd-hostnamed proxy */
nm_settings_set_transient_hostname (priv->settings,
name,
settings_set_hostname_cb,
- NULL);
+ g_object_ref (self));
}
static void
@@ -534,23 +583,55 @@ lookup_callback (GObject *source,
}
static void
-update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
+update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const char *msg)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
char *configured_hostname = NULL;
+ gs_free char *temp_hostname = NULL;
const char *dhcp_hostname, *p;
NMIP4Config *ip4_config;
NMIP6Config *ip6_config;
+ gboolean external_hostname = FALSE;
g_return_if_fail (self != NULL);
+ if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_NONE) {
+ _LOGT (LOGD_DNS, "set-hostname: hostname is unmanaged");
+ return;
+ }
+
+ _LOGT (LOGD_DNS, "set-hostname: updating hostname (%s)", msg);
+
nm_clear_g_cancellable (&priv->lookup_cancellable);
+ /* Check if the hostname was set externally to NM, so that in that case
+ * we can avoid to fallback to the one we got when we started.
+ * Consider "not specific" hostnames as equal. */
+ if ( _get_hostname (self, &temp_hostname)
+ && !nm_streq0 (temp_hostname, priv->last_hostname)
+ && ( nm_utils_is_specific_hostname (temp_hostname)
+ || nm_utils_is_specific_hostname (priv->last_hostname))) {
+ external_hostname = TRUE;
+ _LOGI (LOGD_DNS, "set-hostname: current hostname was changed outside NetworkManager: '%s'",
+ temp_hostname);
+ priv->dhcp_hostname = FALSE;
+
+ if (!nm_streq0 (temp_hostname, priv->orig_hostname)) {
+ /* Update original (fallback) hostname */
+ g_free (priv->orig_hostname);
+ if (nm_utils_is_specific_hostname (temp_hostname)) {
+ priv->orig_hostname = temp_hostname;
+ temp_hostname = NULL;
+ } else
+ priv->orig_hostname = NULL;
+ }
+ }
+
/* Hostname precedence order:
*
* 1) a configured hostname (from settings)
* 2) automatic hostname from the default device's config (DHCP, VPN, etc)
- * 3) the original hostname when NM started
+ * 3) the last hostname set outside NM
* 4) reverse-DNS of the best device's IPv4 address
*
*/
@@ -559,6 +640,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
g_object_get (G_OBJECT (priv->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
if (configured_hostname && nm_utils_is_specific_hostname (configured_hostname)) {
_set_hostname (self, configured_hostname, "from system configuration");
+ priv->dhcp_hostname = FALSE;
g_free (configured_hostname);
return;
}
@@ -570,14 +652,6 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
if (!best6)
best6 = get_best_ip6_device (self, TRUE);
- if (!best4 && !best6) {
- /* No best device; fall back to original hostname or if there wasn't
- * one, 'localhost.localdomain'
- */
- _set_hostname (self, priv->orig_hostname, "no default device");
- return;
- }
-
if (best4) {
NMDhcp4Config *dhcp4_config;
@@ -590,10 +664,11 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
while (*p) {
if (!g_ascii_isspace (*p++)) {
_set_hostname (self, p-1, "from DHCPv4");
+ priv->dhcp_hostname = TRUE;
return;
}
}
- _LOGW (LOGD_DNS, "DHCPv4-provided hostname '%s' looks invalid; ignoring it",
+ _LOGW (LOGD_DNS, "set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it",
dhcp_hostname);
}
}
@@ -609,17 +684,45 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
while (*p) {
if (!g_ascii_isspace (*p++)) {
_set_hostname (self, p-1, "from DHCPv6");
+ priv->dhcp_hostname = TRUE;
return;
}
}
- _LOGW (LOGD_DNS, "DHCPv6-provided hostname '%s' looks invalid; ignoring it",
+ _LOGW (LOGD_DNS, "set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it",
dhcp_hostname);
}
}
}
- /* If no automatically-configured hostname, try using the hostname from
- * when NM started up.
+ /* If an hostname was set outside NetworkManager keep it */
+ if (external_hostname)
+ return;
+
+ if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_DHCP) {
+ /* In dhcp hostname-mode, the hostname is updated only if it comes from
+ * a DHCP host-name option: if last set was from a host-name option and
+ * we are here than that connection is gone (with its host-name option),
+ * so reset the hostname to the previous value
+ */
+ if (priv->dhcp_hostname) {
+ _set_hostname (self, priv->orig_hostname, "reset dhcp hostname");
+ priv->dhcp_hostname = FALSE;
+ }
+ return;
+ }
+
+ priv->dhcp_hostname = FALSE;
+
+ if (!best4 && !best6) {
+ /* No best device; fall back to the last hostname set externally
+ * to NM or if there wasn't one, 'localhost.localdomain'
+ */
+ _set_hostname (self, priv->orig_hostname, "no default device");
+ return;
+ }
+
+ /* If no automatically-configured hostname, try using the last hostname
+ * set externally to NM
*/
if (priv->orig_hostname) {
_set_hostname (self, priv->orig_hostname, "from system startup");
@@ -921,7 +1024,7 @@ update_routing_and_dns (NMPolicy *self, gboolean force_update)
update_ip6_routing (self, force_update);
/* Update the system hostname */
- update_system_hostname (self, priv->default_device4, priv->default_device6);
+ update_system_hostname (self, priv->default_device4, priv->default_device6, "routing and dns");
nm_dns_manager_end_updates (priv->dns_manager, __func__);
}
@@ -1152,7 +1255,7 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data)
NMPolicyPrivate *priv = user_data;
NMPolicy *self = _PRIV_TO_SELF (priv);
- update_system_hostname (self, NULL, NULL);
+ update_system_hostname (self, NULL, NULL, "hostname changed");
}
static void
@@ -1620,8 +1723,9 @@ device_ip4_config_changed (NMDevice *device,
nm_dns_manager_begin_updates (priv->dns_manager, __func__);
- /* Ignore IP config changes while the device is activating, because we'll
- * catch all the changes when the device moves to ACTIVATED state.
+ /* We catch already all the IP events registering on the device state changes but
+ * the ones where the IP changes but the device state keep stable (i.e., activated):
+ * ignore IP config changes but when the device is in activated state.
* Prevents unecessary changes to DNS information.
*/
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
@@ -1633,7 +1737,7 @@ device_ip4_config_changed (NMDevice *device,
}
update_ip4_dns (self, priv->dns_manager);
update_ip4_routing (self, TRUE);
- update_system_hostname (self, priv->default_device4, priv->default_device6);
+ update_system_hostname (self, priv->default_device4, priv->default_device6, "ip4 conf");
} else {
/* Old configs get removed immediately */
if (old_config)
@@ -1655,11 +1759,12 @@ device_ip6_config_changed (NMDevice *device,
nm_dns_manager_begin_updates (priv->dns_manager, __func__);
- /* Ignore IP config changes while the device is activating, because we'll
- * catch all the changes when the device moves to ACTIVATED state.
+ /* We catch already all the IP events registering on the device state changes but
+ * the ones where the IP changes but the device state keep stable (i.e., activated):
+ * ignore IP config changes but when the device is in activated state.
* Prevents unecessary changes to DNS information.
*/
- if (!nm_device_is_activating (device)) {
+ if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
if (old_config != new_config) {
if (old_config)
nm_dns_manager_remove_ip6_config (priv->dns_manager, old_config);
@@ -1668,7 +1773,7 @@ device_ip6_config_changed (NMDevice *device,
}
update_ip6_dns (self, priv->dns_manager);
update_ip6_routing (self, TRUE);
- update_system_hostname (self, priv->default_device4, priv->default_device6);
+ update_system_hostname (self, priv->default_device4, priv->default_device6, "ip6 conf");
} else {
/* Old configs get removed immediately */
if (old_config)
@@ -1979,6 +2084,15 @@ dns_config_changed (NMDnsManager *dns_manager, gpointer user_data)
/* Re-start the hostname lookup thread if we don't have hostname yet. */
if (priv->lookup_addr) {
char *str = NULL;
+ gs_free char *hostname = NULL;
+
+ /* Check if the hostname was externally set */
+ if ( _get_hostname (self, &hostname)
+ && nm_utils_is_specific_hostname (hostname)
+ && !nm_streq0 (hostname, priv->last_hostname)) {
+ g_clear_object (&priv->lookup_addr);
+ return;
+ }
_LOGD (LOGD_DNS, "restarting reverse-lookup thread for address %s",
(str = g_inet_address_to_string (priv->lookup_addr)));
@@ -2173,7 +2287,20 @@ static void
nm_policy_init (NMPolicy *self)
{
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
-
+ const char *hostname_mode;
+
+ hostname_mode = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
+ NM_CONFIG_KEYFILE_GROUP_MAIN,
+ NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE,
+ NM_CONFIG_GET_VALUE_STRIP | NM_CONFIG_GET_VALUE_NO_EMPTY);
+ if (nm_streq0 (hostname_mode, "none"))
+ priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_NONE;
+ else if (nm_streq0 (hostname_mode, "dhcp"))
+ priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_DHCP;
+ else /* default - full mode */
+ priv->hostname_mode = NM_POLICY_HOSTNAME_MODE_FULL;
+
+ _LOGI (LOGD_DNS, "hostname management mode: %s", hostname_mode ? hostname_mode : "default");
priv->devices = g_hash_table_new (NULL, NULL);
priv->ip6_prefix_delegations = g_array_new (FALSE, FALSE, sizeof (IP6PrefixDelegation));
g_array_set_clear_func (priv->ip6_prefix_delegations, clear_ip6_prefix_delegation);
@@ -2184,13 +2311,15 @@ constructed (GObject *object)
{
NMPolicy *self = NM_POLICY (object);
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self);
- char hostname[HOST_NAME_MAX + 2];
+ char *hostname = NULL;
/* Grab hostname on startup and use that if nothing provides one */
- memset (hostname, 0, sizeof (hostname));
- if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) {
+ if (_get_hostname (self, &hostname)) {
+ /* init last_hostname */
+ priv->last_hostname = hostname;
+
/* only cache it if it's a valid hostname */
- if (*hostname && nm_utils_is_specific_hostname (hostname))
+ if (nm_utils_is_specific_hostname (hostname))
priv->orig_hostname = g_strdup (hostname);
}
@@ -2284,6 +2413,7 @@ dispose (GObject *object)
g_clear_pointer (&priv->orig_hostname, g_free);
g_clear_pointer (&priv->cur_hostname, g_free);
+ g_clear_pointer (&priv->last_hostname, g_free);
if (priv->settings) {
g_signal_handlers_disconnect_by_data (priv->settings, priv);
diff --git a/src/nm-policy.h b/src/nm-policy.h
index 64cac4fe70..2c96e6d090 100644
--- a/src/nm-policy.h
+++ b/src/nm-policy.h
@@ -47,4 +47,21 @@ NMDevice *nm_policy_get_default_ip6_device (NMPolicy *policy);
NMDevice *nm_policy_get_activating_ip4_device (NMPolicy *policy);
NMDevice *nm_policy_get_activating_ip6_device (NMPolicy *policy);
+/**
+ * NMPolicyHostnameMode
+ * @NM_POLICY_HOSTNAME_MODE_NONE: never update the transient hostname.
+ * @NM_POLICY_HOSTNAME_MODE_DHCP: only hostname from DHCP hostname
+ * options are eligible to be set as transient hostname.
+ * @NM_POLICY_HOSTNAME_MODE_FULL: NM will try to update the hostname looking
+ * to current static hostname, DHCP options, reverse IP lookup and externally
+ * set hostnames.
+ *
+ * NMPolicy's hostname update policy
+ */
+typedef enum {
+ NM_POLICY_HOSTNAME_MODE_NONE,
+ NM_POLICY_HOSTNAME_MODE_DHCP,
+ NM_POLICY_HOSTNAME_MODE_FULL,
+} NMPolicyHostnameMode;
+
#endif /* __NETWORKMANAGER_POLICY_H__ */
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index f738b4377a..afd1b0849c 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -1685,6 +1685,28 @@ nm_settings_set_transient_hostname (NMSettings *self,
info);
}
+gboolean
+nm_settings_get_transient_hostname (NMSettings *self, char **hostname)
+{
+ NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
+ GVariant *v_hostname;
+
+ if (!priv->hostname.hostnamed_proxy)
+ return FALSE;
+
+ v_hostname = g_dbus_proxy_get_cached_property (priv->hostname.hostnamed_proxy,
+ "Hostname");
+ if (!v_hostname) {
+ _LOGT ("transient hostname retrieval failed");
+ return FALSE;
+ }
+
+ *hostname = g_variant_dup_string (v_hostname, NULL);
+ g_variant_unref (v_hostname);
+
+ return TRUE;
+}
+
static gboolean
write_hostname (NMSettingsPrivate *priv, const char *hostname)
{
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 406e305767..7110a12ba8 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -132,4 +132,7 @@ void nm_settings_set_transient_hostname (NMSettings *self,
NMSettingsSetHostnameCb cb,
gpointer user_data);
+gboolean nm_settings_get_transient_hostname (NMSettings *self,
+ char **hostname);
+
#endif /* __NM_SETTINGS_H__ */