diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-02-18 18:19:30 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-02-19 11:03:02 +0100 |
commit | 1924c4fe24630afd8374b2f24f9ce0e840495c73 (patch) | |
tree | f3c09fa390698d4b683e4c6cb683232faad36fca | |
parent | 6d5e55870a00f44ab1421b5579ef8c309a7a615d (diff) | |
download | NetworkManager-bg/sethostname-hostnamed.tar.gz |
core: use hostnamed to set the transient hostnamebg/sethostname-hostnamed
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 | 45 | ||||
-rw-r--r-- | src/settings/nm-settings.c | 65 | ||||
-rw-r--r-- | src/settings/nm-settings.h | 4 |
3 files changed, 98 insertions, 16 deletions
diff --git a/src/nm-policy.c b/src/nm-policy.c index 05f7edf4db..e6abbc5428 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -120,9 +120,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 (char *hostname, gboolean result) { + int ret = 0; + + if (!result) { + ret = sethostname (hostname, strlen (hostname)); + if (ret != 0) { + int errsv = errno; + + nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s", + hostname, errsv, strerror (errsv)); + if (errsv == EPERM) + nm_log_warn (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); + + g_free (hostname); +} + +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; @@ -140,23 +163,14 @@ 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; - nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg); - ret = sethostname (name, strlen (name)); - if (ret != 0) { - int errsv = errno; - - nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s", - name, errsv, strerror (errsv)); - if (errsv == EPERM) - nm_log_warn (LOGD_DNS, "You should use hostnamed when systemd hardening is in effect!"); - } + nm_settings_set_transient_hostname (priv->settings, g_strdup (name), settings_set_hostname_cb); - return (ret == 0); + return; } static void @@ -198,8 +212,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 377d52793c..280670e535 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1526,6 +1526,71 @@ impl_settings_reload_connections (NMSettings *self, g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); } +typedef struct { + char *hostname; + NMSettingsSetHostnameCb cb; +} SetHostnameInfo; + +static void +set_transient_hostname_done (GObject *object, + GAsyncResult *res, + gpointer user_data) +{ + GDBusProxy *proxy = G_DBUS_PROXY (object); + SetHostnameInfo *info = user_data; + GError *error = NULL; + GVariant *result; + + result = g_dbus_proxy_call_finish (proxy, + res, + &error); + + if (error) { + nm_log_warn (LOGD_DNS, + "couldn't set the system hostname to '%s' using hostnamed: %s", + info->hostname, error->message); + } + + info->cb (info->hostname, !error); + + if (error) + g_error_free (error); + g_variant_unref (result); + g_free (info); +} + +void +nm_settings_set_transient_hostname (NMSettings *self, + char *hostname, + NMSettingsSetHostnameCb cb) +{ + gs_unref_variant GVariant *var = NULL; + gs_free_error GError *error = NULL; + 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); + return; + } + + info = g_new0 (SetHostnameInfo, 1); + info->hostname = hostname; + info->cb = cb; + + 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..07e36c44c1 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) (char *name, gboolean result); + GType nm_settings_get_type (void); NMSettings *nm_settings_new (void); @@ -127,4 +129,6 @@ 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, char *hostname, NMSettingsSetHostnameCb cb); + #endif /* __NM_SETTINGS_H__ */ |