diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-02-18 18:19:30 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-03-04 14:27:09 +0100 |
commit | 4090716d96180caaeb807033e0c9a3b4a3092f9b (patch) | |
tree | 794a6daf295646528dcc10983c52c983865d950a | |
parent | 298ab552252a10d3d1212aba56a7bdbdd543cdb4 (diff) | |
download | NetworkManager-4090716d96180caaeb807033e0c9a3b4a3092f9b.tar.gz |
core: use hostnamed to set the transient hostname
In commit 6dc35e66d45e ("settings: add hostnamed support") we started
to use systemd-hostnamed for setting the system static hostname
(i.e. the one written to /etc/hostname), but nm-policy.c still called
sethostname() to set the transient (dynamic) hostname when this needs
to be changed, for example after a reverse lookup of our dynamic IP
address.
Thus, when using systemd the hostname change failed because process'
capabilities are restricted and sethostname() requires CAP_SYS_ADMIN.
We should set also the transient hostname through hostnamed when this
is available.
https://bugzilla.redhat.com/show_bug.cgi?id=1308974
-rw-r--r-- | src/nm-policy.c | 48 | ||||
-rw-r--r-- | src/settings/nm-settings.c | 59 | ||||
-rw-r--r-- | src/settings/nm-settings.h | 7 |
3 files changed, 97 insertions, 17 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index bbfc3dd638..c564ff0a52 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -127,9 +127,32 @@ get_best_ip6_device (NMPolicy *self, gboolean fully_activated) #define FALLBACK_HOSTNAME4 "localhost.localdomain" -static gboolean -set_system_hostname (const char *new_hostname, const char *msg) +static void settings_set_hostname_cb (const char *hostname, + gboolean result, + gpointer user_data) { + int ret = 0; + + if (!result) { + ret = sethostname (hostname, strlen (hostname)); + if (ret != 0) { + int errsv = errno; + + _LOGW (LOGD_DNS, "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!"); + } + } + + if (!ret) + nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL); +} + +static void +set_system_hostname (NMPolicy *self, const char *new_hostname, const char *msg) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); char old_hostname[HOST_NAME_MAX + 1]; const char *name; int ret; @@ -147,23 +170,15 @@ set_system_hostname (const char *new_hostname, const char *msg) /* Don't set the hostname if it isn't actually changing */ if ( (new_hostname && !strcmp (old_hostname, new_hostname)) || (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME4))) - return FALSE; + return; } name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4; - _LOGI (LOGD_DNS, "setting system hostname to '%s' (%s)", name, msg); - ret = sethostname (name, strlen (name)); - if (ret != 0) { - int errsv = errno; - - _LOGW (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s", - name, errsv, strerror (errsv)); - if (errsv == EPERM) - _LOGW (LOGD_DNS, "you should use hostnamed when systemd hardening is in effect!"); - } - - return (ret == 0); + nm_settings_set_transient_hostname (priv->settings, + name, + settings_set_hostname_cb, + NULL); } static void @@ -205,8 +220,7 @@ _set_hostname (NMPolicy *policy, nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname); - if (set_system_hostname (priv->cur_hostname, msg)) - nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL); + set_system_hostname (policy, priv->cur_hostname, msg); } static void diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index f9bac4ded6..f090185480 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1527,6 +1527,65 @@ impl_settings_reload_connections (NMSettings *self, g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); } +typedef struct { + char *hostname; + NMSettingsSetHostnameCb cb; + gpointer user_data; +} SetHostnameInfo; + +static void +set_transient_hostname_done (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + gs_free SetHostnameInfo *info = user_data; + gs_unref_variant GVariant *result = NULL; + gs_free_error GError *error = NULL; + + result = g_dbus_proxy_call_finish (proxy, res, &error); + + if (error) { + _LOGW ("couldn't set the system hostname to '%s' using hostnamed: %s", + info->hostname, error->message); + } + + info->cb (info->hostname, !error, info->user_data); + g_free (info->hostname); +} + +void +nm_settings_set_transient_hostname (NMSettings *self, + const char *hostname, + NMSettingsSetHostnameCb cb, + gpointer user_data) +{ + NMSettingsPrivate *priv; + SetHostnameInfo *info; + + g_return_if_fail (NM_IS_SETTINGS (self)); + priv = NM_SETTINGS_GET_PRIVATE (self); + + if (!priv->hostname.hostnamed_proxy) { + cb (hostname, FALSE, user_data); + return; + } + + info = g_new0 (SetHostnameInfo, 1); + info->hostname = g_strdup (hostname); + info->cb = cb; + info->user_data = user_data; + + g_dbus_proxy_call (priv->hostname.hostnamed_proxy, + "SetHostname", + g_variant_new ("(sb)", hostname, FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + set_transient_hostname_done, + info); +} + static gboolean write_hostname (NMSettingsPrivate *priv, const char *hostname) { diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 923b164b04..051c209423 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -71,6 +71,8 @@ typedef struct { void (*agent_registered) (NMSettings *self, NMSecretAgent *agent); } NMSettingsClass; +typedef void (*NMSettingsSetHostnameCb) (const char *name, gboolean result, gpointer user_data); + GType nm_settings_get_type (void); NMSettings *nm_settings_new (void); @@ -127,4 +129,9 @@ gint nm_settings_sort_connections (gconstpointer a, gconstpointer b); gboolean nm_settings_get_startup_complete (NMSettings *self); +void nm_settings_set_transient_hostname (NMSettings *self, + const char *hostname, + NMSettingsSetHostnameCb cb, + gpointer user_data); + #endif /* __NM_SETTINGS_H__ */ |