summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-04-23 00:40:46 +0200
committerThomas Haller <thaller@redhat.com>2017-05-12 17:29:33 +0200
commit5bfb7c3c89afe4da5b1ac2395391e9a986c722f0 (patch)
tree6c7ac733441dfb8e1478162dd1390b8e0d780685 /src
parentf3dfe0f745d2cfdab638804980e5e8501112183f (diff)
downloadNetworkManager-5bfb7c3c89afe4da5b1ac2395391e9a986c722f0.tar.gz
hostname: split out hostname management from NMSettings
Hostname management is complicated. At least, how it is implemented currently. For example, NMPolicy also sets the hostname (NMPolicy calls nm_settings_set_transient_hostname() to have hostnamed set the hostname, but then falls back to sethostname() in settings_set_hostname_cb()). Also, NMManager tracks the hostname in NM_MANAGER_HOSTNAME too, and NMPolicy listens to changes from there -- instead of changes from NMSettings. Eventually, NMHostnameManager should contain the hostname parts from NMSettings and NMPolicy.
Diffstat (limited to 'src')
-rw-r--r--src/nm-hostname-manager.c649
-rw-r--r--src/nm-hostname-manager.h61
-rw-r--r--src/nm-manager.c5
-rw-r--r--src/nm-policy.c15
-rw-r--r--src/settings/nm-settings.c520
-rw-r--r--src/settings/nm-settings.h10
6 files changed, 761 insertions, 499 deletions
diff --git a/src/nm-hostname-manager.c b/src/nm-hostname-manager.c
new file mode 100644
index 0000000000..31132082b5
--- /dev/null
+++ b/src/nm-hostname-manager.c
@@ -0,0 +1,649 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2017 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-hostname-manager.h"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+
+#if HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include "nm-common-macros.h"
+#include "nm-dbus-interface.h"
+#include "nm-connection.h"
+#include "nm-utils.h"
+#include "nm-core-internal.h"
+
+#include "NetworkManagerUtils.h"
+#include "nm-dispatcher.h"
+
+/*****************************************************************************/
+
+#define HOSTNAMED_SERVICE_NAME "org.freedesktop.hostname1"
+#define HOSTNAMED_SERVICE_PATH "/org/freedesktop/hostname1"
+#define HOSTNAMED_SERVICE_INTERFACE "org.freedesktop.hostname1"
+
+#define HOSTNAME_FILE_DEFAULT "/etc/hostname"
+#define HOSTNAME_FILE_UCASE_HOSTNAME "/etc/HOSTNAME"
+#define HOSTNAME_FILE_GENTOO "/etc/conf.d/hostname"
+
+#if (defined(HOSTNAME_PERSIST_SUSE) + defined(HOSTNAME_PERSIST_SLACKWARE) + defined(HOSTNAME_PERSIST_GENTOO)) > 1
+#error "Can only define one of HOSTNAME_PERSIST_*"
+#endif
+
+#if defined(HOSTNAME_PERSIST_SUSE)
+#define HOSTNAME_FILE HOSTNAME_FILE_UCASE_HOSTNAME
+#elif defined(HOSTNAME_PERSIST_SLACKWARE)
+#define HOSTNAME_FILE HOSTNAME_FILE_UCASE_HOSTNAME
+#elif defined(HOSTNAME_PERSIST_GENTOO)
+#define HOSTNAME_FILE HOSTNAME_FILE_GENTOO
+#else
+#define HOSTNAME_FILE HOSTNAME_FILE_DEFAULT
+#endif
+
+/*****************************************************************************/
+
+NM_GOBJECT_PROPERTIES_DEFINE (NMHostnameManager,
+ PROP_HOSTNAME,
+);
+
+typedef struct {
+ char *value;
+ GFileMonitor *monitor;
+ GFileMonitor *dhcp_monitor;
+ gulong monitor_id;
+ gulong dhcp_monitor_id;
+ GDBusProxy *hostnamed_proxy;
+} NMHostnameManagerPrivate;
+
+struct _NMHostnameManager {
+ GObject parent;
+ NMHostnameManagerPrivate _priv;
+};
+
+struct _NMHostnameManagerClass {
+ GObjectClass parent;
+};
+
+G_DEFINE_TYPE (NMHostnameManager, nm_hostname_manager, G_TYPE_OBJECT);
+
+#define NM_HOSTNAME_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMHostnameManager, NM_IS_HOSTNAME_MANAGER)
+
+NM_DEFINE_SINGLETON_GETTER (NMHostnameManager, nm_hostname_manager_get, NM_TYPE_HOSTNAME_MANAGER);
+
+/*****************************************************************************/
+
+#define _NMLOG_DOMAIN LOGD_CORE
+#define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "hostname", __VA_ARGS__)
+
+/*****************************************************************************/
+
+#if defined(HOSTNAME_PERSIST_GENTOO)
+static gchar *
+read_hostname_gentoo (const char *path)
+{
+ gs_free char *contents = NULL;
+ gs_strfreev char **all_lines = NULL;
+ const char *tmp;
+ guint i;
+
+ if (!g_file_get_contents (path, &contents, NULL, NULL))
+ return NULL;
+
+ all_lines = g_strsplit (contents, "\n", 0);
+ for (i = 0; all_lines[i]; i++) {
+ g_strstrip (all_lines[i]);
+ if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
+ continue;
+ if (g_str_has_prefix (all_lines[i], "hostname=")) {
+ tmp = &all_lines[i][NM_STRLEN ("hostname=")];
+ return g_shell_unquote (tmp, NULL);
+ }
+ }
+ return NULL;
+}
+#endif
+
+#if defined(HOSTNAME_PERSIST_SLACKWARE)
+static gchar *
+read_hostname_slackware (const char *path)
+{
+ gs_free char *contents = NULL;
+ gs_strfreev char **all_lines = NULL;
+ char *tmp;
+ guint i, j = 0;
+
+ if (!g_file_get_contents (path, &contents, NULL, NULL))
+ return NULL;
+
+ all_lines = g_strsplit (contents, "\n", 0);
+ for (i = 0; all_lines[i]; i++) {
+ g_strstrip (all_lines[i]);
+ if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
+ continue;
+ tmp = &all_lines[i][0];
+ /* We only want up to the first '.' -- the rest of the */
+ /* fqdn is defined in /etc/hosts */
+ while (tmp[j] != '\0') {
+ if (tmp[j] == '.') {
+ tmp[j] = '\0';
+ break;
+ }
+ j++;
+ }
+ return g_shell_unquote (tmp, NULL);
+ }
+ return NULL;
+}
+#endif
+
+#if defined(HOSTNAME_PERSIST_SUSE)
+static gboolean
+hostname_is_dynamic (void)
+{
+ GIOChannel *channel;
+ char *str = NULL;
+ gboolean dynamic = FALSE;
+
+ channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
+ if (!channel)
+ return dynamic;
+
+ while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
+ if (str) {
+ g_strstrip (str);
+ if (g_str_has_prefix (str, "DHCLIENT_SET_HOSTNAME="))
+ dynamic = strcmp (&str[NM_STRLEN ("DHCLIENT_SET_HOSTNAME=")], "\"yes\"") == 0;
+ g_free (str);
+ }
+ }
+
+ g_io_channel_shutdown (channel, FALSE, NULL);
+ g_io_channel_unref (channel);
+
+ return dynamic;
+}
+#endif
+
+/* Returns an allocated string which the caller owns and must eventually free */
+char *
+nm_hostname_manager_get_hostname (NMHostnameManager *self)
+{
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+ char *hostname = NULL;
+
+ if (priv->hostnamed_proxy) {
+ hostname = g_strdup (priv->value);
+ goto out;
+ }
+
+#if defined(HOSTNAME_PERSIST_SUSE)
+ if (priv->dhcp_monitor_id && hostname_is_dynamic ())
+ return NULL;
+#endif
+
+#if defined(HOSTNAME_PERSIST_GENTOO)
+ hostname = read_hostname_gentoo (HOSTNAME_FILE);
+#elif defined(HOSTNAME_PERSIST_SLACKWARE)
+ hostname = read_hostname_slackware (HOSTNAME_FILE);
+#else
+ if (g_file_get_contents (HOSTNAME_FILE, &hostname, NULL, NULL))
+ g_strchomp (hostname);
+#endif
+
+out:
+ if (hostname && !hostname[0]) {
+ g_free (hostname);
+ hostname = NULL;
+ }
+
+ return hostname;
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ char *hostname;
+ NMHostnameManagerSetHostnameCb 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_hostname_manager_set_transient_hostname (NMHostnameManager *self,
+ const char *hostname,
+ NMHostnameManagerSetHostnameCb cb,
+ gpointer user_data)
+{
+ NMHostnameManagerPrivate *priv;
+ SetHostnameInfo *info;
+
+ g_return_if_fail (NM_IS_HOSTNAME_MANAGER (self));
+
+ priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+
+ if (!priv->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->hostnamed_proxy,
+ "SetHostname",
+ g_variant_new ("(sb)", hostname, FALSE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ set_transient_hostname_done,
+ info);
+}
+
+gboolean
+nm_hostname_manager_get_transient_hostname (NMHostnameManager *self, char **hostname)
+{
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+ GVariant *v_hostname;
+
+ if (!priv->hostnamed_proxy)
+ return FALSE;
+
+ v_hostname = g_dbus_proxy_get_cached_property (priv->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;
+}
+
+gboolean
+nm_hostname_manager_write_hostname (NMHostnameManager *self, const char *hostname)
+{
+ NMHostnameManagerPrivate *priv;
+ char *hostname_eol;
+ gboolean ret;
+ gs_free_error GError *error = NULL;
+ const char *file = HOSTNAME_FILE;
+ gs_free char *link_path = NULL;
+ gs_unref_variant GVariant *var = NULL;
+ struct stat file_stat;
+#if HAVE_SELINUX
+ security_context_t se_ctx_prev = NULL, se_ctx = NULL;
+ mode_t st_mode = 0;
+#endif
+
+ g_return_val_if_fail (NM_IS_HOSTNAME_MANAGER (self), FALSE);
+
+ priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+
+ if (priv->hostnamed_proxy) {
+ var = g_dbus_proxy_call_sync (priv->hostnamed_proxy,
+ "SetStaticHostname",
+ g_variant_new ("(sb)", hostname, FALSE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+ if (error)
+ _LOGW ("could not set hostname: %s", error->message);
+
+ return !error;
+ }
+
+ /* If the hostname file is a symbolic link, follow it to find where the
+ * real file is located, otherwise g_file_set_contents will attempt to
+ * replace the link with a plain file.
+ */
+ if ( lstat (file, &file_stat) == 0
+ && S_ISLNK (file_stat.st_mode)
+ && (link_path = nm_utils_read_link_absolute (file, NULL)))
+ file = link_path;
+
+#if HAVE_SELINUX
+ /* Get default context for hostname file and set it for fscreate */
+ if (stat (file, &file_stat) == 0)
+ st_mode = file_stat.st_mode;
+ matchpathcon (file, st_mode, &se_ctx);
+ matchpathcon_fini ();
+ getfscreatecon (&se_ctx_prev);
+ setfscreatecon (se_ctx);
+#endif
+
+#if defined (HOSTNAME_PERSIST_GENTOO)
+ hostname_eol = g_strdup_printf ("#Generated by NetworkManager\n"
+ "hostname=\"%s\"\n", hostname);
+#else
+ hostname_eol = g_strdup_printf ("%s\n", hostname);
+#endif
+
+ ret = g_file_set_contents (file, hostname_eol, -1, &error);
+
+#if HAVE_SELINUX
+ /* Restore previous context and cleanup */
+ setfscreatecon (se_ctx_prev);
+ freecon (se_ctx);
+ freecon (se_ctx_prev);
+#endif
+
+ g_free (hostname_eol);
+
+ if (!ret) {
+ _LOGW ("could not save hostname to %s: %s", file, error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+nm_hostname_manager_validate_hostname (const char *hostname)
+{
+ const char *p;
+ gboolean dot = TRUE;
+
+ if (!hostname || !hostname[0])
+ return FALSE;
+
+ for (p = hostname; *p; p++) {
+ if (*p == '.') {
+ if (dot)
+ return FALSE;
+ dot = TRUE;
+ } else {
+ if (!g_ascii_isalnum (*p) && (*p != '-') && (*p != '_'))
+ return FALSE;
+ dot = FALSE;
+ }
+ }
+
+ if (dot)
+ return FALSE;
+
+ return (p - hostname <= HOST_NAME_MAX);
+}
+
+static void
+hostname_maybe_changed (NMHostnameManager *settings)
+{
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (settings);
+ char *new_hostname;
+
+ new_hostname = nm_hostname_manager_get_hostname (settings);
+
+ if ( (new_hostname && !priv->value)
+ || (!new_hostname && priv->value)
+ || (priv->value && new_hostname && strcmp (priv->value, new_hostname))) {
+
+ _LOGI ("hostname changed from %s%s%s to %s%s%s",
+ NM_PRINT_FMT_QUOTED (priv->value, "\"", priv->value, "\"", "(none)"),
+ NM_PRINT_FMT_QUOTED (new_hostname, "\"", new_hostname, "\"", "(none)"));
+ g_free (priv->value);
+ priv->value = new_hostname;
+ _notify (settings, PROP_HOSTNAME);
+ } else
+ g_free (new_hostname);
+}
+
+static void
+hostname_file_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ hostname_maybe_changed (user_data);
+}
+
+/*****************************************************************************/
+
+static void
+hostnamed_properties_changed (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ char **invalidated_properties,
+ gpointer user_data)
+{
+ NMHostnameManager *self = user_data;
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+ GVariant *v_hostname;
+ const char *hostname;
+
+ v_hostname = g_dbus_proxy_get_cached_property (priv->hostnamed_proxy,
+ "StaticHostname");
+ if (!v_hostname)
+ return;
+
+ hostname = g_variant_get_string (v_hostname, NULL);
+
+ if (g_strcmp0 (priv->value, hostname) != 0) {
+ _LOGI ("hostname changed from %s%s%s to %s%s%s",
+ NM_PRINT_FMT_QUOTED (priv->value, "\"", priv->value, "\"", "(none)"),
+ NM_PRINT_FMT_QUOTED (hostname, "\"", hostname, "\"", "(none)"));
+ g_free (priv->value);
+ priv->value = g_strdup (hostname);
+ _notify (self, PROP_HOSTNAME);
+ nm_dispatcher_call_hostname (NULL, NULL, NULL);
+ }
+
+ g_variant_unref (v_hostname);
+}
+
+static void
+setup_hostname_file_monitors (NMHostnameManager *self)
+{
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+ GFileMonitor *monitor;
+ const char *path = HOSTNAME_FILE;
+ char *link_path = NULL;
+ struct stat file_stat;
+ GFile *file;
+
+ priv->value = nm_hostname_manager_get_hostname (self);
+
+ /* resolve the path to the hostname file if it is a symbolic link */
+ if ( lstat(path, &file_stat) == 0
+ && S_ISLNK (file_stat.st_mode)
+ && (link_path = nm_utils_read_link_absolute (path, NULL))) {
+ path = link_path;
+ if ( lstat(link_path, &file_stat) == 0
+ && S_ISLNK (file_stat.st_mode)) {
+ _LOGW ("only one level of symbolic link indirection is allowed when monitoring "
+ HOSTNAME_FILE);
+ }
+ }
+
+ /* monitor changes to hostname file */
+ file = g_file_new_for_path (path);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+ g_free(link_path);
+ if (monitor) {
+ priv->monitor_id = g_signal_connect (monitor, "changed",
+ G_CALLBACK (hostname_file_changed_cb),
+ self);
+ priv->monitor = monitor;
+ }
+
+#if defined (HOSTNAME_PERSIST_SUSE)
+ /* monitor changes to dhcp file to know whether the hostname is valid */
+ file = g_file_new_for_path (CONF_DHCP);
+ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+ if (monitor) {
+ priv->dhcp_monitor_id = g_signal_connect (monitor, "changed",
+ G_CALLBACK (hostname_file_changed_cb),
+ self);
+ priv->dhcp_monitor = monitor;
+ }
+#endif
+
+ hostname_maybe_changed (self);
+}
+
+/*****************************************************************************/
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMHostnameManager *self = NM_HOSTNAME_MANAGER (object);
+
+ switch (prop_id) {
+ case PROP_HOSTNAME:
+ g_value_take_string (value, nm_hostname_manager_get_hostname (self));
+
+ /* Don't ever pass NULL through D-Bus */
+ if (!g_value_get_string (value))
+ g_value_set_static_string (value, "");
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_hostname_manager_init (NMHostnameManager *self)
+{
+}
+
+static void
+constructed (GObject *object)
+{
+ NMHostnameManager *self = NM_HOSTNAME_MANAGER (object);
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+ GDBusProxy *proxy;
+ GVariant *variant;
+ gs_free GError *error = NULL;
+
+ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, NULL,
+ HOSTNAMED_SERVICE_NAME, HOSTNAMED_SERVICE_PATH,
+ HOSTNAMED_SERVICE_INTERFACE, NULL, &error);
+ if (proxy) {
+ variant = g_dbus_proxy_get_cached_property (proxy, "StaticHostname");
+ if (variant) {
+ _LOGI ("hostname: using hostnamed");
+ priv->hostnamed_proxy = proxy;
+ g_signal_connect (proxy, "g-properties-changed",
+ G_CALLBACK (hostnamed_properties_changed), self);
+ hostnamed_properties_changed (proxy, NULL, NULL, self);
+ g_variant_unref (variant);
+ } else {
+ _LOGI ("hostname: couldn't get property from hostnamed");
+ g_object_unref (proxy);
+ }
+ } else {
+ _LOGI ("hostname: hostnamed not used as proxy creation failed with: %s",
+ error->message);
+ g_clear_error (&error);
+ }
+
+ if (!priv->hostnamed_proxy)
+ setup_hostname_file_monitors (self);
+
+ G_OBJECT_CLASS (nm_hostname_manager_parent_class)->constructed (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMHostnameManager *self = NM_HOSTNAME_MANAGER (object);
+ NMHostnameManagerPrivate *priv = NM_HOSTNAME_MANAGER_GET_PRIVATE (self);
+
+ if (priv->hostnamed_proxy) {
+ g_signal_handlers_disconnect_by_func (priv->hostnamed_proxy,
+ G_CALLBACK (hostnamed_properties_changed),
+ self);
+ g_clear_object (&priv->hostnamed_proxy);
+ }
+
+ if (priv->monitor) {
+ if (priv->monitor_id)
+ g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+
+ g_file_monitor_cancel (priv->monitor);
+ g_clear_object (&priv->monitor);
+ }
+
+ if (priv->dhcp_monitor) {
+ if (priv->dhcp_monitor_id)
+ g_signal_handler_disconnect (priv->dhcp_monitor,
+ priv->dhcp_monitor_id);
+
+ g_file_monitor_cancel (priv->dhcp_monitor);
+ g_clear_object (&priv->dhcp_monitor);
+ }
+
+ g_clear_pointer (&priv->value, g_free);
+
+ G_OBJECT_CLASS (nm_hostname_manager_parent_class)->dispose (object);
+}
+
+static void
+nm_hostname_manager_class_init (NMHostnameManagerClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->constructed = constructed;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ obj_properties[PROP_HOSTNAME] =
+ g_param_spec_string (NM_HOSTNAME_MANAGER_HOSTNAME, "", "",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+}
diff --git a/src/nm-hostname-manager.h b/src/nm-hostname-manager.h
new file mode 100644
index 0000000000..92702bbc1b
--- /dev/null
+++ b/src/nm-hostname-manager.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager
+ *
+ * Søren Sandmann <sandmann@daimi.au.dk>
+ * Dan Williams <dcbw@redhat.com>
+ * Tambet Ingo <tambet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2007 - 2011, 2017 Red Hat, Inc.
+ * (C) Copyright 2008 Novell, Inc.
+ */
+
+#ifndef __NM_HOSTNAME_MANAGER_H__
+#define __NM_HOSTNAME_MANAGER_H__
+
+#define NM_TYPE_HOSTNAME_MANAGER (nm_hostname_manager_get_type ())
+#define NM_HOSTNAME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HOSTNAME_MANAGER, NMHostnameManager))
+#define NM_HOSTNAME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_HOSTNAME_MANAGER, NMHostnameManagerClass))
+#define NM_IS_HOSTNAME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HOSTNAME_MANAGER))
+#define NM_IS_HOSTNAME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_HOSTNAME_MANAGER))
+#define NM_HOSTNAME_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_HOSTNAME_MANAGER, NMHostnameManagerClass))
+
+#define NM_HOSTNAME_MANAGER_HOSTNAME "hostname"
+
+typedef struct _NMHostnameManager NMHostnameManager;
+typedef struct _NMHostnameManagerClass NMHostnameManagerClass;
+
+typedef void (*NMHostnameManagerSetHostnameCb) (const char *name, gboolean result, gpointer user_data);
+
+GType nm_hostname_manager_get_type (void);
+
+NMHostnameManager *nm_hostname_manager_get (void);
+
+char *nm_hostname_manager_get_hostname (NMHostnameManager *self);
+
+gboolean nm_hostname_manager_write_hostname (NMHostnameManager *self, const char *hostname);
+
+void nm_hostname_manager_set_transient_hostname (NMHostnameManager *self,
+ const char *hostname,
+ NMHostnameManagerSetHostnameCb cb,
+ gpointer user_data);
+
+gboolean nm_hostname_manager_get_transient_hostname (NMHostnameManager *self,
+ char **hostname);
+
+gboolean nm_hostname_manager_validate_hostname (const char *hostname);
+
+#endif /* __NM_HOSTNAME_MANAGER_H__ */
diff --git a/src/nm-manager.c b/src/nm-manager.c
index a74021951a..0d65e58537 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -1412,7 +1412,10 @@ system_hostname_changed_cb (NMSettings *settings,
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
char *hostname;
- hostname = nm_settings_get_hostname (priv->settings);
+ g_object_get (priv->settings,
+ NM_SETTINGS_HOSTNAME,
+ &hostname,
+ NULL);
/* nm_settings_get_hostname() does not return an empty hostname. */
nm_assert (!hostname || *hostname);
diff --git a/src/nm-policy.c b/src/nm-policy.c
index 7c74a6b412..24b3cba8c4 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -49,6 +49,7 @@
#include "nm-dhcp6-config.h"
#include "nm-config.h"
#include "nm-netns.h"
+#include "nm-hostname-manager.h"
/*****************************************************************************/
@@ -73,6 +74,8 @@ typedef struct {
NMSettings *settings;
+ NMHostnameManager *hostname_manager;
+
NMDevice *default_device4, *activating_device4;
NMDevice *default_device6, *activating_device6;
@@ -460,7 +463,7 @@ _get_hostname (NMPolicy *self, char **hostname)
}
/* try to get the hostname via dbus... */
- if (nm_settings_get_transient_hostname (priv->settings, hostname)) {
+ if (nm_hostname_manager_get_transient_hostname (priv->hostname_manager, hostname)) {
_LOGT (LOGD_DNS, "get-hostname: \"%s\" (from dbus)", *hostname);
return *hostname;
}
@@ -549,10 +552,10 @@ _set_hostname (NMPolicy *self,
/* Ask NMSettings to update the transient hostname using its
* systemd-hostnamed proxy */
- nm_settings_set_transient_hostname (priv->settings,
- name,
- settings_set_hostname_cb,
- g_object_ref (self));
+ nm_hostname_manager_set_transient_hostname (priv->hostname_manager,
+ name,
+ settings_set_hostname_cb,
+ g_object_ref (self));
}
static void
@@ -2300,6 +2303,8 @@ nm_policy_init (NMPolicy *self)
priv->netns = g_object_ref (nm_netns_get ());
+ priv->hostname_manager = g_object_ref (nm_hostname_manager_get ());
+
hostname_mode = nm_config_data_get_value (NM_CONFIG_GET_DATA_ORIG,
NM_CONFIG_KEYFILE_GROUP_MAIN,
NM_CONFIG_KEYFILE_KEY_MAIN_HOSTNAME_MODE,
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index afd1b0849c..2e41f9c3a4 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -76,6 +76,7 @@
#include "NetworkManagerUtils.h"
#include "nm-dispatcher.h"
#include "nm-inotify-helper.h"
+#include "nm-hostname-manager.h"
#include "introspection/org.freedesktop.NetworkManager.Settings.h"
@@ -94,13 +95,6 @@ EXPORT(nm_settings_connection_replace_and_commit)
/*****************************************************************************/
-#define HOSTNAMED_SERVICE_NAME "org.freedesktop.hostname1"
-#define HOSTNAMED_SERVICE_PATH "/org/freedesktop/hostname1"
-#define HOSTNAMED_SERVICE_INTERFACE "org.freedesktop.hostname1"
-
-#define HOSTNAME_FILE_DEFAULT "/etc/hostname"
-#define HOSTNAME_FILE_UCASE_HOSTNAME "/etc/HOSTNAME"
-#define HOSTNAME_FILE_GENTOO "/etc/conf.d/hostname"
#define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
#define CONF_DHCP IFCFG_DIR "/dhcp"
@@ -162,14 +156,9 @@ typedef struct {
gboolean started;
gboolean startup_complete;
- struct {
- char *value;
- GFileMonitor *monitor;
- GFileMonitor *dhcp_monitor;
- gulong monitor_id;
- gulong dhcp_monitor_id;
- GDBusProxy *hostnamed_proxy;
- } hostname;
+ char *hostname;
+ NMHostnameManager *hostname_manager;
+
} NMSettingsPrivate;
struct _NMSettings {
@@ -568,131 +557,6 @@ get_plugin (NMSettings *self, guint32 capability)
return NULL;
}
-#if defined(HOSTNAME_PERSIST_GENTOO)
-static gchar *
-read_hostname_gentoo (const char *path)
-{
- gs_free char *contents = NULL;
- gs_strfreev char **all_lines = NULL;
- const char *tmp;
- guint i;
-
- if (!g_file_get_contents (path, &contents, NULL, NULL))
- return NULL;
-
- all_lines = g_strsplit (contents, "\n", 0);
- for (i = 0; all_lines[i]; i++) {
- g_strstrip (all_lines[i]);
- if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
- continue;
- if (g_str_has_prefix (all_lines[i], "hostname=")) {
- tmp = &all_lines[i][NM_STRLEN ("hostname=")];
- return g_shell_unquote (tmp, NULL);
- }
- }
- return NULL;
-}
-#endif
-
-#if defined(HOSTNAME_PERSIST_SLACKWARE)
-static gchar *
-read_hostname_slackware (const char *path)
-{
- gs_free char *contents = NULL;
- gs_strfreev char **all_lines = NULL;
- char *tmp;
- guint i, j = 0;
-
- if (!g_file_get_contents (path, &contents, NULL, NULL))
- return NULL;
-
- all_lines = g_strsplit (contents, "\n", 0);
- for (i = 0; all_lines[i]; i++) {
- g_strstrip (all_lines[i]);
- if (all_lines[i][0] == '#' || all_lines[i][0] == '\0')
- continue;
- tmp = &all_lines[i][0];
- /* We only want up to the first '.' -- the rest of the */
- /* fqdn is defined in /etc/hosts */
- while (tmp[j] != '\0') {
- if (tmp[j] == '.') {
- tmp[j] = '\0';
- break;
- }
- j++;
- }
- return g_shell_unquote (tmp, NULL);
- }
- return NULL;
-}
-#endif
-
-#if defined(HOSTNAME_PERSIST_SUSE)
-static gboolean
-hostname_is_dynamic (void)
-{
- GIOChannel *channel;
- char *str = NULL;
- gboolean dynamic = FALSE;
-
- channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
- if (!channel)
- return dynamic;
-
- while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
- if (str) {
- g_strstrip (str);
- if (g_str_has_prefix (str, "DHCLIENT_SET_HOSTNAME="))
- dynamic = strcmp (&str[NM_STRLEN ("DHCLIENT_SET_HOSTNAME=")], "\"yes\"") == 0;
- g_free (str);
- }
- }
-
- g_io_channel_shutdown (channel, FALSE, NULL);
- g_io_channel_unref (channel);
-
- return dynamic;
-}
-#endif
-
-/* Returns an allocated string which the caller owns and must eventually free */
-char *
-nm_settings_get_hostname (NMSettings *self)
-{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- char *hostname = NULL;
-
- if (!priv->started)
- return NULL;
-
- if (priv->hostname.hostnamed_proxy) {
- hostname = g_strdup (priv->hostname.value);
- goto out;
- }
-
-#if defined(HOSTNAME_PERSIST_SUSE)
- if (priv->hostname.dhcp_monitor_id && hostname_is_dynamic ())
- return NULL;
-#endif
-
-#if defined(HOSTNAME_PERSIST_GENTOO)
- hostname = read_hostname_gentoo (HOSTNAME_FILE);
-#elif defined(HOSTNAME_PERSIST_SLACKWARE)
- hostname = read_hostname_slackware (HOSTNAME_FILE);
-#else
- if (g_file_get_contents (HOSTNAME_FILE, &hostname, NULL, NULL))
- g_strchomp (hostname);
-#endif
-
-out:
- if (hostname && !hostname[0]) {
- g_free (hostname);
- hostname = NULL;
- }
-
- return hostname;
-}
-
static gboolean
find_spec (GSList *spec_list, const char *spec)
{
@@ -1626,160 +1490,7 @@ 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);
-}
-
-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)
-{
- char *hostname_eol;
- gboolean ret;
- gs_free_error GError *error = NULL;
- const char *file = HOSTNAME_FILE;
- gs_free char *link_path = NULL;
- gs_unref_variant GVariant *var = NULL;
- struct stat file_stat;
-#if HAVE_SELINUX
- security_context_t se_ctx_prev = NULL, se_ctx = NULL;
- mode_t st_mode = 0;
-#endif
-
- if (priv->hostname.hostnamed_proxy) {
- var = g_dbus_proxy_call_sync (priv->hostname.hostnamed_proxy,
- "SetStaticHostname",
- g_variant_new ("(sb)", hostname, FALSE),
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- &error);
- if (error)
- _LOGW ("could not set hostname: %s", error->message);
-
- return !error;
- }
-
- /* If the hostname file is a symbolic link, follow it to find where the
- * real file is located, otherwise g_file_set_contents will attempt to
- * replace the link with a plain file.
- */
- if ( lstat (file, &file_stat) == 0
- && S_ISLNK (file_stat.st_mode)
- && (link_path = nm_utils_read_link_absolute (file, NULL)))
- file = link_path;
-
-#if HAVE_SELINUX
- /* Get default context for hostname file and set it for fscreate */
- if (stat (file, &file_stat) == 0)
- st_mode = file_stat.st_mode;
- matchpathcon (file, st_mode, &se_ctx);
- matchpathcon_fini ();
- getfscreatecon (&se_ctx_prev);
- setfscreatecon (se_ctx);
-#endif
-
-#if defined (HOSTNAME_PERSIST_GENTOO)
- hostname_eol = g_strdup_printf ("#Generated by NetworkManager\n"
- "hostname=\"%s\"\n", hostname);
-#else
- hostname_eol = g_strdup_printf ("%s\n", hostname);
-#endif
-
- ret = g_file_set_contents (file, hostname_eol, -1, &error);
-
-#if HAVE_SELINUX
- /* Restore previous context and cleanup */
- setfscreatecon (se_ctx_prev);
- freecon (se_ctx);
- freecon (se_ctx_prev);
-#endif
-
- g_free (hostname_eol);
-
- if (!ret) {
- _LOGW ("could not save hostname to %s: %s", file, error->message);
- return FALSE;
- }
-
- return TRUE;
-}
+/*****************************************************************************/
static void
pk_hostname_cb (NMAuthChain *chain,
@@ -1812,7 +1523,7 @@ pk_hostname_cb (NMAuthChain *chain,
} else {
hostname = nm_auth_chain_get_data (chain, "hostname");
- if (!write_hostname (priv, hostname)) {
+ if (!nm_hostname_manager_write_hostname (priv->hostname_manager, hostname)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_FAILED,
"Saving the hostname failed.");
@@ -1827,33 +1538,6 @@ pk_hostname_cb (NMAuthChain *chain,
nm_auth_chain_unref (chain);
}
-static gboolean
-validate_hostname (const char *hostname)
-{
- const char *p;
- gboolean dot = TRUE;
-
- if (!hostname || !hostname[0])
- return FALSE;
-
- for (p = hostname; *p; p++) {
- if (*p == '.') {
- if (dot)
- return FALSE;
- dot = TRUE;
- } else {
- if (!g_ascii_isalnum (*p) && (*p != '-') && (*p != '_'))
- return FALSE;
- dot = FALSE;
- }
- }
-
- if (dot)
- return FALSE;
-
- return (p - hostname <= HOST_NAME_MAX);
-}
-
static void
impl_settings_save_hostname (NMSettings *self,
GDBusMethodInvocation *context,
@@ -1864,7 +1548,7 @@ impl_settings_save_hostname (NMSettings *self,
GError *error = NULL;
/* Minimal validation of the hostname */
- if (!validate_hostname (hostname)) {
+ if (!nm_hostname_manager_validate_hostname (hostname)) {
error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_INVALID_HOSTNAME,
"The hostname was too long or contained invalid characters.");
@@ -1888,37 +1572,7 @@ done:
g_dbus_method_invocation_take_error (context, error);
}
-static void
-hostname_maybe_changed (NMSettings *settings)
-{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (settings);
- char *new_hostname;
-
- new_hostname = nm_settings_get_hostname (settings);
-
- if ( (new_hostname && !priv->hostname.value)
- || (!new_hostname && priv->hostname.value)
- || (priv->hostname.value && new_hostname && strcmp (priv->hostname.value, new_hostname))) {
-
- _LOGI ("hostname changed from %s%s%s to %s%s%s",
- NM_PRINT_FMT_QUOTED (priv->hostname.value, "\"", priv->hostname.value, "\"", "(none)"),
- NM_PRINT_FMT_QUOTED (new_hostname, "\"", new_hostname, "\"", "(none)"));
- g_free (priv->hostname.value);
- priv->hostname.value = new_hostname;
- _notify (settings, PROP_HOSTNAME);
- } else
- g_free (new_hostname);
-}
-
-static void
-hostname_file_changed_cb (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
-{
- hostname_maybe_changed (user_data);
-}
+/*****************************************************************************/
static gboolean
have_connection_for_device (NMSettings *self, NMDevice *device)
@@ -2141,95 +1795,34 @@ nm_settings_get_startup_complete (NMSettings *self)
/*****************************************************************************/
static void
-hostnamed_properties_changed (GDBusProxy *proxy,
- GVariant *changed_properties,
- char **invalidated_properties,
- gpointer user_data)
+_hostname_changed (NMSettings *self)
{
- NMSettings *self = user_data;
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- GVariant *v_hostname;
- const char *hostname;
-
- v_hostname = g_dbus_proxy_get_cached_property (priv->hostname.hostnamed_proxy,
- "StaticHostname");
- if (!v_hostname)
- return;
+ gs_free char *hostname = NULL;
- hostname = g_variant_get_string (v_hostname, NULL);
+ hostname = nm_hostname_manager_get_hostname (priv->hostname_manager);
- if (g_strcmp0 (priv->hostname.value, hostname) != 0) {
- _LOGI ("hostname changed from %s%s%s to %s%s%s",
- NM_PRINT_FMT_QUOTED (priv->hostname.value, "\"", priv->hostname.value, "\"", "(none)"),
- NM_PRINT_FMT_QUOTED (hostname, "\"", hostname, "\"", "(none)"));
- g_free (priv->hostname.value);
- priv->hostname.value = g_strdup (hostname);
- _notify (self, PROP_HOSTNAME);
- nm_dispatcher_call_hostname (NULL, NULL, NULL);
- }
-
- g_variant_unref (v_hostname);
+ if (nm_streq0 (hostname, priv->hostname))
+ return;
+ g_free (priv->hostname);
+ priv->hostname = g_steal_pointer (&hostname);
+ _notify (self, PROP_HOSTNAME);
}
static void
-setup_hostname_file_monitors (NMSettings *self)
+_hostname_changed_cb (NMHostnameManager *hostname_manager,
+ GParamSpec *pspec,
+ gpointer user_data)
{
- NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
- GFileMonitor *monitor;
- const char *path = HOSTNAME_FILE;
- char *link_path = NULL;
- struct stat file_stat;
- GFile *file;
-
- priv->hostname.value = nm_settings_get_hostname (self);
-
- /* resolve the path to the hostname file if it is a symbolic link */
- if ( lstat(path, &file_stat) == 0
- && S_ISLNK (file_stat.st_mode)
- && (link_path = nm_utils_read_link_absolute (path, NULL))) {
- path = link_path;
- if ( lstat(link_path, &file_stat) == 0
- && S_ISLNK (file_stat.st_mode)) {
- _LOGW ("only one level of symbolic link indirection is allowed when monitoring "
- HOSTNAME_FILE);
- }
- }
-
- /* monitor changes to hostname file */
- file = g_file_new_for_path (path);
- monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_object_unref (file);
- g_free(link_path);
- if (monitor) {
- priv->hostname.monitor_id = g_signal_connect (monitor, "changed",
- G_CALLBACK (hostname_file_changed_cb),
- self);
- priv->hostname.monitor = monitor;
- }
-
-#if defined (HOSTNAME_PERSIST_SUSE)
- /* monitor changes to dhcp file to know whether the hostname is valid */
- file = g_file_new_for_path (CONF_DHCP);
- monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
- g_object_unref (file);
- if (monitor) {
- priv->hostname.dhcp_monitor_id = g_signal_connect (monitor, "changed",
- G_CALLBACK (hostname_file_changed_cb),
- self);
- priv->hostname.dhcp_monitor = monitor;
- }
-#endif
-
- hostname_maybe_changed (self);
+ _hostname_changed (NM_SETTINGS (user_data));
}
+/*****************************************************************************/
+
gboolean
nm_settings_start (NMSettings *self, GError **error)
{
NMSettingsPrivate *priv;
- GDBusProxy *proxy;
- GVariant *variant;
- GError *local_error = NULL;
gs_strfreev char **plugins = NULL;
priv = NM_SETTINGS_GET_PRIVATE (self);
@@ -2245,33 +1838,12 @@ nm_settings_start (NMSettings *self, GError **error)
load_connections (self);
check_startup_complete (self);
- proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, NULL,
- HOSTNAMED_SERVICE_NAME, HOSTNAMED_SERVICE_PATH,
- HOSTNAMED_SERVICE_INTERFACE, NULL, &local_error);
- if (proxy) {
- variant = g_dbus_proxy_get_cached_property (proxy, "StaticHostname");
- if (variant) {
- _LOGI ("hostname: using hostnamed");
- priv->hostname.hostnamed_proxy = proxy;
- g_signal_connect (proxy, "g-properties-changed",
- G_CALLBACK (hostnamed_properties_changed), self);
- hostnamed_properties_changed (proxy, NULL, NULL, self);
- g_variant_unref (variant);
- } else {
- _LOGI ("hostname: couldn't get property from hostnamed");
- g_object_unref (proxy);
- }
- } else {
- _LOGI ("hostname: hostnamed not used as proxy creation failed with: %s",
- local_error->message);
- g_clear_error (&local_error);
- }
-
- if (!priv->hostname.hostnamed_proxy)
- setup_hostname_file_monitors (self);
-
- priv->started = TRUE;
- _notify (self, PROP_HOSTNAME);
+ priv->hostname_manager = g_object_ref (nm_hostname_manager_get ());
+ g_signal_connect (priv->hostname_manager,
+ "notify::"NM_HOSTNAME_MANAGER_HOSTNAME,
+ G_CALLBACK (_hostname_changed_cb),
+ self);
+ _hostname_changed (self);
return TRUE;
}
@@ -2298,10 +1870,9 @@ get_property (GObject *object, guint prop_id,
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
break;
case PROP_HOSTNAME:
- g_value_take_string (value, nm_settings_get_hostname (self));
-
- /* Don't ever pass NULL through D-Bus */
- if (!g_value_get_string (value))
+ if (priv->hostname)
+ g_value_set_string (value, priv->hostname);
+ else
g_value_set_static_string (value, "");
break;
case PROP_CAN_MODIFY:
@@ -2362,32 +1933,13 @@ dispose (GObject *object)
g_object_unref (priv->agent_mgr);
- if (priv->hostname.hostnamed_proxy) {
- g_signal_handlers_disconnect_by_func (priv->hostname.hostnamed_proxy,
- G_CALLBACK (hostnamed_properties_changed),
+ if (priv->hostname_manager) {
+ g_signal_handlers_disconnect_by_func (priv->hostname_manager,
+ G_CALLBACK (_hostname_changed_cb),
self);
- g_clear_object (&priv->hostname.hostnamed_proxy);
- }
-
- if (priv->hostname.monitor) {
- if (priv->hostname.monitor_id)
- g_signal_handler_disconnect (priv->hostname.monitor, priv->hostname.monitor_id);
-
- g_file_monitor_cancel (priv->hostname.monitor);
- g_clear_object (&priv->hostname.monitor);
+ g_clear_object (&priv->hostname_manager);
}
- if (priv->hostname.dhcp_monitor) {
- if (priv->hostname.dhcp_monitor_id)
- g_signal_handler_disconnect (priv->hostname.dhcp_monitor,
- priv->hostname.dhcp_monitor_id);
-
- g_file_monitor_cancel (priv->hostname.dhcp_monitor);
- g_clear_object (&priv->hostname.dhcp_monitor);
- }
-
- g_clear_pointer (&priv->hostname.value, g_free);
-
G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
}
@@ -2405,6 +1957,8 @@ finalize (GObject *object)
g_slist_free_full (priv->plugins, g_object_unref);
+ g_free (priv->hostname);
+
g_clear_object (&priv->config);
G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h
index 7110a12ba8..eede76b029 100644
--- a/src/settings/nm-settings.h
+++ b/src/settings/nm-settings.h
@@ -119,20 +119,10 @@ gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *con
const GSList *nm_settings_get_unmanaged_specs (NMSettings *self);
-char *nm_settings_get_hostname (NMSettings *self);
-
void nm_settings_device_added (NMSettings *self, NMDevice *device);
void nm_settings_device_removed (NMSettings *self, NMDevice *device, gboolean quitting);
gboolean nm_settings_get_startup_complete (NMSettings *self);
-void nm_settings_set_transient_hostname (NMSettings *self,
- const char *hostname,
- NMSettingsSetHostnameCb cb,
- gpointer user_data);
-
-gboolean nm_settings_get_transient_hostname (NMSettings *self,
- char **hostname);
-
#endif /* __NM_SETTINGS_H__ */