diff --git a/configure.ac b/configure.ac
index adaf2e040f..7a8e7651e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -212,42 +212,10 @@ PKG_CHECK_MODULES(UUID, uuid)
AC_SUBST(UUID_CFLAGS)
AC_SUBST(UUID_LIBS)
-PKG_CHECK_MODULES(POLKIT, polkit-dbus)
+PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
-##### Find out the version of PolicyKit we're using
-polkit_version=`pkg-config --modversion polkit`
-POLKIT_VERSION_MAJOR=`echo $polkit_version | awk -F. '{print $1}'`
-POLKIT_VERSION_MINOR=`echo $polkit_version | awk -F. '{print $2}'`
-POLKIT_VERSION_MICRO=`echo $polkit_version | awk -F. '{print $3}'`
-if test "z$POLKIT_VERSION_MAJOR" = "z"; then
- POLKIT_VERSION_MAJOR="0"
-fi
-if test "z$POLKIT_VERSION_MINOR" = "z"; then
- POLKIT_VERSION_MINOR="0"
-fi
-if test "z$POLKIT_VERSION_MICRO" = "z"; then
- POLKIT_VERSION_MICRO="0"
-fi
-
-if test "z$POLKIT_VERSION_MAJOR" = "z0" -a "z$POLKIT_VERSION_MINOR" = "z0" -a "z$POLKIT_VERSION_MICRO" = "z0"; then
- echo "Error: Couldn't determine the version of your PolicyKit package."
- echo " This is probably an error in this script, please report it"
- echo " along with the following information:"
- echo " Base PolicyKit version ='$polkit_version'"
- echo " POLKIT_VERSION_MAJOR='$POLKIT_VERSION_MAJOR'"
- echo " POLKIT_VERSION_MINOR='$POLKIT_VERSION_MINOR'"
- echo " POLKIT_VERSION_MICRO='$POLKIT_VERSION_MICRO'"
- exit 1
-else
- echo "Your PolicyKit version is $POLKIT_VERSION_MAJOR,$POLKIT_VERSION_MINOR,$POLKIT_VERSION_MICRO."
- POLKIT_CFLAGS="$POLKIT_CFLAGS -DPOLKIT_VERSION_MAJOR=$POLKIT_VERSION_MAJOR"
- POLKIT_CFLAGS="$POLKIT_CFLAGS -DPOLKIT_VERSION_MINOR=$POLKIT_VERSION_MINOR"
- POLKIT_CFLAGS="$POLKIT_CFLAGS -DPOLKIT_VERSION_MICRO=$POLKIT_VERSION_MICRO"
-fi
AC_SUBST(POLKIT_CFLAGS)
-AC_PATH_PROG([POLKIT_POLICY_FILE_VALIDATE], [polkit-policy-file-validate], [false])
-
AC_ARG_WITH(crypto, AS_HELP_STRING([--with-crypto=nss | gnutls], [Cryptography library to use for certificate and key operations]),ac_crypto=$withval, ac_crypto=nss)
with_nss=no
diff --git a/introspection/nm-settings-system.xml b/introspection/nm-settings-system.xml
index 0e13b7a8d6..d03b8dddb8 100644
--- a/introspection/nm-settings-system.xml
+++ b/introspection/nm-settings-system.xml
@@ -8,7 +8,7 @@
- Add new connection.
+ DEPRECATED. Adds new connection.
diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml
index 5e072f2641..0e77a0377a 100644
--- a/introspection/nm-settings.xml
+++ b/introspection/nm-settings.xml
@@ -18,9 +18,22 @@
+
+
+ Add new connection.
+
+
+
+
+
+ Connection settings and properties.
+
+
+
+
- Emitted when a new connection has been configured.
+ Emitted when a new connection has been added.
diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am
index 16de0dd0c5..3e14bd750d 100644
--- a/libnm-glib/Makefile.am
+++ b/libnm-glib/Makefile.am
@@ -41,7 +41,6 @@ libnminclude_HEADERS = \
nm-device-bt.h \
nm-access-point.h \
nm-ip4-config.h \
- nm-settings.h \
nm-gsm-device.h \
nm-cdma-device.h \
nm-serial-device.h \
@@ -50,10 +49,15 @@ libnminclude_HEADERS = \
nm-vpn-plugin-ui-interface.h \
nm-types.h \
nm-active-connection.h \
- nm-dbus-connection.h \
- nm-dbus-settings.h \
- nm-dbus-settings-system.h \
- nm-dhcp4-config.h
+ nm-dhcp4-config.h \
+ nm-remote-connection.h \
+ nm-settings-interface.h \
+ nm-settings-system-interface.h \
+ nm-remote-settings.h \
+ nm-remote-settings-system.h \
+ nm-settings-connection-interface.h \
+ nm-exported-connection.h \
+ nm-settings-service.h
libnm_glib_la_SOURCES = \
libnm_glib.c \
@@ -69,7 +73,6 @@ libnm_glib_la_SOURCES = \
nm-device-bt.c \
nm-access-point.c \
nm-ip4-config.c \
- nm-settings.c \
nm-gsm-device.c \
nm-cdma-device.c \
nm-serial-device.c \
@@ -79,10 +82,15 @@ libnm_glib_la_SOURCES = \
nm-object-cache.c \
nm-object-cache.h \
nm-active-connection.c \
- nm-dbus-connection.c \
- nm-dbus-settings.c \
- nm-dbus-settings-system.c \
- nm-dhcp4-config.c
+ nm-dhcp4-config.c \
+ nm-remote-connection.c \
+ nm-settings-interface.c \
+ nm-settings-system-interface.c \
+ nm-remote-settings.c \
+ nm-remote-settings-system.c \
+ nm-settings-connection-interface.c \
+ nm-exported-connection.c \
+ nm-settings-service.c
libnm_glib_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
diff --git a/libnm-glib/libnm_glib.ver b/libnm-glib/libnm_glib.ver
index e45f347440..ef79722748 100644
--- a/libnm-glib/libnm_glib.ver
+++ b/libnm-glib/libnm_glib.ver
@@ -40,8 +40,6 @@ global:
nm_client_wireless_get_enabled;
nm_client_wireless_hardware_get_enabled;
nm_client_wireless_set_enabled;
- nm_dbus_connection_get_type;
- nm_dbus_connection_new;
nm_dbus_settings_get_connection_by_path;
nm_dbus_settings_get_type;
nm_dbus_settings_new;
@@ -85,14 +83,9 @@ global:
nm_dhcp4_config_get_options;
nm_dhcp4_config_get_type;
nm_dhcp4_config_new;
- nm_exported_connection_delete;
- nm_exported_connection_get_connection;
+ nm_exported_connection_export;
nm_exported_connection_get_type;
nm_exported_connection_new;
- nm_exported_connection_register_object;
- nm_exported_connection_signal_removed;
- nm_exported_connection_signal_updated;
- nm_exported_connection_update;
nm_gsm_device_get_type;
nm_gsm_device_new;
nm_ip4_config_get_addresses;
@@ -107,9 +100,31 @@ global:
nm_object_get_connection;
nm_object_get_path;
nm_object_get_type;
+ nm_remote_connection_get_type;
+ nm_remote_connection_new;
+ nm_remote_settings_get_type;
+ nm_remote_settings_new;
+ nm_remote_settings_system_get_type;
+ nm_remote_settings_system_new;
nm_serial_device_get_bytes_received;
nm_serial_device_get_bytes_sent;
nm_serial_device_get_type;
+ nm_settings_connection_interface_delete;
+ nm_settings_connection_interface_emit_updated;
+ nm_settings_connection_interface_get_secrets;
+ nm_settings_connection_interface_get_type;
+ nm_settings_connection_interface_update;
+ nm_settings_interface_add_connection;
+ nm_settings_interface_error_quark;
+ nm_settings_interface_get_connection_by_path;
+ nm_settings_interface_get_type;
+ nm_settings_interface_list_connections;
+ nm_settings_service_export;
+ nm_settings_service_get_connection_by_path;
+ nm_settings_service_get_type;
+ nm_settings_system_interface_get_type;
+ nm_settings_system_interface_add_connection;
+ nm_settings_system_interface_save_hostname;
nm_settings_error_quark;
nm_settings_get_type;
nm_settings_list_connections;
diff --git a/libnm-glib/nm-dbus-connection.c b/libnm-glib/nm-dbus-connection.c
deleted file mode 100644
index 25085b7d1b..0000000000
--- a/libnm-glib/nm-dbus-connection.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#include
-#include
-#include
-#include "nm-dbus-connection.h"
-#include "nm-exported-connection-bindings.h"
-#include "nm-utils.h"
-
-G_DEFINE_TYPE (NMDBusConnection, nm_dbus_connection, NM_TYPE_EXPORTED_CONNECTION)
-
-#define NM_DBUS_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DBUS_CONNECTION, NMDBusConnectionPrivate))
-
-typedef struct {
- DBusGConnection *dbus_connection;
- NMConnectionScope scope;
- char *path;
-
- DBusGProxy *proxy;
-
- gboolean disposed;
-} NMDBusConnectionPrivate;
-
-enum {
- PROP_0,
- PROP_BUS,
- PROP_SCOPE,
- PROP_PATH,
-
- LAST_PROP
-};
-
-NMDBusConnection *
-nm_dbus_connection_new (DBusGConnection *dbus_connection,
- NMConnectionScope scope,
- const char *path)
-{
- g_return_val_if_fail (dbus_connection != NULL, NULL);
- g_return_val_if_fail (scope != NM_CONNECTION_SCOPE_UNKNOWN, NULL);
- g_return_val_if_fail (path != NULL, NULL);
-
- return (NMDBusConnection *) g_object_new (NM_TYPE_DBUS_CONNECTION,
- NM_DBUS_CONNECTION_BUS, dbus_connection,
- NM_DBUS_CONNECTION_SCOPE, scope,
- NM_DBUS_CONNECTION_PATH, path,
- NULL);
-}
-
-static GHashTable *
-get_settings (NMExportedConnection *exported)
-{
- return nm_connection_to_hash (nm_exported_connection_get_connection (exported));
-}
-
-static gboolean
-update (NMExportedConnection *exported, GHashTable *new_settings, GError **err)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (exported);
-
- return org_freedesktop_NetworkManagerSettings_Connection_update (priv->proxy, new_settings, err);
-}
-
-static gboolean
-do_delete (NMExportedConnection *exported, GError **err)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (exported);
-
- return org_freedesktop_NetworkManagerSettings_Connection_delete (priv->proxy, err);
-}
-
-static void
-connection_updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_data)
-{
- NMExportedConnection *exported = NM_EXPORTED_CONNECTION (user_data);
- NMConnection *wrapped;
- GError *error = NULL;
-
- wrapped = nm_exported_connection_get_connection (exported);
- if (nm_connection_replace_settings (wrapped, settings, &error))
- nm_exported_connection_signal_updated (exported, settings);
- else {
- g_warning ("%s: '%s' / '%s' invalid: %d",
- __func__,
- error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
- (error && error->message) ? error->message : "(none)",
- error ? error->code : -1);
- g_clear_error (&error);
- nm_exported_connection_signal_removed (exported);
- }
-}
-
-static void
-connection_removed_cb (DBusGProxy *proxy, gpointer user_data)
-{
- nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (user_data));
-}
-
-/* GObject */
-
-static void
-nm_dbus_connection_init (NMDBusConnection *connection)
-{
-}
-
-static GObject *
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- NMDBusConnectionPrivate *priv;
- NMConnection *wrapped;
- const char *service;
- GHashTable *settings = NULL;
- GError *error = NULL;
-
- object = G_OBJECT_CLASS (nm_dbus_connection_parent_class)->constructor (type, n_construct_params, construct_params);
-
- if (!object)
- return NULL;
-
- priv = NM_DBUS_CONNECTION_GET_PRIVATE (object);
-
- if (!priv->dbus_connection) {
- nm_warning ("DBusGConnection not provided.");
- goto err;
- }
-
- if (!priv->path)
- nm_warning ("DBus path not provided.");
-
- service = (priv->scope == NM_CONNECTION_SCOPE_SYSTEM) ?
- NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS;
-
- priv->proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
- service,
- priv->path,
- NM_DBUS_IFACE_SETTINGS_CONNECTION);
-
- if (!org_freedesktop_NetworkManagerSettings_Connection_get_settings (priv->proxy, &settings, &error)) {
- nm_warning ("Can not retrieve settings: %s", error->message);
- g_error_free (error);
- goto err;
- }
-
- wrapped = nm_connection_new_from_hash (settings, &error);
- g_hash_table_destroy (settings);
-
- if (!wrapped) {
- nm_warning ("Invalid connection: '%s' / '%s' invalid: %d",
- g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
- error->message,
- error->code);
- g_error_free (error);
- goto err;
- }
-
- nm_connection_set_scope (wrapped, priv->scope);
- nm_connection_set_path (wrapped, priv->path);
-
- g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL);
- g_object_unref (wrapped);
-
- dbus_g_proxy_add_signal (priv->proxy, "Updated",
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->proxy, "Updated",
- G_CALLBACK (connection_updated_cb),
- object, NULL);
-
- dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->proxy, "Removed",
- G_CALLBACK (connection_removed_cb),
- object, NULL);
-
- return object;
-
- err:
- g_object_unref (object);
-
- return NULL;
-}
-
-static void
-dispose (GObject *object)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (object);
-
- if (priv->disposed)
- return;
-
- priv->disposed = TRUE;
-
- g_object_unref (priv->proxy);
- dbus_g_connection_unref (priv->dbus_connection);
-
- G_OBJECT_CLASS (nm_dbus_connection_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (object);
-
- g_free (priv->path);
-
- G_OBJECT_CLASS (nm_dbus_connection_parent_class)->finalize (object);
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_BUS:
- /* Construct only */
- priv->dbus_connection = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
- break;
- case PROP_SCOPE:
- /* Construct only */
- priv->scope = (NMConnectionScope) g_value_get_uint (value);
- break;
- case PROP_PATH:
- /* Construct only */
- priv->path = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_BUS:
- g_value_set_boxed (value, priv->dbus_connection);
- break;
- case PROP_SCOPE:
- g_value_set_uint (value, priv->scope);
- break;
- case PROP_PATH:
- g_value_set_string (value, priv->path);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_dbus_connection_class_init (NMDBusConnectionClass *dbus_connection_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (dbus_connection_class);
- NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (dbus_connection_class);
-
- g_type_class_add_private (dbus_connection_class, sizeof (NMDBusConnectionPrivate));
-
- /* Virtual methods */
- object_class->constructor = constructor;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = finalize;
-
- connection_class->get_settings = get_settings;
- connection_class->update = update;
- connection_class->do_delete = do_delete;
-
- /* Properties */
- g_object_class_install_property
- (object_class, PROP_BUS,
- g_param_spec_boxed (NM_DBUS_CONNECTION_BUS,
- "DBusGConnection",
- "DBusGConnection",
- DBUS_TYPE_G_CONNECTION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, PROP_SCOPE,
- g_param_spec_uint (NM_DBUS_CONNECTION_SCOPE,
- "Scope",
- "NMConnection scope",
- NM_CONNECTION_SCOPE_UNKNOWN,
- NM_CONNECTION_SCOPE_USER,
- NM_CONNECTION_SCOPE_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, PROP_PATH,
- g_param_spec_string (NM_DBUS_CONNECTION_PATH,
- "DBus path",
- "DBus path",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
diff --git a/libnm-glib/nm-dbus-connection.h b/libnm-glib/nm-dbus-connection.h
deleted file mode 100644
index e6b0bc675b..0000000000
--- a/libnm-glib/nm-dbus-connection.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#ifndef NM_DBUS_CONNECTION_H
-#define NM_DBUS_CONNECTION_H
-
-#include
-#include
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_DBUS_CONNECTION (nm_dbus_connection_get_type ())
-#define NM_DBUS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DBUS_CONNECTION, NMDBusConnection))
-#define NM_DBUS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DBUS_CONNECTION, NMDBusConnectionClass))
-#define NM_IS_DBUS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DBUS_CONNECTION))
-#define NM_IS_DBUS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DBUS_CONNECTION))
-#define NM_DBUS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DBUS_CONNECTION, NMDBusConnectionClass))
-
-#define NM_DBUS_CONNECTION_BUS "bus"
-#define NM_DBUS_CONNECTION_SCOPE "scope"
-#define NM_DBUS_CONNECTION_PATH "path"
-
-typedef struct {
- NMExportedConnection parent;
-} NMDBusConnection;
-
-typedef struct {
- NMExportedConnectionClass parent;
-} NMDBusConnectionClass;
-
-GType nm_dbus_connection_get_type (void);
-
-NMDBusConnection *nm_dbus_connection_new (DBusGConnection *dbus_connection,
- NMConnectionScope scope,
- const char *path);
-
-G_END_DECLS
-
-#endif /* NM_DBUS_CONNECTION_H */
diff --git a/libnm-glib/nm-dbus-settings-system.c b/libnm-glib/nm-dbus-settings-system.c
deleted file mode 100644
index 16ff4ec0a5..0000000000
--- a/libnm-glib/nm-dbus-settings-system.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#include
-#include
-#include "nm-dbus-settings-system.h"
-#include "nm-settings-system-bindings.h"
-
-G_DEFINE_TYPE (NMDBusSettingsSystem, nm_dbus_settings_system, NM_TYPE_DBUS_SETTINGS)
-
-#define NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DBUS_SETTINGS_SYSTEM, NMDBusSettingsSystemPrivate))
-
-typedef struct {
- DBusGProxy *settings_proxy;
- DBusGProxy *props_proxy;
-
- gboolean got_unmanaged_devices;
- GSList *unmanaged_devices;
-
- gboolean got_hostname;
- char *hostname;
-
- gboolean got_can_modify;
- gboolean can_modify;
-
- gboolean disposed;
-} NMDBusSettingsSystemPrivate;
-
-enum {
- PROP_0,
- PROP_UNMANAGED_DEVICES,
- PROP_HOSTNAME,
- PROP_CAN_MODIFY,
-
- LAST_PROP
-};
-
-NMDBusSettingsSystem *
-nm_dbus_settings_system_new (DBusGConnection *dbus_connection)
-{
- g_return_val_if_fail (dbus_connection != NULL, NULL);
-
- return (NMDBusSettingsSystem *) g_object_new (NM_TYPE_DBUS_SETTINGS_SYSTEM,
- NM_DBUS_SETTINGS_DBUS_CONNECTION, dbus_connection,
- NM_DBUS_SETTINGS_SCOPE, NM_CONNECTION_SCOPE_SYSTEM,
- NULL);
-}
-
-gboolean
-nm_dbus_settings_system_add_connection (NMDBusSettingsSystem *self,
- NMConnection *connection,
- GError **err)
-{
- NMDBusSettingsSystemPrivate *priv;
- GHashTable *settings;
- gboolean ret;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self), FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
- settings = nm_connection_to_hash (connection);
-
- ret = org_freedesktop_NetworkManagerSettings_System_add_connection (priv->settings_proxy, settings, err);
- g_hash_table_destroy (settings);
-
- return ret;
-}
-
-static void
-update_unmanaged_devices (NMDBusSettingsSystem *self, GValue *value)
-{
- NMDBusSettingsSystemPrivate *priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- if (priv->unmanaged_devices) {
- g_slist_foreach (priv->unmanaged_devices, (GFunc) g_free, NULL);
- g_slist_free (priv->unmanaged_devices);
- priv->unmanaged_devices = NULL;
- }
-
- if (G_VALUE_TYPE (value) == DBUS_TYPE_G_OBJECT_ARRAY) {
- GPtrArray *array;
- int i;
-
- array = (GPtrArray *) g_value_get_boxed (value);
- for (i = 0; i < array->len; i++)
- priv->unmanaged_devices = g_slist_prepend (priv->unmanaged_devices,
- g_strdup ((const char *) g_ptr_array_index (array, i)));
-
- priv->got_unmanaged_devices = TRUE;
- } else
- g_warning ("Invalid return value type: %s", G_VALUE_TYPE_NAME (value));
-}
-
-GSList *
-nm_dbus_settings_system_get_unmanaged_devices (NMDBusSettingsSystem *self)
-{
- NMDBusSettingsSystemPrivate *priv;
- GValue value = { 0, };
- GError *err = NULL;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self), NULL);
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- if (priv->got_unmanaged_devices)
- return priv->unmanaged_devices;
-
- if (!dbus_g_proxy_call (priv->props_proxy, "Get", &err,
- G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- G_TYPE_STRING, "UnmanagedDevices",
- G_TYPE_INVALID,
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID)) {
- g_warning ("Could not retrieve unmanaged devices: %s", err->message);
- g_error_free (err);
- return NULL;
- }
-
- update_unmanaged_devices (self, &value);
- g_value_unset (&value);
-
- return priv->unmanaged_devices;
-}
-
-gboolean
-nm_dbus_settings_system_save_hostname (NMDBusSettingsSystem *self,
- const char *hostname,
- GError **err)
-{
- NMDBusSettingsSystemPrivate *priv;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self), FALSE);
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- return org_freedesktop_NetworkManagerSettings_System_save_hostname (priv->settings_proxy, hostname ? hostname : "", err);
-}
-
-static void
-update_hostname (NMDBusSettingsSystem *self, GValue *value)
-{
- NMDBusSettingsSystemPrivate *priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- if (priv->hostname) {
- g_free (priv->hostname);
- priv->hostname = NULL;
- }
-
- if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
- priv->hostname = g_value_dup_string (value);
- priv->got_hostname = TRUE;
- } else
- g_warning ("%s: Invalid return value type: %s", __func__, G_VALUE_TYPE_NAME (value));
-}
-
-const char *
-nm_dbus_settings_system_get_hostname (NMDBusSettingsSystem *self)
-{
- NMDBusSettingsSystemPrivate *priv;
- GValue value = { 0, };
- GError *err = NULL;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self), NULL);
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- if (priv->got_hostname)
- return priv->hostname;
-
- if (!dbus_g_proxy_call (priv->props_proxy, "Get", &err,
- G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- G_TYPE_STRING, "Hostname",
- G_TYPE_INVALID,
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID)) {
- g_warning ("Could not retrieve hostname: %s", err->message);
- g_error_free (err);
- return NULL;
- }
-
- update_hostname (self, &value);
- g_value_unset (&value);
-
- return priv->hostname;
-}
-
-gboolean
-nm_dbus_settings_system_get_can_modify (NMDBusSettingsSystem *self)
-{
- NMDBusSettingsSystemPrivate *priv;
- GValue value = { 0, };
- GError *err = NULL;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self), FALSE);
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
-
- if (priv->got_can_modify)
- return priv->can_modify;
-
- if (!dbus_g_proxy_call (priv->props_proxy, "Get", &err,
- G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- G_TYPE_STRING, "CanModify",
- G_TYPE_INVALID,
- G_TYPE_VALUE, &value,
- G_TYPE_INVALID)) {
- g_warning ("Could not retrieve can-modify: %s", err->message);
- g_error_free (err);
- return FALSE;
- }
-
- priv->can_modify = g_value_get_boolean (&value);
- g_value_unset (&value);
-
- return priv->can_modify;
-}
-
-static void
-proxy_properties_changed (DBusGProxy *proxy,
- GHashTable *properties,
- gpointer user_data)
-{
- NMDBusSettingsSystem *self = NM_DBUS_SETTINGS_SYSTEM (user_data);
- NMDBusSettingsSystemPrivate * priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (self);
- GValue *value;
-
- value = (GValue *) g_hash_table_lookup (properties, "UnmanagedDevices");
- if (value) {
- update_unmanaged_devices (self, value);
- g_object_notify (G_OBJECT (self), NM_DBUS_SETTINGS_SYSTEM_UNMANAGED_DEVICES);
- }
-
- value = (GValue *) g_hash_table_lookup (properties, "Hostname");
- if (value) {
- update_hostname (self, value);
- g_object_notify (G_OBJECT (self), NM_DBUS_SETTINGS_SYSTEM_HOSTNAME);
- }
-
- value = (GValue *) g_hash_table_lookup (properties, "CanModify");
- if (value) {
- priv->can_modify = g_value_get_boolean (value);
- g_object_notify (G_OBJECT (self), NM_DBUS_SETTINGS_SYSTEM_CAN_MODIFY);
- }
-}
-
-static void
-nm_dbus_settings_system_init (NMDBusSettingsSystem *self)
-{
-}
-
-static GObject *
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- NMDBusSettingsSystemPrivate *priv;
- DBusGConnection *dbus_connection = NULL;
-
- object = G_OBJECT_CLASS (nm_dbus_settings_system_parent_class)->constructor (type, n_construct_params, construct_params);
-
- if (!object)
- return NULL;
-
- priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (object);
-
- g_object_get (object,
- NM_DBUS_SETTINGS_DBUS_CONNECTION, &dbus_connection,
- NULL);
-
- priv->settings_proxy = dbus_g_proxy_new_for_name (dbus_connection,
- NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- NM_DBUS_PATH_SETTINGS,
- NM_DBUS_IFACE_SETTINGS_SYSTEM);
- dbus_g_proxy_add_signal (priv->settings_proxy, "PropertiesChanged",
- DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->settings_proxy, "PropertiesChanged",
- G_CALLBACK (proxy_properties_changed),
- object, NULL);
-
- priv->props_proxy = dbus_g_proxy_new_for_name (dbus_connection,
- NM_DBUS_SERVICE_SYSTEM_SETTINGS,
- NM_DBUS_PATH_SETTINGS,
- "org.freedesktop.DBus.Properties");
-
- return object;
-}
-
-static void
-dispose (GObject *object)
-{
- NMDBusSettingsSystemPrivate *priv = NM_DBUS_SETTINGS_SYSTEM_GET_PRIVATE (object);
-
- if (priv->disposed)
- return;
-
- priv->disposed = TRUE;
-
- g_free (priv->hostname);
-
- if (priv->unmanaged_devices) {
- g_slist_foreach (priv->unmanaged_devices, (GFunc) g_free, NULL);
- g_slist_free (priv->unmanaged_devices);
- }
-
- g_object_unref (priv->settings_proxy);
- g_object_unref (priv->props_proxy);
-
- G_OBJECT_CLASS (nm_dbus_settings_system_parent_class)->dispose (object);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMDBusSettingsSystem *self = NM_DBUS_SETTINGS_SYSTEM (object);
-
- switch (prop_id) {
- case PROP_UNMANAGED_DEVICES:
- g_value_set_pointer (value, nm_dbus_settings_system_get_unmanaged_devices (self));
- break;
- case PROP_HOSTNAME:
- g_value_set_string (value, nm_dbus_settings_system_get_hostname (self));
- break;
- case PROP_CAN_MODIFY:
- g_value_set_boolean (value, nm_dbus_settings_system_get_can_modify (self));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_dbus_settings_system_class_init (NMDBusSettingsSystemClass *dbus_settings_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (dbus_settings_class);
-
- g_type_class_add_private (dbus_settings_class, sizeof (NMDBusSettingsSystemPrivate));
-
- /* Virtual methods */
- object_class->constructor = constructor;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
-
- /* Properties */
- g_object_class_install_property
- (object_class, PROP_UNMANAGED_DEVICES,
- g_param_spec_pointer (NM_DBUS_SETTINGS_SYSTEM_UNMANAGED_DEVICES,
- "Unmanaged devices",
- "Unmanaged devices",
- G_PARAM_READABLE));
-
- g_object_class_install_property
- (object_class, PROP_HOSTNAME,
- g_param_spec_string (NM_DBUS_SETTINGS_SYSTEM_HOSTNAME,
- "Hostname",
- "Configured hostname",
- NULL,
- G_PARAM_READABLE));
-
- g_object_class_install_property
- (object_class, PROP_HOSTNAME,
- g_param_spec_boolean (NM_DBUS_SETTINGS_SYSTEM_CAN_MODIFY,
- "Can modify",
- "Can modify",
- FALSE,
- G_PARAM_READABLE));
-}
-
diff --git a/libnm-glib/nm-dbus-settings-system.h b/libnm-glib/nm-dbus-settings-system.h
deleted file mode 100644
index 5c6175b6a8..0000000000
--- a/libnm-glib/nm-dbus-settings-system.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
- */
-
-#ifndef NM_DBUS_SETTINGS_SYSTEM_H
-#define NM_DBUS_SETTINGS_SYSTEM_H
-
-#include
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_DBUS_SETTINGS_SYSTEM (nm_dbus_settings_system_get_type ())
-#define NM_DBUS_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DBUS_SETTINGS_SYSTEM, NMDBusSettingsSystem))
-#define NM_DBUS_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DBUS_SETTINGS_SYSTEM, NMDBusSettingsSystemClass))
-#define NM_IS_DBUS_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DBUS_SETTINGS_SYSTEM))
-#define NM_IS_DBUS_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DBUS_SETTINGS_SYSTEM))
-#define NM_DBUS_SETTINGS_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DBUS_SETTINGS_SYSTEM, NMDBusSettingsSystemClass))
-
-#define NM_DBUS_SETTINGS_SYSTEM_UNMANAGED_DEVICES "unmanaged-devices"
-#define NM_DBUS_SETTINGS_SYSTEM_HOSTNAME "hostname"
-#define NM_DBUS_SETTINGS_SYSTEM_CAN_MODIFY "can-modify"
-
-typedef struct {
- NMDBusSettings parent;
-} NMDBusSettingsSystem;
-
-typedef struct {
- NMDBusSettingsClass parent;
-} NMDBusSettingsSystemClass;
-
-GType nm_dbus_settings_system_get_type (void);
-
-NMDBusSettingsSystem *nm_dbus_settings_system_new (DBusGConnection *dbus_connection);
-
-gboolean nm_dbus_settings_system_add_connection (NMDBusSettingsSystem *self,
- NMConnection *connection,
- GError **err);
-
-GSList *nm_dbus_settings_system_get_unmanaged_devices (NMDBusSettingsSystem *self);
-
-const char *nm_dbus_settings_system_get_hostname (NMDBusSettingsSystem *self);
-
-gboolean nm_dbus_settings_system_save_hostname (NMDBusSettingsSystem *self,
- const char *hostname,
- GError **err);
-
-gboolean nm_dbus_settings_system_get_can_modify (NMDBusSettingsSystem *self);
-
-G_END_DECLS
-
-#endif /* NM_DBUS_SETTINGS_SYSTEM_H */
diff --git a/libnm-glib/nm-dbus-settings.c b/libnm-glib/nm-dbus-settings.c
deleted file mode 100644
index 9f47d903a4..0000000000
--- a/libnm-glib/nm-dbus-settings.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- */
-
-#include
-#include
-#include
-
-#include "nm-dbus-settings.h"
-#include "nm-settings-bindings.h"
-
-G_DEFINE_TYPE (NMDBusSettings, nm_dbus_settings, NM_TYPE_SETTINGS)
-
-#define NM_DBUS_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DBUS_SETTINGS, NMDBusSettingsPrivate))
-
-typedef struct {
- DBusGConnection *dbus_connection;
- NMConnectionScope scope;
- DBusGProxy *settings_proxy;
- DBusGProxy *dbus_proxy;
-
- GHashTable *connections;
-
- gboolean disposed;
-} NMDBusSettingsPrivate;
-
-enum {
- PROP_0,
- PROP_DBUS_CONNECTION,
- PROP_SCOPE,
-
- LAST_PROP
-};
-
-NMDBusSettings *
-nm_dbus_settings_new (DBusGConnection *dbus_connection)
-{
- g_return_val_if_fail (dbus_connection != NULL, NULL);
-
- return (NMDBusSettings *) g_object_new (NM_TYPE_DBUS_SETTINGS,
- NM_DBUS_SETTINGS_DBUS_CONNECTION, dbus_connection,
- NM_DBUS_SETTINGS_SCOPE, NM_CONNECTION_SCOPE_USER,
- NULL);
-}
-
-NMDBusConnection *
-nm_dbus_settings_get_connection_by_path (NMDBusSettings *self, const char *path)
-{
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS (self), NULL);
- g_return_val_if_fail (path != NULL, NULL);
-
- return g_hash_table_lookup (NM_DBUS_SETTINGS_GET_PRIVATE (self)->connections, path);
-}
-
-static void
-connection_removed_cb (NMExportedConnection *exported, gpointer user_data)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (user_data);
- NMConnection *connection;
-
- connection = nm_exported_connection_get_connection (exported);
- g_hash_table_remove (priv->connections, nm_connection_get_path (connection));
-}
-
-static void
-new_connection_cb (DBusGProxy *proxy,
- const char *path,
- gpointer user_data)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (user_data);
- NMDBusConnection *connection;
-
- connection = nm_dbus_connection_new (priv->dbus_connection, priv->scope, path);
- if (connection) {
- g_signal_connect (connection, "removed",
- G_CALLBACK (connection_removed_cb),
- user_data);
-
- g_hash_table_insert (priv->connections, g_strdup (path), connection);
- nm_settings_signal_new_connection (NM_SETTINGS (user_data),
- NM_EXPORTED_CONNECTION (connection));
- }
-}
-
-static void
-fetch_connections_done (DBusGProxy *proxy,
- GPtrArray *connections,
- GError *err,
- gpointer user_data)
-{
- if (!err) {
- int i;
-
- for (i = 0; i < connections->len; i++) {
- char *path = g_ptr_array_index (connections, i);
-
- new_connection_cb (proxy, path, user_data);
- g_free (path);
- }
-
- g_ptr_array_free (connections, TRUE);
- } else {
- g_warning ("Could not retrieve dbus connections: %s.", err->message);
- g_error_free (err);
- }
-}
-
-static void
-settings_proxy_destroyed (gpointer data, GObject *destroyed_object)
-{
- NM_DBUS_SETTINGS_GET_PRIVATE (data)->settings_proxy = NULL;
-}
-
-static gboolean
-fetch_connections (gpointer data)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (data);
- DBusGProxyCall *call;
-
- if (!priv->settings_proxy) {
- const char *service = (priv->scope == NM_CONNECTION_SCOPE_SYSTEM) ?
- NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS;
-
- priv->settings_proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
- service,
- NM_DBUS_PATH_SETTINGS,
- NM_DBUS_IFACE_SETTINGS);
-
- g_object_weak_ref (G_OBJECT (priv->settings_proxy), settings_proxy_destroyed, data);
-
- dbus_g_proxy_add_signal (priv->settings_proxy, "NewConnection",
- DBUS_TYPE_G_OBJECT_PATH,
- G_TYPE_INVALID);
-
- dbus_g_proxy_connect_signal (priv->settings_proxy, "NewConnection",
- G_CALLBACK (new_connection_cb),
- data,
- NULL);
- }
-
- call = org_freedesktop_NetworkManagerSettings_list_connections_async (priv->settings_proxy,
- fetch_connections_done,
- data);
-
- return FALSE;
-}
-
-static void
-hash_values_to_slist (gpointer key, gpointer data, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_prepend (*list, data);
-}
-
-static GSList *
-list_connections (NMSettings *settings)
-{
- GSList *list = NULL;
-
- g_return_val_if_fail (NM_IS_DBUS_SETTINGS (settings), NULL);
-
- g_hash_table_foreach (NM_DBUS_SETTINGS_GET_PRIVATE (settings)->connections, hash_values_to_slist, &list);
-
- return list;
-}
-
-static void
-remove_one_connection (gpointer key, gpointer value, gpointer user_data)
-{
- nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (value));
-}
-
-static gboolean
-remove_connections (gpointer data)
-{
- NMDBusSettings *self = NM_DBUS_SETTINGS (data);
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (self);
-
- g_hash_table_foreach (priv->connections, remove_one_connection, NULL);
-
- return FALSE;
-}
-
-static void
-name_owner_changed (DBusGProxy *proxy,
- const char *name,
- const char *old_owner,
- const char *new_owner,
- gpointer user_data)
-{
- if (!strcmp (name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) {
- if (new_owner && strlen (new_owner) > 0)
- g_idle_add (fetch_connections, user_data);
- else
- g_idle_add (remove_connections, user_data);
- }
-}
-
-/* GObject stuff */
-
-static void
-nm_dbus_settings_init (NMDBusSettings *settings)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (settings);
-
- priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-}
-
-static GObject *
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- GObject *object;
- NMDBusSettingsPrivate *priv;
-
- object = G_OBJECT_CLASS (nm_dbus_settings_parent_class)->constructor (type, n_construct_params, construct_params);
-
- if (!object)
- return NULL;
-
- priv = NM_DBUS_SETTINGS_GET_PRIVATE (object);
-
- if (!priv->dbus_connection) {
- g_warning ("DBus connection not provided.");
- goto err;
- }
-
- if (priv->scope == NM_CONNECTION_SCOPE_UNKNOWN) {
- g_warning ("Connection scope not provided.");
- goto err;
- }
-
- priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus");
-
- dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->dbus_proxy,
- "NameOwnerChanged",
- G_CALLBACK (name_owner_changed),
- object, NULL);
-
- g_idle_add (fetch_connections, object);
-
- return object;
-
- err:
- g_object_unref (object);
-
- return NULL;
-}
-
-static void
-dispose (GObject *object)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (object);
-
- if (priv->disposed)
- return;
-
- priv->disposed = TRUE;
-
- if (priv->connections)
- g_hash_table_destroy (priv->connections);
-
- if (priv->dbus_proxy)
- g_object_unref (priv->dbus_proxy);
-
- if (priv->settings_proxy)
- g_object_unref (priv->settings_proxy);
-
- dbus_g_connection_unref (priv->dbus_connection);
-
- G_OBJECT_CLASS (nm_dbus_settings_parent_class)->dispose (object);
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_DBUS_CONNECTION:
- /* Construct only */
- priv->dbus_connection = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
- break;
- case PROP_SCOPE:
- priv->scope = (NMConnectionScope) g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMDBusSettingsPrivate *priv = NM_DBUS_SETTINGS_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_DBUS_CONNECTION:
- g_value_set_boxed (value, priv->dbus_connection);
- break;
- case PROP_SCOPE:
- g_value_set_uint (value, priv->scope);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_dbus_settings_class_init (NMDBusSettingsClass *dbus_settings_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (dbus_settings_class);
- NMSettingsClass *settings_class = NM_SETTINGS_CLASS (dbus_settings_class);
-
- g_type_class_add_private (dbus_settings_class, sizeof (NMDBusSettingsPrivate));
-
- /* Virtual methods */
- object_class->constructor = constructor;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
-
- settings_class->list_connections = list_connections;
-
- /* Properties */
- g_object_class_install_property
- (object_class, PROP_DBUS_CONNECTION,
- g_param_spec_boxed (NM_DBUS_SETTINGS_DBUS_CONNECTION,
- "DBusGConnection",
- "DBusGConnection",
- DBUS_TYPE_G_CONNECTION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, PROP_SCOPE,
- g_param_spec_uint (NM_DBUS_SETTINGS_SCOPE,
- "Scope",
- "NMConnection scope",
- NM_CONNECTION_SCOPE_UNKNOWN,
- NM_CONNECTION_SCOPE_USER,
- NM_CONNECTION_SCOPE_USER,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
diff --git a/libnm-glib/nm-dbus-settings.h b/libnm-glib/nm-dbus-settings.h
deleted file mode 100644
index bdf33ec094..0000000000
--- a/libnm-glib/nm-dbus-settings.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2008 Novell, Inc.
- */
-
-#ifndef NM_DBUS_SETTINGS_H
-#define NM_DBUS_SETTINGS_H
-
-#include
-#include
-#include
-#include
-
-G_BEGIN_DECLS
-
-#define NM_TYPE_DBUS_SETTINGS (nm_dbus_settings_get_type ())
-#define NM_DBUS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DBUS_SETTINGS, NMDBusSettings))
-#define NM_DBUS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DBUS_SETTINGS, NMDBusSettingsClass))
-#define NM_IS_DBUS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DBUS_SETTINGS))
-#define NM_IS_DBUS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DBUS_SETTINGS))
-#define NM_DBUS_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DBUS_SETTINGS, NMDBusSettingsClass))
-
-#define NM_DBUS_SETTINGS_DBUS_CONNECTION "dbus-connection"
-#define NM_DBUS_SETTINGS_SCOPE "scope"
-
-typedef struct {
- NMSettings parent;
-} NMDBusSettings;
-
-typedef struct {
- NMSettingsClass parent;
-} NMDBusSettingsClass;
-
-GType nm_dbus_settings_get_type (void);
-
-NMDBusSettings *nm_dbus_settings_new (DBusGConnection *dbus_connection);
-
-NMDBusConnection *nm_dbus_settings_get_connection_by_path (NMDBusSettings *self,
- const char *path);
-
-G_END_DECLS
-
-#endif /* NM_DBUS_SETTINGS_H */
diff --git a/libnm-glib/nm-exported-connection.c b/libnm-glib/nm-exported-connection.c
new file mode 100644
index 0000000000..57dde41442
--- /dev/null
+++ b/libnm-glib/nm-exported-connection.c
@@ -0,0 +1,306 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * 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 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
+
+#include
+#include
+
+#include "nm-exported-connection.h"
+#include "nm-settings-connection-interface.h"
+
+static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection,
+ GHashTable **settings,
+ GError **error);
+
+static void impl_exported_connection_update (NMExportedConnection *connection,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context);
+
+static void impl_exported_connection_delete (NMExportedConnection *connection,
+ DBusGMethodInvocation *context);
+
+static void impl_exported_connection_get_secrets (NMExportedConnection *connection,
+ const gchar *setting_name,
+ const gchar **hints,
+ gboolean request_new,
+ DBusGMethodInvocation *context);
+
+#include "nm-exported-connection-glue.h"
+
+G_DEFINE_TYPE (NMExportedConnection, nm_exported_connection, NM_TYPE_CONNECTION)
+
+#define NM_EXPORTED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_EXPORTED_CONNECTION, \
+ NMExportedConnectionPrivate))
+
+typedef struct {
+ DBusGConnection *bus;
+ gboolean disposed;
+} NMExportedConnectionPrivate;
+
+enum {
+ PROP_0,
+ PROP_BUS,
+
+ LAST_PROP
+};
+
+
+/**************************************************************/
+
+void
+nm_exported_connection_export (NMExportedConnection *self)
+{
+ NMExportedConnectionPrivate *priv;
+ static guint32 ec_counter = 0;
+ char *path;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (NM_IS_EXPORTED_CONNECTION (self));
+
+ priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (self);
+
+ /* Don't allow exporting twice */
+ g_return_if_fail (nm_connection_get_path (NM_CONNECTION (self)) == NULL);
+
+ path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
+ nm_connection_set_path (NM_CONNECTION (self), path);
+ dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (self));
+ g_free (path);
+}
+
+static GHashTable *
+real_get_settings (NMExportedConnection *self, GError **error)
+{
+ NMConnection *no_secrets;
+ GHashTable *settings;
+
+ /* Secrets should *never* be returned by the GetSettings method, they
+ * get returned by the GetSecrets method which can be better
+ * protected against leakage of secrets to unprivileged callers.
+ */
+ no_secrets = nm_connection_duplicate (NM_CONNECTION (self));
+ g_assert (no_secrets);
+ nm_connection_clear_secrets (no_secrets);
+ settings = nm_connection_to_hash (no_secrets);
+ g_assert (settings);
+ g_object_unref (no_secrets);
+
+ return settings;
+}
+
+/**************************************************************/
+
+static gboolean
+impl_exported_connection_get_settings (NMExportedConnection *self,
+ GHashTable **settings,
+ GError **error)
+{
+ /* Must always be implemented */
+ g_assert (NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_settings);
+ *settings = NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_settings (self, error);
+ return *settings ? TRUE : FALSE;
+}
+
+static void
+impl_exported_connection_update (NMExportedConnection *self,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context)
+{
+ NMConnection *tmp;
+ GError *error = NULL;
+
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (new_settings, &error);
+ if (!tmp) {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+ g_object_unref (tmp);
+
+ if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->update)
+ NM_EXPORTED_CONNECTION_GET_CLASS (self)->update (self, new_settings, context);
+ else {
+ error = g_error_new (0, 0, "%s: %s:%d update() unimplemented", __func__, __FILE__, __LINE__);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+static void
+impl_exported_connection_delete (NMExportedConnection *self,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+
+ if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->delete)
+ NM_EXPORTED_CONNECTION_GET_CLASS (self)->delete (self, context);
+ else {
+ error = g_error_new (0, 0, "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+static void
+impl_exported_connection_get_secrets (NMExportedConnection *self,
+ const gchar *setting_name,
+ const gchar **hints,
+ gboolean request_new,
+ DBusGMethodInvocation *context)
+{
+ GError *error = NULL;
+
+ if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_secrets)
+ NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_secrets (self, setting_name, hints, request_new, context);
+ else {
+ error = g_error_new (0, 0, "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+/**************************************************************/
+
+/**
+ * nm_exported_connection_new:
+ * @bus: a valid and connected D-Bus connection
+ * @scope: the Connection scope (either user or system)
+ * @path: the D-Bus path of the connection as exported by the settings service
+ * indicated by @scope
+ *
+ * Creates a new object representing the remote connection.
+ *
+ * Returns: the new exported connection object on success, or %NULL on failure
+ **/
+NMExportedConnection *
+nm_exported_connection_new (DBusGConnection *bus,
+ NMConnectionScope scope)
+{
+ g_return_val_if_fail (bus != NULL, NULL);
+ g_return_val_if_fail (scope != NM_CONNECTION_SCOPE_UNKNOWN, NULL);
+
+ return (NMExportedConnection *) g_object_new (NM_TYPE_EXPORTED_CONNECTION,
+ NM_EXPORTED_CONNECTION_BUS, bus,
+ NM_CONNECTION_SCOPE, scope,
+ NULL);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMExportedConnectionPrivate *priv;
+
+ object = G_OBJECT_CLASS (nm_exported_connection_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
+ g_assert (priv->bus);
+
+ return object;
+}
+
+static void
+nm_exported_connection_init (NMExportedConnection *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMExportedConnectionPrivate *priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ /* Construct only */
+ priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMExportedConnectionPrivate *priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ g_value_set_boxed (value, priv->bus);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMExportedConnectionPrivate *priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+ dbus_g_connection_unref (priv->bus);
+ }
+
+ G_OBJECT_CLASS (nm_exported_connection_parent_class)->dispose (object);
+}
+
+static void
+nm_exported_connection_class_init (NMExportedConnectionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMExportedConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->dispose = dispose;
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ class->get_settings = real_get_settings;
+
+ /**
+ * NMExportedConnection:bus:
+ *
+ * The %DBusGConnection which this object is exported on
+ **/
+ g_object_class_install_property (object_class, PROP_BUS,
+ g_param_spec_boxed (NM_EXPORTED_CONNECTION_BUS,
+ "Bus",
+ "Bus",
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
+ &dbus_glib_nm_exported_connection_object_info);
+}
diff --git a/libnm-glib/nm-exported-connection.h b/libnm-glib/nm-exported-connection.h
new file mode 100644
index 0000000000..79c7f80c39
--- /dev/null
+++ b/libnm-glib/nm-exported-connection.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * 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 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_EXPORTED_CONNECTION_H
+#define NM_EXPORTED_CONNECTION_H
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_EXPORTED_CONNECTION (nm_exported_connection_get_type ())
+#define NM_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnection))
+#define NM_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass))
+#define NM_IS_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION))
+#define NM_IS_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION))
+#define NM_EXPORTED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass))
+
+#define NM_EXPORTED_CONNECTION_BUS "bus"
+
+typedef struct {
+ NMConnection parent;
+} NMExportedConnection;
+
+typedef struct {
+ NMConnectionClass parent;
+
+ GHashTable * (*get_settings) (NMExportedConnection *self,
+ GError **error);
+
+ void (*update) (NMExportedConnection *self,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context);
+
+ void (*delete) (NMExportedConnection *self,
+ DBusGMethodInvocation *context);
+
+ void (*get_secrets) (NMExportedConnection *self,
+ const gchar *setting_name,
+ const gchar **hints,
+ gboolean request_new,
+ DBusGMethodInvocation *context);
+} NMExportedConnectionClass;
+
+GType nm_exported_connection_get_type (void);
+
+NMExportedConnection *nm_exported_connection_new (DBusGConnection *bus,
+ NMConnectionScope scope);
+
+void nm_exported_connection_export (NMExportedConnection *self);
+
+G_END_DECLS
+
+#endif /* NM_EXPORTED_CONNECTION_H */
diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c
new file mode 100644
index 0000000000..76fdcf0244
--- /dev/null
+++ b/libnm-glib/nm-remote-connection.c
@@ -0,0 +1,419 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#include
+
+#include
+#include
+#include
+#include "nm-remote-connection.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-exported-connection-bindings.h"
+#include "nm-settings-connection-interface.h"
+
+#define NM_REMOTE_CONNECTION_BUS "bus"
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *klass);
+
+G_DEFINE_TYPE_EXTENDED (NMRemoteConnection, nm_remote_connection, NM_TYPE_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, settings_connection_interface_init))
+
+enum {
+ PROP_0,
+ PROP_BUS,
+
+ LAST_PROP
+};
+
+
+typedef struct {
+ NMRemoteConnection *self;
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
+ GFunc callback;
+ gpointer user_data;
+} RemoteCall;
+
+typedef struct {
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+ DBusGProxy *secrets_proxy;
+ GSList *calls;
+
+ gboolean disposed;
+} NMRemoteConnectionPrivate;
+
+#define NM_REMOTE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionPrivate))
+
+/****************************************************************/
+
+static void
+remote_call_complete (NMRemoteConnection *self, RemoteCall *call)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
+
+ priv->calls = g_slist_remove (priv->calls, call);
+ /* Don't need to cancel it since this function should only be called from
+ * the dispose handler (where the proxy will be destroyed immediately after)
+ * or from the call's completion callback.
+ */
+ memset (call, 0, sizeof (RemoteCall));
+ g_free (call);
+}
+
+static void
+update_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
+{
+ RemoteCall *call = user_data;
+ NMSettingsConnectionInterfaceUpdateFunc func = (NMSettingsConnectionInterfaceUpdateFunc) call->callback;
+
+ (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), error, call->user_data);
+ remote_call_complete (call->self, call);
+}
+
+static gboolean
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
+{
+ NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection);
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
+ GHashTable *settings = NULL;
+ RemoteCall *call;
+
+ call = g_malloc0 (sizeof (RemoteCall));
+ call->self = self;
+ call->callback = (GFunc) callback;
+ call->user_data = user_data;
+ call->proxy = priv->proxy;
+
+ settings = nm_connection_to_hash (NM_CONNECTION (self));
+
+ call->call = org_freedesktop_NetworkManagerSettings_Connection_update_async (priv->proxy,
+ settings,
+ update_cb,
+ call);
+ g_assert (call->call);
+ priv->calls = g_slist_append (priv->calls, call);
+
+ g_hash_table_destroy (settings);
+
+ return TRUE;
+}
+
+static void
+delete_cb (DBusGProxy *proxy, GError *error, gpointer user_data)
+{
+ RemoteCall *call = user_data;
+ NMSettingsConnectionInterfaceDeleteFunc func = (NMSettingsConnectionInterfaceDeleteFunc) call->callback;
+
+ (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), error, call->user_data);
+ remote_call_complete (call->self, call);
+}
+
+static gboolean
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
+{
+ NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection);
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
+ RemoteCall *call;
+
+ call = g_malloc0 (sizeof (RemoteCall));
+ call->self = self;
+ call->callback = (GFunc) callback;
+ call->user_data = user_data;
+ call->proxy = priv->proxy;
+
+ call->call = org_freedesktop_NetworkManagerSettings_Connection_delete_async (priv->proxy,
+ delete_cb,
+ call);
+ g_assert (call->call);
+ priv->calls = g_slist_append (priv->calls, call);
+
+ return TRUE;
+}
+
+static void
+get_secrets_cb (DBusGProxy *proxy, GHashTable *secrets, GError *error, gpointer user_data)
+{
+ RemoteCall *call = user_data;
+ NMSettingsConnectionInterfaceGetSecretsFunc func = (NMSettingsConnectionInterfaceGetSecretsFunc) call->callback;
+
+ (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), secrets, error, call->user_data);
+ remote_call_complete (call->self, call);
+}
+
+static gboolean
+get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data)
+{
+ NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection);
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
+ RemoteCall *call;
+
+ call = g_malloc0 (sizeof (RemoteCall));
+ call->self = self;
+ call->callback = (GFunc) callback;
+ call->user_data = user_data;
+ call->proxy = priv->secrets_proxy;
+
+ call->call = org_freedesktop_NetworkManagerSettings_Connection_Secrets_get_secrets_async (priv->proxy,
+ setting_name,
+ hints,
+ request_new,
+ get_secrets_cb,
+ call);
+ g_assert (call->call);
+ priv->calls = g_slist_append (priv->calls, call);
+
+ return TRUE;
+}
+
+/****************************************************************/
+
+static gboolean
+replace_settings (NMRemoteConnection *self, GHashTable *new_settings)
+{
+ GError *error = NULL;
+
+ if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) {
+ g_warning ("%s: error updating %s connection %s settings: (%d) %s",
+ __func__,
+ (nm_connection_get_scope (NM_CONNECTION (self)) == NM_CONNECTION_SCOPE_USER) ? "user" : "system",
+ nm_connection_get_path (NM_CONNECTION (self)),
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return FALSE;
+ }
+
+ /* Emit update irregardless to let listeners figure out what to do with
+ * the connection; whether to delete / ignore it or not.
+ */
+ nm_settings_connection_interface_emit_updated (NM_SETTINGS_CONNECTION_INTERFACE (self));
+ return TRUE;
+}
+
+static void
+get_settings_cb (DBusGProxy *proxy,
+ GHashTable *new_settings,
+ GError *error,
+ gpointer user_data)
+{
+ NMRemoteConnection *self = user_data;
+
+ if (error) {
+ g_warning ("%s: error getting %s connection %s settings: (%d) %s",
+ __func__,
+ (nm_connection_get_scope (NM_CONNECTION (self)) == NM_CONNECTION_SCOPE_USER) ? "user" : "system",
+ nm_connection_get_path (NM_CONNECTION (self)),
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ g_error_free (error);
+ } else {
+ replace_settings (self, new_settings);
+ g_hash_table_destroy (new_settings);
+ }
+}
+
+static void
+updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_data)
+{
+ replace_settings (NM_REMOTE_CONNECTION (user_data), settings);
+}
+
+static void
+removed_cb (DBusGProxy *proxy, gpointer user_data)
+{
+ g_signal_emit_by_name (G_OBJECT (user_data), "removed");
+}
+
+/****************************************************************/
+
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *klass)
+{
+ /* interface implementation */
+ klass->update = update;
+ klass->delete = do_delete;
+ klass->get_secrets = get_secrets;
+}
+
+/**
+ * nm_remote_connection_new:
+ * @bus: a valid and connected D-Bus connection
+ * @scope: the Connection scope (either user or system)
+ * @path: the D-Bus path of the connection as exported by the settings service
+ * indicated by @scope
+ *
+ * Creates a new object representing the remote connection.
+ *
+ * Returns: the new remote connection object on success, or %NULL on failure
+ **/
+NMRemoteConnection *
+nm_remote_connection_new (DBusGConnection *bus,
+ NMConnectionScope scope,
+ const char *path)
+{
+ g_return_val_if_fail (bus != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ return (NMRemoteConnection *) g_object_new (NM_TYPE_REMOTE_CONNECTION,
+ NM_REMOTE_CONNECTION_BUS, bus,
+ NM_CONNECTION_SCOPE, scope,
+ NM_CONNECTION_PATH, path,
+ NULL);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMRemoteConnectionPrivate *priv;
+ const char *service = NM_DBUS_SERVICE_USER_SETTINGS;
+
+ object = G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
+ g_assert (priv->bus);
+ g_assert (nm_connection_get_path (NM_CONNECTION (object)));
+
+ if (nm_connection_get_scope (NM_CONNECTION (object)) == NM_CONNECTION_SCOPE_SYSTEM)
+ service = NM_DBUS_SERVICE_SYSTEM_SETTINGS;
+
+ priv->proxy = dbus_g_proxy_new_for_name (priv->bus,
+ service,
+ nm_connection_get_path (NM_CONNECTION (object)),
+ NM_DBUS_IFACE_SETTINGS_CONNECTION);
+ g_assert (priv->proxy);
+
+ priv->secrets_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ service,
+ nm_connection_get_path (NM_CONNECTION (object)),
+ NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS);
+ g_assert (priv->secrets_proxy);
+
+ dbus_g_proxy_add_signal (priv->proxy, "Updated", DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "Updated", G_CALLBACK (updated_cb), object, NULL);
+
+ dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), object, NULL);
+
+ org_freedesktop_NetworkManagerSettings_Connection_get_settings_async (priv->proxy,
+ get_settings_cb,
+ object);
+ return object;
+}
+
+static void
+nm_remote_connection_init (NMRemoteConnection *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ /* Construct only */
+ priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMRemoteConnection *self = NM_REMOTE_CONNECTION (object);
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ g_value_set_boxed (value, priv->bus);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMRemoteConnection *self = NM_REMOTE_CONNECTION (object);
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+
+ while (g_slist_length (priv->calls))
+ remote_call_complete (self, priv->calls->data);
+
+ g_object_unref (priv->proxy);
+ g_object_unref (priv->secrets_proxy);
+ dbus_g_connection_unref (priv->bus);
+ }
+
+ G_OBJECT_CLASS (nm_remote_connection_parent_class)->dispose (object);
+}
+
+static void
+nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (remote_class);
+
+ g_type_class_add_private (object_class, sizeof (NMRemoteConnectionPrivate));
+
+ /* virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->constructor = constructor;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_BUS,
+ g_param_spec_boxed (NM_REMOTE_CONNECTION_BUS,
+ "DBusGConnection",
+ "DBusGConnection",
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h
new file mode 100644
index 0000000000..1210684d05
--- /dev/null
+++ b/libnm-glib/nm-remote-connection.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#ifndef __NM_REMOTE_CONNECTION_H__
+#define __NM_REMOTE_CONNECTION_H__
+
+#include
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_REMOTE_CONNECTION (nm_remote_connection_get_type ())
+#define NM_REMOTE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnection))
+#define NM_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass))
+#define NM_IS_REMOTE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_CONNECTION))
+#define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_CONNECTION))
+#define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass))
+
+typedef struct {
+ NMConnection parent;
+} NMRemoteConnection;
+
+typedef struct {
+ NMConnectionClass parent_class;
+} NMRemoteConnectionClass;
+
+GType nm_remote_connection_get_type (void);
+
+NMRemoteConnection *nm_remote_connection_new (DBusGConnection *dbus_connection,
+ NMConnectionScope scope,
+ const char *path);
+G_END_DECLS
+
+#endif /* __NM_REMOTE_CONNECTION__ */
+
diff --git a/libnm-glib/nm-remote-settings-system.c b/libnm-glib/nm-remote-settings-system.c
new file mode 100644
index 0000000000..9dcca659e0
--- /dev/null
+++ b/libnm-glib/nm-remote-settings-system.c
@@ -0,0 +1,259 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#include
+#include
+#include
+
+#include "nm-marshal.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-remote-settings-system.h"
+#include "nm-settings-system-bindings.h"
+#include "nm-settings-system-interface.h"
+
+static void settings_system_interface_init (NMSettingsSystemInterface *klass);
+
+G_DEFINE_TYPE_EXTENDED (NMRemoteSettingsSystem, nm_remote_settings_system, NM_TYPE_REMOTE_SETTINGS, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, settings_system_interface_init))
+
+#define NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemPrivate))
+
+typedef struct {
+ DBusGProxy *proxy;
+ DBusGProxy *props_proxy;
+
+ char *hostname;
+ gboolean can_modify;
+
+ gboolean disposed;
+} NMRemoteSettingsSystemPrivate;
+
+static void
+properties_changed_cb (DBusGProxy *proxy,
+ GHashTable *properties,
+ gpointer user_data)
+{
+ NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (user_data);
+ NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer key, tmp;
+
+ g_hash_table_iter_init (&iter, properties);
+ while (g_hash_table_iter_next (&iter, &key, &tmp)) {
+ GValue *value = tmp;
+
+ if (!strcmp ((const char *) key, "Hostname")) {
+ g_free (priv->hostname);
+ priv->hostname = g_value_dup_string (value);
+ g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
+ }
+
+ if (!strcmp ((const char *) key, "CanModify")) {
+ priv->can_modify = g_value_get_boolean (value);
+ g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY);
+ }
+ }
+}
+
+static void
+get_all_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (user_data);
+ GHashTable *props = NULL;
+ GError *error = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: couldn't retrieve system settings properties: (%d) %s.",
+ __func__,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ properties_changed_cb (NULL, props, self);
+ g_hash_table_destroy (props);
+}
+
+static gboolean
+save_hostname (NMSettingsSystemInterface *settings,
+ const char *hostname,
+ NMSettingsSystemSaveHostnameFunc callback,
+ gpointer user_data)
+{
+ return FALSE;
+}
+
+/****************************************************************/
+
+static void
+settings_system_interface_init (NMSettingsSystemInterface *klass)
+{
+ /* interface implementation */
+ klass->save_hostname = save_hostname;
+}
+
+/**
+ * nm_remote_settings_system_new:
+ * @bus: a valid and connected D-Bus connection
+ *
+ * Creates a new object representing the remote system settings service.
+ *
+ * Returns: the new remote system settings object on success, or %NULL on failure
+ **/
+NMRemoteSettingsSystem *
+nm_remote_settings_system_new (DBusGConnection *bus)
+{
+ g_return_val_if_fail (bus != NULL, NULL);
+
+ return (NMRemoteSettingsSystem *) g_object_new (NM_TYPE_REMOTE_SETTINGS_SYSTEM,
+ NM_REMOTE_SETTINGS_BUS, bus,
+ NM_REMOTE_SETTINGS_SCOPE, NM_CONNECTION_SCOPE_SYSTEM,
+ NULL);
+}
+
+static void
+nm_remote_settings_system_init (NMRemoteSettingsSystem *self)
+{
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMRemoteSettingsSystemPrivate *priv;
+ DBusGConnection *bus = NULL;
+
+ object = G_OBJECT_CLASS (nm_remote_settings_system_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object);
+
+ g_object_get (G_OBJECT (object), NM_REMOTE_SETTINGS_BUS, &bus, NULL);
+ g_assert (bus);
+
+ /* D-Bus properties proxy */
+ priv->props_proxy = dbus_g_proxy_new_for_name (bus,
+ NM_DBUS_SERVICE_SYSTEM_SETTINGS,
+ NM_DBUS_PATH_SETTINGS,
+ "org.freedesktop.DBus.Properties");
+ g_assert (priv->props_proxy);
+
+ /* System settings proxy */
+ priv->proxy = dbus_g_proxy_new_for_name (bus,
+ NM_DBUS_SERVICE_SYSTEM_SETTINGS,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS_SYSTEM);
+ g_assert (priv->proxy);
+
+ dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE,
+ DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->proxy, "PropertiesChanged",
+ DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "PropertiesChanged",
+ G_CALLBACK (properties_changed_cb),
+ object,
+ NULL);
+
+ /* Get properties */
+ dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
+ get_all_cb,
+ object,
+ NULL,
+ G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_SYSTEM,
+ G_TYPE_INVALID);
+
+ dbus_g_connection_unref (bus);
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object);
+
+ if (priv->disposed)
+ return;
+
+ priv->disposed = TRUE;
+
+ g_free (priv->hostname);
+
+ g_object_unref (priv->props_proxy);
+ g_object_unref (priv->proxy);
+
+ G_OBJECT_CLASS (nm_remote_settings_system_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME:
+ g_value_set_string (value, priv->hostname);
+ break;
+ case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY:
+ g_value_set_boolean (value, priv->can_modify);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_remote_settings_system_class_init (NMRemoteSettingsSystemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (NMRemoteSettingsSystemPrivate));
+
+ /* Virtual methods */
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_override_property (object_class,
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME,
+ NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
+
+ g_object_class_override_property (object_class,
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY,
+ NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY);
+}
+
diff --git a/libnm-glib/nm-remote-settings-system.h b/libnm-glib/nm-remote-settings-system.h
new file mode 100644
index 0000000000..09d76dfee7
--- /dev/null
+++ b/libnm-glib/nm-remote-settings-system.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_REMOTE_SETTINGS_SYSTEM_H
+#define NM_REMOTE_SETTINGS_SYSTEM_H
+
+#include
+#include
+
+#include "nm-remote-settings.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_REMOTE_SETTINGS_SYSTEM (nm_remote_settings_system_get_type ())
+#define NM_REMOTE_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystem))
+#define NM_REMOTE_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemClass))
+#define NM_IS_REMOTE_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM))
+#define NM_IS_REMOTE_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM))
+#define NM_REMOTE_SETTINGS_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemClass))
+
+typedef struct {
+ NMRemoteSettings parent;
+} NMRemoteSettingsSystem;
+
+typedef struct {
+ NMRemoteSettingsClass parent;
+} NMRemoteSettingsSystemClass;
+
+GType nm_remote_settings_system_get_type (void);
+
+NMRemoteSettingsSystem *nm_remote_settings_system_new (DBusGConnection *bus);
+
+G_END_DECLS
+
+#endif /* NM_REMOTE_SETTINGS_SYSTEM_H */
diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c
new file mode 100644
index 0000000000..6a261ace99
--- /dev/null
+++ b/libnm-glib/nm-remote-settings.c
@@ -0,0 +1,425 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#include
+#include
+#include
+
+#include "nm-marshal.h"
+#include "nm-remote-settings.h"
+#include "nm-settings-bindings.h"
+#include "nm-settings-interface.h"
+
+static void settings_interface_init (NMSettingsInterface *class);
+
+G_DEFINE_TYPE_EXTENDED (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init))
+
+#define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate))
+
+typedef struct {
+ DBusGConnection *bus;
+ NMConnectionScope scope;
+
+ DBusGProxy *proxy;
+ GHashTable *connections;
+
+ DBusGProxy *dbus_proxy;
+
+ guint fetch_id;
+
+ gboolean disposed;
+} NMRemoteSettingsPrivate;
+
+enum {
+ PROP_0,
+ PROP_BUS,
+ PROP_SCOPE,
+
+ LAST_PROP
+};
+
+static NMSettingsConnectionInterface *
+get_connection_by_path (NMSettingsInterface *settings, const char *path)
+{
+ return g_hash_table_lookup (NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->connections, path);
+}
+
+static void
+connection_removed_cb (NMRemoteConnection *remote, gpointer user_data)
+{
+ g_hash_table_remove (NM_REMOTE_SETTINGS_GET_PRIVATE (user_data)->connections,
+ nm_connection_get_path (NM_CONNECTION (remote)));
+}
+
+static void
+new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+ NMRemoteConnection *connection;
+
+ connection = nm_remote_connection_new (priv->bus, priv->scope, path);
+ if (connection) {
+ g_signal_connect (connection, "removed",
+ G_CALLBACK (connection_removed_cb),
+ self);
+
+ g_hash_table_insert (priv->connections, g_strdup (path), connection);
+ g_signal_emit_by_name (self, "new-connection", connection);
+ }
+}
+
+static void
+fetch_connections_done (DBusGProxy *proxy,
+ GPtrArray *connections,
+ GError *error,
+ gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+ int i;
+
+ if (error) {
+ g_warning ("%s: error fetching %s connections: (%d) %s.",
+ __func__,
+ priv->scope == NM_CONNECTION_SCOPE_USER ? "user" : "system",
+ error->code,
+ error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ for (i = 0; connections && (i < connections->len); i++) {
+ char *path = g_ptr_array_index (connections, i);
+
+ new_connection_cb (proxy, path, user_data);
+ g_free (path);
+ }
+ g_ptr_array_free (connections, TRUE);
+}
+
+static gboolean
+fetch_connections (gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+
+ priv->fetch_id = 0;
+
+ org_freedesktop_NetworkManagerSettings_list_connections_async (priv->proxy,
+ fetch_connections_done,
+ self);
+ return FALSE;
+}
+
+static GSList *
+list_connections (NMSettingsInterface *settings)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
+ GSList *list = NULL;
+ GHashTableIter iter;
+ gpointer value;
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value));
+
+ return list;
+}
+
+typedef struct {
+ NMSettingsInterface *self;
+ NMSettingsAddConnectionFunc callback;
+ gpointer callback_data;
+} AddConnectionInfo;
+
+static void
+add_connection_done (DBusGProxy *proxy,
+ GError *error,
+ gpointer user_data)
+{
+ AddConnectionInfo *info = user_data;
+
+ info->callback (info->self, error, info->callback_data);
+ g_free (info);
+}
+
+static gboolean
+add_connection (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (settings);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+ AddConnectionInfo *info;
+ GHashTable *new_settings;
+
+ info = g_malloc0 (sizeof (AddConnectionInfo));
+ info->self = settings;
+ info->callback = callback;
+ info->callback_data = user_data;
+
+ new_settings = nm_connection_to_hash (NM_CONNECTION (connection));
+ org_freedesktop_NetworkManagerSettings_add_connection_async (priv->proxy,
+ new_settings,
+ add_connection_done,
+ info);
+ g_hash_table_destroy (new_settings);
+ return TRUE;
+}
+
+static gboolean
+remove_connections (gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer value;
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, NULL, &value))
+ g_signal_emit_by_name (NM_REMOTE_CONNECTION (value), "removed");
+
+ g_hash_table_remove_all (priv->connections);
+ return FALSE;
+}
+
+static void
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
+{
+ NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+ const char *sname = NM_DBUS_SERVICE_USER_SETTINGS;
+
+ if (priv->scope == NM_CONNECTION_SCOPE_SYSTEM)
+ sname = NM_DBUS_SERVICE_SYSTEM_SETTINGS;
+
+ if (!strcmp (name, sname)) {
+ if (priv->fetch_id)
+ g_source_remove (priv->fetch_id);
+
+ if (new_owner && strlen (new_owner) > 0)
+ priv->fetch_id = g_idle_add (fetch_connections, self);
+ else
+ priv->fetch_id = g_idle_add (remove_connections, self);
+ }
+}
+
+/****************************************************************/
+
+static void
+settings_interface_init (NMSettingsInterface *iface)
+{
+ /* interface implementation */
+ iface->list_connections = list_connections;
+ iface->get_connection_by_path = get_connection_by_path;
+ iface->add_connection = add_connection;
+}
+
+/**
+ * nm_remote_settings_new:
+ * @bus: a valid and connected D-Bus connection
+ * @scope: the settings service scope (either user or system)
+ *
+ * Creates a new object representing the remote settings service.
+ *
+ * Returns: the new remote settings object on success, or %NULL on failure
+ **/
+NMRemoteSettings *
+nm_remote_settings_new (DBusGConnection *bus, NMConnectionScope scope)
+{
+ g_return_val_if_fail (bus != NULL, NULL);
+ g_return_val_if_fail (scope != NM_CONNECTION_SCOPE_UNKNOWN, NULL);
+
+ return (NMRemoteSettings *) g_object_new (NM_TYPE_REMOTE_SETTINGS,
+ NM_REMOTE_SETTINGS_BUS, bus,
+ NM_REMOTE_SETTINGS_SCOPE, scope,
+ NULL);
+}
+
+static void
+nm_remote_settings_init (NMRemoteSettings *self)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+
+ priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMRemoteSettingsPrivate *priv;
+ const char *service = NM_DBUS_SERVICE_USER_SETTINGS;
+
+ object = G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
+
+ /* D-Bus proxy for clearing connections on NameOwnerChanged */
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+ g_assert (priv->dbus_proxy);
+
+ dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->dbus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed),
+ object, NULL);
+
+ /* Settings service proxy */
+ if (priv->scope == NM_CONNECTION_SCOPE_SYSTEM)
+ service = NM_DBUS_SERVICE_SYSTEM_SETTINGS;
+
+ priv->proxy = dbus_g_proxy_new_for_name (priv->bus,
+ service,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_IFACE_SETTINGS);
+ g_assert (priv->proxy);
+
+ dbus_g_proxy_add_signal (priv->proxy, "NewConnection",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "NewConnection",
+ G_CALLBACK (new_connection_cb),
+ object,
+ NULL);
+
+ priv->fetch_id = g_idle_add (fetch_connections, object);
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
+
+ if (priv->disposed)
+ return;
+
+ priv->disposed = TRUE;
+
+ if (priv->fetch_id)
+ g_source_remove (priv->fetch_id);
+
+ if (priv->connections)
+ g_hash_table_destroy (priv->connections);
+
+ g_object_unref (priv->dbus_proxy);
+ g_object_unref (priv->proxy);
+ dbus_g_connection_unref (priv->bus);
+
+ G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ /* Construct only */
+ priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
+ break;
+ case PROP_SCOPE:
+ priv->scope = (NMConnectionScope) g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ g_value_set_boxed (value, priv->bus);
+ break;
+ case PROP_SCOPE:
+ g_value_set_uint (value, priv->scope);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_remote_settings_class_init (NMRemoteSettingsClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate));
+
+ /* Virtual methods */
+ object_class->constructor = constructor;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_BUS,
+ g_param_spec_boxed (NM_REMOTE_SETTINGS_BUS,
+ "DBusGConnection",
+ "DBusGConnection",
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_SCOPE,
+ g_param_spec_uint (NM_REMOTE_SETTINGS_SCOPE,
+ "Scope",
+ "NMConnection scope",
+ NM_CONNECTION_SCOPE_UNKNOWN,
+ NM_CONNECTION_SCOPE_USER,
+ NM_CONNECTION_SCOPE_USER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h
new file mode 100644
index 0000000000..f94aee4f2e
--- /dev/null
+++ b/libnm-glib/nm-remote-settings.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_REMOTE_SETTINGS_H
+#define NM_REMOTE_SETTINGS_H
+
+#include
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_REMOTE_SETTINGS (nm_remote_settings_get_type ())
+#define NM_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettings))
+#define NM_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass))
+#define NM_IS_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS))
+#define NM_IS_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS))
+#define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass))
+
+#define NM_REMOTE_SETTINGS_BUS "bus"
+#define NM_REMOTE_SETTINGS_SCOPE "scope"
+
+typedef struct {
+ GObject parent;
+} NMRemoteSettings;
+
+typedef struct {
+ GObjectClass parent;
+} NMRemoteSettingsClass;
+
+GType nm_remote_settings_get_type (void);
+
+NMRemoteSettings *nm_remote_settings_new (DBusGConnection *bus, NMConnectionScope scope);
+
+G_END_DECLS
+
+#endif /* NM_REMOTE_SETTINGS_H */
diff --git a/libnm-glib/nm-settings-connection-interface.c b/libnm-glib/nm-settings-connection-interface.c
new file mode 100644
index 0000000000..72859c17f7
--- /dev/null
+++ b/libnm-glib/nm-settings-connection-interface.c
@@ -0,0 +1,210 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#include "nm-settings-connection-interface.h"
+#include "nm-dbus-glib-types.h"
+
+/**
+ * nm_settings_connection_interface_update:
+ * @self: an object implementing #NMSettingsConnectionInterface
+ * @callback: a function to be called when the update completes
+ * @user_data: caller-specific data to be passed to @callback
+ *
+ * Update the connection with current settings and properties.
+ *
+ * Returns: TRUE on success, FALSE on failure
+ **/
+gboolean
+nm_settings_connection_interface_update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
+{
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE);
+ g_return_val_if_fail (callback != NULL, FALSE);
+
+ if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->update) {
+ return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->update (connection,
+ callback,
+ user_data);
+ }
+ return FALSE;
+}
+
+/**
+ * nm_settings_connection_interface_delete:
+ * @self: a objecting implementing #NMSettingsConnectionInterface
+ * @callback: a function to be called when the delete completes
+ * @user_data: caller-specific data to be passed to @callback
+ *
+ * Delete the connection.
+ *
+ * Returns: TRUE on success, FALSE on failure
+ **/
+gboolean
+nm_settings_connection_interface_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
+{
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE);
+ g_return_val_if_fail (callback != NULL, FALSE);
+
+ if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->delete) {
+ return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->delete (connection,
+ callback,
+ user_data);
+ }
+ return FALSE;
+}
+
+/**
+ * nm_settings_connection_interface_get_secrets:
+ * @self: a object implementing #NMSettingsConnectionInterface
+ * @setting_name: the #NMSetting object name to get secrets for
+ * @hints: #NMSetting key names to get secrets for (optional)
+ * @request_new: hint that new secrets (instead of cached or stored secrets)
+ * should be returned
+ * @callback: a function to be called when the update completes
+ * @user_data: caller-specific data to be passed to @callback
+ *
+ * Request the connection's secrets.
+ *
+ * Returns: TRUE on success, FALSE on failure
+ **/
+gboolean
+nm_settings_connection_interface_get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data)
+{
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE);
+ g_return_val_if_fail (callback != NULL, FALSE);
+
+ if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->get_secrets) {
+ return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->get_secrets (connection,
+ setting_name,
+ hints,
+ request_new,
+ callback,
+ user_data);
+ }
+ return FALSE;
+}
+
+void
+nm_settings_connection_interface_emit_updated (NMSettingsConnectionInterface *connection)
+{
+ if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->emit_updated)
+ NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->emit_updated (connection);
+ else {
+ NMConnection *tmp;
+ GHashTable *settings;
+
+ tmp = nm_connection_duplicate (NM_CONNECTION (connection));
+ nm_connection_clear_secrets (tmp);
+ settings = nm_connection_to_hash (tmp);
+ g_object_unref (tmp);
+
+ g_signal_emit_by_name (connection, "updated", settings);
+ g_hash_table_destroy (settings);
+ }
+}
+
+static void
+nm_settings_connection_interface_init (gpointer g_iface)
+{
+ GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
+ /* Properties */
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_string (NM_SETTINGS_CONNECTION_INTERFACE_PATH,
+ "Path",
+ "D-Bus path",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_uint (NM_SETTINGS_CONNECTION_INTERFACE_SCOPE,
+ "Scope",
+ "Connection scope (user, system)",
+ NM_CONNECTION_SCOPE_UNKNOWN,
+ NM_CONNECTION_SCOPE_USER,
+ NM_CONNECTION_SCOPE_USER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* Signals */
+ g_signal_new ("updated",
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsConnectionInterface, updated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT);
+
+ g_signal_new ("removed",
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsConnectionInterface, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ initialized = TRUE;
+}
+
+GType
+nm_settings_connection_interface_get_type (void)
+{
+ static GType itype = 0;
+
+ if (!itype) {
+ const GTypeInfo iinfo = {
+ sizeof (NMSettingsConnectionInterface), /* class_size */
+ nm_settings_connection_interface_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ itype = g_type_register_static (G_TYPE_INTERFACE,
+ "NMSettingsConnectionInterface",
+ &iinfo, 0);
+
+ g_type_interface_add_prerequisite (itype, NM_TYPE_CONNECTION);
+ }
+
+ return itype;
+}
+
diff --git a/libnm-glib/nm-settings-connection-interface.h b/libnm-glib/nm-settings-connection-interface.h
new file mode 100644
index 0000000000..6270797af0
--- /dev/null
+++ b/libnm-glib/nm-settings-connection-interface.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#ifndef __NM_SETTINGS_CONNECTION_INTERFACE_H__
+#define __NM_SETTINGS_CONNECTION_INTERFACE_H__
+
+#include
+#include
+
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SETTINGS_CONNECTION_INTERFACE (nm_settings_connection_interface_get_type ())
+#define NM_SETTINGS_CONNECTION_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE, NMSettingsConnectionInterface))
+#define NM_IS_SETTINGS_CONNECTION_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE))
+#define NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE, NMSettingsConnectionInterface))
+
+#define NM_SETTINGS_CONNECTION_INTERFACE_PATH "path"
+#define NM_SETTINGS_CONNECTION_INTERFACE_SCOPE "scope"
+
+typedef enum {
+ NM_SETTINGS_CONNECTION_INTERFACE_PROP_FIRST = 0x1000,
+
+ NM_SETTINGS_CONNECTION_INTERFACE_PROP_PATH = NM_SETTINGS_CONNECTION_INTERFACE_PROP_FIRST,
+ NM_SETTINGS_CONNECTION_INTERFACE_PROP_SCOPE
+} NMSettingsConnectionInterfaceProp;
+
+
+typedef struct _NMSettingsConnectionInterface NMSettingsConnectionInterface;
+
+typedef void (*NMSettingsConnectionInterfaceUpdateFunc) (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*NMSettingsConnectionInterfaceDeleteFunc) (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data);
+
+typedef void (*NMSettingsConnectionInterfaceGetSecretsFunc) (NMSettingsConnectionInterface *connection,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data);
+
+struct _NMSettingsConnectionInterface {
+ GTypeInterface g_iface;
+
+ /* Methods */
+ gboolean (*update) (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data);
+
+ gboolean (*delete) (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data);
+
+ gboolean (*get_secrets) (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data);
+
+ void (*emit_updated) (NMSettingsConnectionInterface *connection);
+
+ /* Signals */
+ /* 'new_settings' hash should *not* contain secrets */
+ void (*updated) (NMSettingsConnectionInterface *connection,
+ GHashTable *new_settings);
+
+ void (*removed) (NMSettingsConnectionInterface *connection);
+};
+
+GType nm_settings_connection_interface_get_type (void);
+
+gboolean nm_settings_connection_interface_update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data);
+
+gboolean nm_settings_connection_interface_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data);
+
+gboolean nm_settings_connection_interface_get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data);
+
+void nm_settings_connection_interface_emit_updated (NMSettingsConnectionInterface *connection);
+
+G_END_DECLS
+
+#endif /* __NM_SETTINGS_CONNECTION_INTERFACE_H__ */
+
diff --git a/libnm-glib/nm-settings-interface.c b/libnm-glib/nm-settings-interface.c
new file mode 100644
index 0000000000..66c63d7728
--- /dev/null
+++ b/libnm-glib/nm-settings-interface.c
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2008 Red Hat, Inc.
+ */
+
+#include "nm-settings-interface.h"
+
+
+/**
+ * nm_settings_interface_error_quark:
+ *
+ * Setting error quark.
+ *
+ * Returns: the setting error quark
+ **/
+GQuark
+nm_settings_interface_error_quark (void)
+{
+ static GQuark quark;
+
+ if (G_UNLIKELY (!quark))
+ quark = g_quark_from_static_string ("nm-settings-interface-error-quark");
+ return quark;
+}
+
+/* This should really be standard. */
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_settings_interface_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* The connection was invalid. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, "InvalidConnection"),
+ /* The connection is read-only; modifications are not allowed. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"),
+ /* A bug in the settings service caused the error. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, "InternalError"),
+ /* Retrieval or request of secrets failed. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"),
+ /* The request for secrets was canceled. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"),
+ /* The request could not be completed because permission was denied. */
+ ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED, "PermissionDenied"),
+ { 0, 0, 0 },
+ };
+ etype = g_enum_register_static ("NMSettingsInterfaceError", values);
+ }
+ return etype;
+}
+
+
+/**
+ * nm_settings_list_connections:
+ * @settings: a object implementing %NMSettingsInterface
+ *
+ * Returns: all connections known to the object.
+ **/
+GSList *
+nm_settings_interface_list_connections (NMSettingsInterface *settings)
+{
+ g_return_val_if_fail (settings != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), NULL);
+
+ if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->list_connections)
+ return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->list_connections (settings);
+ return NULL;
+}
+
+/**
+ * nm_settings_get_connection_by_path:
+ * @settings: a object implementing %NMSettingsInterface
+ * @path: the D-Bus object path of the remote connection
+ *
+ * Returns the object implementing %NMSettingsConnectionInterface at @path.
+ *
+ * Returns: the remote connection object on success, or NULL if the object was
+ * not known
+ **/
+NMSettingsConnectionInterface *
+nm_settings_interface_get_connection_by_path (NMSettingsInterface *settings,
+ const char *path)
+{
+ g_return_val_if_fail (settings != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_connection_by_path)
+ return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_connection_by_path (settings, path);
+ return NULL;
+}
+
+/**
+ * nm_settings_interface_add_connection:
+ * @settings: a object implementing %NMSettingsInterface
+ * @connection: the settings to add; note that this objects settings will be
+ * added, not the object itself
+ * @callback: callback to be called when the add operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Requests that the settings service add the given settings to a new connection.
+ *
+ * Returns: TRUE if the request was successful, FALSE if it failed
+ **/
+gboolean
+nm_settings_interface_add_connection (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data)
+{
+ g_return_val_if_fail (settings != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE);
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE);
+ g_return_val_if_fail (callback != NULL, FALSE);
+
+ if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->add_connection) {
+ return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->add_connection (settings,
+ connection,
+ callback,
+ user_data);
+ }
+ return FALSE;
+}
+
+/*****************************************************************/
+
+static void
+nm_settings_interface_init (gpointer g_iface)
+{
+ GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
+ /* Signals */
+ g_signal_new (NM_SETTINGS_INTERFACE_NEW_CONNECTION,
+ iface_type,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSettingsInterface, new_connection),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ initialized = TRUE;
+}
+
+GType
+nm_settings_interface_get_type (void)
+{
+ static GType settings_interface_type = 0;
+
+ if (!settings_interface_type) {
+ const GTypeInfo settings_interface_info = {
+ sizeof (NMSettingsInterface), /* class_size */
+ nm_settings_interface_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ settings_interface_type = g_type_register_static (G_TYPE_INTERFACE,
+ "NMSettingsInterface",
+ &settings_interface_info, 0);
+
+ g_type_interface_add_prerequisite (settings_interface_type, G_TYPE_OBJECT);
+ }
+
+ return settings_interface_type;
+}
+
diff --git a/libnm-glib/nm-settings-interface.h b/libnm-glib/nm-settings-interface.h
new file mode 100644
index 0000000000..a058042f62
--- /dev/null
+++ b/libnm-glib/nm-settings-interface.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_INTERFACE_H
+#define NM_SETTINGS_INTERFACE_H
+
+#include
+
+#include "NetworkManager.h"
+#include "nm-settings-connection-interface.h"
+
+typedef enum {
+ NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION = 0,
+ NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
+ NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED,
+ NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED
+} NMSettingsInterfaceError;
+
+#define NM_SETTINGS_INTERFACE_ERROR (nm_settings_interface_error_quark ())
+GQuark nm_settings_interface_error_quark (void);
+
+#define NM_TYPE_SETTINGS_INTERFACE_ERROR (nm_settings_interface_error_get_type ())
+GType nm_settings_interface_error_get_type (void);
+
+
+#define NM_TYPE_SETTINGS_INTERFACE (nm_settings_interface_get_type ())
+#define NM_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface))
+#define NM_IS_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_INTERFACE))
+#define NM_SETTINGS_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface))
+
+#define NM_SETTINGS_INTERFACE_NEW_CONNECTION "new-connection"
+
+typedef struct _NMSettingsInterface NMSettingsInterface;
+
+typedef void (*NMSettingsAddConnectionFunc) (NMSettingsInterface *settings,
+ GError *error,
+ gpointer user_data);
+
+struct _NMSettingsInterface {
+ GTypeInterface g_iface;
+
+ /* Methods */
+ /* Returns a list of objects implementing NMSettingsConnectionInterface */
+ GSList * (*list_connections) (NMSettingsInterface *settings);
+
+ NMSettingsConnectionInterface * (*get_connection_by_path) (NMSettingsInterface *settings,
+ const char *path);
+
+ gboolean (*add_connection) (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data);
+
+ /* Signals */
+ void (*new_connection) (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection);
+};
+
+GType nm_settings_interface_get_type (void);
+
+/* Returns a list of objects implementing NMSettingsConnectionInterface */
+GSList *nm_settings_interface_list_connections (NMSettingsInterface *settings);
+
+NMSettingsConnectionInterface *nm_settings_interface_get_connection_by_path (NMSettingsInterface *settings,
+ const char *path);
+
+gboolean nm_settings_interface_add_connection (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ NMSettingsAddConnectionFunc callback,
+ gpointer user_data);
+
+
+#endif /* NM_SETTINGS_INTERFACE_H */
diff --git a/libnm-glib/nm-settings-service.c b/libnm-glib/nm-settings-service.c
new file mode 100644
index 0000000000..c8e1d4ce50
--- /dev/null
+++ b/libnm-glib/nm-settings-service.c
@@ -0,0 +1,287 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * 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 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
+ */
+
+#include
+#include
+
+#include "nm-settings-service.h"
+#include "nm-settings-interface.h"
+#include "nm-exported-connection.h"
+
+static gboolean impl_settings_list_connections (NMSettingsService *self,
+ GPtrArray **connections,
+ GError **error);
+
+static void impl_settings_add_connection (NMSettingsService *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+
+#include "nm-settings-glue.h"
+
+static void settings_interface_init (NMSettingsInterface *class);
+
+G_DEFINE_TYPE_EXTENDED (NMSettingsService, nm_settings_service, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init))
+
+#define NM_SETTINGS_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+ NM_TYPE_SETTINGS_SERVICE, \
+ NMSettingsServicePrivate))
+
+typedef struct {
+ DBusGConnection *bus;
+ NMConnectionScope scope;
+ gboolean exported;
+
+ gboolean disposed;
+} NMSettingsServicePrivate;
+
+enum {
+ PROP_0,
+ PROP_BUS,
+ PROP_SCOPE,
+
+ LAST_PROP
+};
+
+
+/**************************************************************/
+
+void
+nm_settings_service_export (NMSettingsService *self)
+{
+ NMSettingsServicePrivate *priv;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_SERVICE (self));
+
+ priv = NM_SETTINGS_SERVICE_GET_PRIVATE (self);
+
+ g_return_if_fail (priv->bus != NULL);
+
+ /* Don't allow exporting twice */
+ g_return_if_fail (priv->exported == FALSE);
+
+ dbus_g_connection_register_g_object (priv->bus,
+ NM_DBUS_PATH_SETTINGS,
+ G_OBJECT (self));
+ priv->exported = TRUE;
+}
+
+/**************************************************************/
+
+static GSList *
+list_connections (NMSettingsInterface *settings)
+{
+ /* Must always be implemented */
+ g_assert (NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections);
+ return NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections (NM_SETTINGS_SERVICE (settings));
+}
+
+static gboolean
+impl_settings_list_connections (NMSettingsService *self,
+ GPtrArray **connections,
+ GError **error)
+{
+ GSList *list = NULL, *iter;
+
+ list = list_connections (NM_SETTINGS_INTERFACE (self));
+ *connections = g_ptr_array_sized_new (g_slist_length (list) + 1);
+ for (iter = list; iter; iter = g_slist_next (iter)) {
+ g_ptr_array_add (*connections,
+ g_strdup (nm_connection_get_path (NM_CONNECTION (iter->data))));
+ }
+ g_slist_free (list);
+ return TRUE;
+}
+
+static NMSettingsConnectionInterface *
+get_connection_by_path (NMSettingsInterface *settings, const char *path)
+{
+ NMExportedConnection *connection;
+
+ /* Must always be implemented */
+ g_assert (NM_SETTINGS_SERVICE_GET_CLASS (settings)->get_connection_by_path);
+ connection = NM_SETTINGS_SERVICE_GET_CLASS (settings)->get_connection_by_path (NM_SETTINGS_SERVICE (settings), path);
+ return (NMSettingsConnectionInterface *) connection;
+}
+
+NMExportedConnection *
+nm_settings_service_get_connection_by_path (NMSettingsService *self,
+ const char *path)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_SERVICE (self), NULL);
+
+ return (NMExportedConnection *) get_connection_by_path (NM_SETTINGS_INTERFACE (self), path);
+}
+
+static void
+impl_settings_add_connection (NMSettingsService *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context)
+{
+ NMConnection *tmp;
+ GError *error = NULL;
+
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (settings, &error);
+ if (!tmp) {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+ g_object_unref (tmp);
+
+ if (NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection)
+ NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection (self, settings, context);
+ else {
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s: %s:%d add_connection() not implemented",
+ __func__, __FILE__, __LINE__);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ }
+}
+
+/**************************************************************/
+
+static void
+settings_interface_init (NMSettingsInterface *iface)
+{
+ /* interface implementation */
+ iface->list_connections = list_connections;
+ iface->get_connection_by_path = get_connection_by_path;
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+
+ object = G_OBJECT_CLASS (nm_settings_service_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (object)
+ g_assert (NM_SETTINGS_SERVICE_GET_PRIVATE (object)->scope != NM_CONNECTION_SCOPE_UNKNOWN);
+ return object;
+}
+
+static void
+nm_settings_service_init (NMSettingsService *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ /* Construct only */
+ priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
+ break;
+ case PROP_SCOPE:
+ /* Construct only */
+ priv->scope = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_BUS:
+ g_value_set_boxed (value, priv->bus);
+ break;
+ case PROP_SCOPE:
+ g_value_set_uint (value, priv->scope);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ priv->disposed = TRUE;
+ dbus_g_connection_unref (priv->bus);
+ }
+
+ G_OBJECT_CLASS (nm_settings_service_parent_class)->dispose (object);
+}
+
+static void
+nm_settings_service_class_init (NMSettingsServiceClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMSettingsServicePrivate));
+
+ /* Virtual methods */
+ object_class->dispose = dispose;
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ /**
+ * NMSettingsService:bus:
+ *
+ * The %DBusGConnection which this object is exported on
+ **/
+ g_object_class_install_property (object_class, PROP_BUS,
+ g_param_spec_boxed (NM_SETTINGS_SERVICE_BUS,
+ "Bus",
+ "Bus",
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ /**
+ * NMSettingsService:scope:
+ *
+ * The capabilities of the device.
+ **/
+ g_object_class_install_property (object_class, PROP_SCOPE,
+ g_param_spec_uint (NM_SETTINGS_SERVICE_SCOPE,
+ "Scope",
+ "Scope",
+ NM_CONNECTION_SCOPE_USER,
+ NM_CONNECTION_SCOPE_SYSTEM,
+ NM_CONNECTION_SCOPE_USER,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
+ &dbus_glib_nm_settings_object_info);
+}
diff --git a/libnm-glib/nm-settings-service.h b/libnm-glib/nm-settings-service.h
new file mode 100644
index 0000000000..2a6bb86aa2
--- /dev/null
+++ b/libnm-glib/nm-settings-service.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager system settings service
+ *
+ * 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 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_SERVICE_H
+#define NM_SETTINGS_SERVICE_H
+
+#include
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SETTINGS_SERVICE (nm_settings_service_get_type ())
+#define NM_SETTINGS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_SERVICE, NMSettingsService))
+#define NM_SETTINGS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_SERVICE, NMSettingsServiceClass))
+#define NM_IS_SETTINGS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_SERVICE))
+#define NM_IS_SETTINGS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS_SERVICE))
+#define NM_SETTINGS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_SERVICE, NMSettingsServiceClass))
+
+#define NM_SETTINGS_SERVICE_BUS "bus"
+#define NM_SETTINGS_SERVICE_SCOPE "scope"
+
+typedef struct {
+ GObject parent;
+} NMSettingsService;
+
+typedef struct {
+ GObjectClass parent;
+
+ /* Returned list must contain all NMExportedConnection objects exported
+ * by the settings service. The list (but not the NMExportedConnection
+ * objects) will be freed by caller.
+ */
+ GSList * (*list_connections) (NMSettingsService *self);
+
+ NMExportedConnection * (*get_connection_by_path) (NMSettingsService *self,
+ const char *path);
+
+ void (*add_connection) (NMSettingsService *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+} NMSettingsServiceClass;
+
+GType nm_settings_service_get_type (void);
+
+NMExportedConnection *nm_settings_service_get_connection_by_path (NMSettingsService *self,
+ const char *path);
+
+void nm_settings_service_export (NMSettingsService *self);
+
+G_END_DECLS
+
+#endif /* NM_SETTINGS_SERVICE_H */
diff --git a/libnm-glib/nm-settings-system-interface.c b/libnm-glib/nm-settings-system-interface.c
new file mode 100644
index 0000000000..c563eb17a7
--- /dev/null
+++ b/libnm-glib/nm-settings-system-interface.c
@@ -0,0 +1,114 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2008 Red Hat, Inc.
+ */
+
+#include "nm-settings-interface.h"
+#include "nm-settings-system-interface.h"
+
+
+/**
+ * nm_settings_system_interface_save_hostname:
+ * @settings: a object implementing %NMSettingsSystemInterface
+ * @hostname: the new persistent hostname to set, or NULL to clear any existing
+ * persistent hostname
+ * @callback: callback to be called when the hostname operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Requests that the machine's persistent hostname be set to the specified value
+ * or cleared.
+ *
+ * Returns: TRUE if the request was successful, FALSE if it failed
+ **/
+gboolean
+nm_settings_system_interface_save_hostname (NMSettingsSystemInterface *settings,
+ const char *hostname,
+ NMSettingsSystemSaveHostnameFunc callback,
+ gpointer user_data)
+{
+ g_return_val_if_fail (settings != NULL, FALSE);
+ g_return_val_if_fail (NM_IS_SETTINGS_SYSTEM_INTERFACE (settings), FALSE);
+ g_return_val_if_fail (hostname != NULL, FALSE);
+ g_return_val_if_fail (callback != NULL, FALSE);
+
+ if (NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->save_hostname) {
+ return NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->save_hostname (settings,
+ hostname,
+ callback,
+ user_data);
+ }
+ return FALSE;
+}
+
+static void
+nm_settings_system_interface_init (gpointer g_iface)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
+ /* Properties */
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_string (NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME,
+ "Hostname",
+ "Persistent hostname",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_object_interface_install_property
+ (g_iface,
+ g_param_spec_string (NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY,
+ "CanModify",
+ "Can modify anything (hostname, connections, etc)",
+ NULL,
+ G_PARAM_READABLE));
+
+ initialized = TRUE;
+}
+
+GType
+nm_settings_system_interface_get_type (void)
+{
+ static GType itype = 0;
+
+ if (!itype) {
+ const GTypeInfo iinfo = {
+ sizeof (NMSettingsSystemInterface), /* class_size */
+ nm_settings_system_interface_init, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL
+ };
+
+ itype = g_type_register_static (G_TYPE_INTERFACE,
+ "NMSettingsSystemInterface",
+ &iinfo, 0);
+
+ g_type_interface_add_prerequisite (itype, NM_TYPE_SETTINGS_INTERFACE);
+ }
+
+ return itype;
+}
+
diff --git a/libnm-glib/nm-settings-system-interface.h b/libnm-glib/nm-settings-system-interface.h
new file mode 100644
index 0000000000..6f535aaa6a
--- /dev/null
+++ b/libnm-glib/nm-settings-system-interface.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * 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.
+ *
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2009 Red Hat, Inc.
+ */
+
+#ifndef NM_SETTINGS_SYSTEM_INTERFACE_H
+#define NM_SETTINGS_SYSTEM_INTERFACE_H
+
+#include
+
+#include "NetworkManager.h"
+
+#define NM_TYPE_SETTINGS_SYSTEM_INTERFACE (nm_settings_system_interface_get_type ())
+#define NM_SETTINGS_SYSTEM_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE, NMSettingsSystemInterface))
+#define NM_IS_SETTINGS_SYSTEM_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE))
+#define NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE, NMSettingsSystemInterface))
+
+#define NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME "hostname"
+#define NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY "can-modify"
+
+typedef enum {
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_FIRST = 0x1000,
+
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME = NM_SETTINGS_SYSTEM_INTERFACE_PROP_FIRST,
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY
+} NMSettingsSystemInterfaceProp;
+
+
+typedef struct _NMSettingsSystemInterface NMSettingsSystemInterface;
+
+
+typedef void (*NMSettingsSystemSaveHostnameFunc) (NMSettingsSystemInterface *settings,
+ GError *error,
+ gpointer user_data);
+
+struct _NMSettingsSystemInterface {
+ GTypeInterface g_iface;
+
+ /* Methods */
+ gboolean (*save_hostname) (NMSettingsSystemInterface *settings,
+ const char *hostname,
+ NMSettingsSystemSaveHostnameFunc callback,
+ gpointer user_data);
+};
+
+GType nm_settings_system_interface_get_type (void);
+
+gboolean nm_settings_system_interface_save_hostname (NMSettingsSystemInterface *settings,
+ const char *hostname,
+ NMSettingsSystemSaveHostnameFunc callback,
+ gpointer user_data);
+
+#endif /* NM_SETTINGS_SYSTEM_INTERFACE_H */
diff --git a/libnm-glib/nm-settings.c b/libnm-glib/nm-settings.c
deleted file mode 100644
index cbe0f8875e..0000000000
--- a/libnm-glib/nm-settings.c
+++ /dev/null
@@ -1,607 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
- */
-
-#include
-#include
-#include
-#include "nm-settings.h"
-#include "nm-dbus-glib-types.h"
-
-
-#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ())
-
-/**
- * nm_settings_error_quark:
- *
- * Setting error quark.
- *
- * Returns: the setting error quark
- **/
-GQuark
-nm_settings_error_quark (void)
-{
- static GQuark quark;
-
- if (G_UNLIKELY (!quark))
- quark = g_quark_from_static_string ("nm-settings-error-quark");
- return quark;
-}
-
-/* This should really be standard. */
-#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
-
-static GType
-nm_settings_error_get_type (void)
-{
- static GType etype = 0;
-
- if (etype == 0) {
- static const GEnumValue values[] = {
- /* The connection was invalid. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"),
- /* The connection is read-only; modifications are not allowed. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"),
- /* A bug in the settings service caused the error. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"),
- /* Retrieval or request of secrets failed. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"),
- /* The request for secrets was canceled. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"),
- /* The request could not be completed because permission was denied. */
- ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"),
- { 0, 0, 0 },
- };
- etype = g_enum_register_static ("NMSettingsError", values);
- }
- return etype;
-}
-
-
-/*
- * NMSettings implementation
- */
-
-static gboolean impl_settings_list_connections (NMSettings *settings, GPtrArray **connections, GError **error);
-
-#include "nm-settings-glue.h"
-
-#define SETTINGS_CLASS(o) (NM_SETTINGS_CLASS (G_OBJECT_GET_CLASS (o)))
-
-G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT)
-
-enum {
- S_NEW_CONNECTION,
-
- S_LAST_SIGNAL
-};
-
-static guint settings_signals[S_LAST_SIGNAL] = { 0 };
-
-static gboolean
-impl_settings_list_connections (NMSettings *settings, GPtrArray **connections, GError **error)
-{
- GSList *list, *iter;
-
- g_return_val_if_fail (NM_IS_SETTINGS (settings), FALSE);
-
- list = nm_settings_list_connections (settings);
-
- *connections = g_ptr_array_new ();
- for (iter = list; iter; iter = iter->next) {
- NMConnection *connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (iter->data));
-
- g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (connection)));
- }
-
- g_slist_free (list);
-
- return TRUE;
-}
-
-static void
-nm_settings_init (NMSettings *settings)
-{
-}
-
-static void
-nm_settings_finalize (GObject *object)
-{
- G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object);
-}
-
-static void
-nm_settings_class_init (NMSettingsClass *settings_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (settings_class);
-
- /* virtual methods */
- object_class->finalize = nm_settings_finalize;
-
- settings_class->list_connections = NULL;
-
- /* signals */
-
- /**
- * NMSettings::new-connection:
- * @setting: the setting that received the signal
- * @connection: the new #NMExportedConnection
- *
- * Notifies that a new exported connection is added.
- **/
- settings_signals[S_NEW_CONNECTION] =
- g_signal_new ("new-connection",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSettingsClass, new_connection),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
-
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class),
- &dbus_glib_nm_settings_object_info);
-
- dbus_g_error_domain_register (NM_SETTINGS_ERROR, NULL, NM_TYPE_SETTINGS_ERROR);
-}
-
-/**
- * nm_settings_list_connections:
- * @settings:
- *
- * Lists all the available connections.
- *
- * Returns: the #GSList containing #NMExportedConnections
- **/
-GSList *
-nm_settings_list_connections (NMSettings *settings)
-{
- GSList *list = NULL;
-
- g_return_val_if_fail (NM_IS_SETTINGS (settings), NULL);
-
- if (SETTINGS_CLASS (settings)->list_connections)
- list = SETTINGS_CLASS (settings)->list_connections (settings);
- else
- g_warning ("Missing implementation for Settings::list_connections.");
-
- return list;
-}
-
-void
-nm_settings_signal_new_connection (NMSettings *settings, NMExportedConnection *connection)
-{
- g_return_if_fail (NM_IS_SETTINGS (settings));
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
-
- g_signal_emit (settings, settings_signals[S_NEW_CONNECTION], 0, connection);
-}
-
-/*
- * NMExportedConnection implementation
- */
-
-static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection,
- GHashTable **settings,
- GError **error);
-
-static gboolean impl_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings,
- DBusGMethodInvocation *context);
-
-static gboolean impl_exported_connection_delete (NMExportedConnection *connection,
- DBusGMethodInvocation *context);
-
-static void impl_exported_connection_get_secrets (NMExportedConnection *connection,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context);
-
-#include "nm-exported-connection-glue.h"
-
-#define EXPORTED_CONNECTION_CLASS(o) (NM_EXPORTED_CONNECTION_CLASS (G_OBJECT_GET_CLASS (o)))
-
-G_DEFINE_TYPE (NMExportedConnection, nm_exported_connection, G_TYPE_OBJECT)
-
-enum {
- EC_UPDATED,
- EC_REMOVED,
-
- EC_LAST_SIGNAL
-};
-
-static guint connection_signals[EC_LAST_SIGNAL] = { 0 };
-
-enum {
- PROP_0,
- PROP_CONNECTION,
-
- LAST_PROP
-};
-
-typedef struct {
- NMConnection *wrapped;
-} NMExportedConnectionPrivate;
-
-#define NM_EXPORTED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
- NM_TYPE_EXPORTED_CONNECTION, \
- NMExportedConnectionPrivate))
-
-NMExportedConnection *
-nm_exported_connection_new (NMConnection *wrapped)
-{
- g_return_val_if_fail (NM_IS_CONNECTION (wrapped), NULL);
-
- return (NMExportedConnection *) g_object_new (NM_TYPE_EXPORTED_CONNECTION,
- NM_EXPORTED_CONNECTION_CONNECTION, wrapped,
- NULL);
-}
-
-static GHashTable *
-real_get_settings (NMExportedConnection *exported)
-{
- NMExportedConnectionPrivate *priv;
- NMConnection *no_secrets;
- GHashTable *hash;
-
- g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (exported), NULL);
-
- priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (exported);
-
- /* Secrets should *never* be returned by the GetSettings method, they
- * get returned by the GetSecrets method which can be better
- * protected against leakage of secrets to unprivileged callers.
- */
- no_secrets = nm_connection_duplicate (priv->wrapped);
- nm_connection_clear_secrets (no_secrets);
- hash = nm_connection_to_hash (no_secrets);
- g_object_unref (G_OBJECT (no_secrets));
- return hash;
-}
-
-static gboolean
-impl_exported_connection_get_settings (NMExportedConnection *connection,
- GHashTable **settings,
- GError **error)
-{
- NMExportedConnectionPrivate *priv;
-
- g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE);
-
- priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (connection);
-
- if (!EXPORTED_CONNECTION_CLASS (connection)->get_settings)
- *settings = real_get_settings (connection);
- else
- *settings = EXPORTED_CONNECTION_CLASS (connection)->get_settings (connection);
-
- return TRUE;
-}
-
-static gboolean
-impl_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings,
- DBusGMethodInvocation *context)
-{
- GError *err = NULL;
- NMConnection *wrapped;
- gboolean success = FALSE;
-
- /* Read-only connections obviously cannot be changed */
- wrapped = nm_exported_connection_get_connection (connection);
- if (wrapped) {
- NMSettingConnection *s_con;
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION);
- if (s_con && nm_setting_connection_get_read_only (s_con)) {
- g_set_error (&err, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
- "%s.%d - Read-only connections may not be modified.",
- __FILE__, __LINE__);
- }
- }
-
- if (!err) {
- /* A hack to share the DBusGMethodInvocation with the possible overriders of connection::update */
- g_object_set_data (G_OBJECT (connection), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION, context);
- success = nm_exported_connection_update (connection, new_settings, &err);
- g_object_set_data (G_OBJECT (connection), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION, NULL);
- }
-
- if (success) {
- dbus_g_method_return (context);
- } else {
- dbus_g_method_return_error (context, err);
- g_error_free (err);
- }
-
- return success;
-}
-
-static gboolean
-impl_exported_connection_delete (NMExportedConnection *connection,
- DBusGMethodInvocation *context)
-{
- GError *err = NULL;
- NMConnection *wrapped;
- gboolean success = FALSE;
-
- /* Read-only connections obviously cannot be changed */
- wrapped = nm_exported_connection_get_connection (connection);
- if (wrapped) {
- NMSettingConnection *s_con;
-
- s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION);
- if (s_con && nm_setting_connection_get_read_only (s_con)) {
- g_set_error (&err, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
- "%s.%d - Read-only connections may not be deleted.",
- __FILE__, __LINE__);
- }
- }
-
- if (!err) {
- /* A hack to share the DBusGMethodInvocation with the possible overriders of connection::delete */
- g_object_set_data (G_OBJECT (connection), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION, context);
- success = nm_exported_connection_delete (connection, &err);
- g_object_set_data (G_OBJECT (connection), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION, NULL);
- }
-
- if (success) {
- dbus_g_method_return (context);
- } else {
- dbus_g_method_return_error (context, err);
- g_error_free (err);
- }
-
- return success;
-}
-
-static void
-impl_exported_connection_get_secrets (NMExportedConnection *connection,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- if (!NM_IS_EXPORTED_CONNECTION (connection)) {
- g_set_error (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
- "%s.%d - Invalid connection in ConnectionSettings::GetSecrets.",
- __FILE__, __LINE__);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- if (!EXPORTED_CONNECTION_CLASS (connection)->service_get_secrets) {
- g_set_error (&error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
- "%s.%d - Missing implementation for ConnectionSettings::GetSecrets.",
- __FILE__, __LINE__);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- EXPORTED_CONNECTION_CLASS (connection)->service_get_secrets (connection, setting_name, hints, request_new, context);
-}
-
-static void
-nm_exported_connection_init (NMExportedConnection *connection)
-{
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- GObject *connection;
- NMExportedConnectionPrivate *priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_CONNECTION:
- if (priv->wrapped) {
- g_object_unref (priv->wrapped);
- priv->wrapped = NULL;
- }
-
- connection = g_value_dup_object (value);
- if (connection)
- priv->wrapped = NM_CONNECTION (connection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMExportedConnection *exported = NM_EXPORTED_CONNECTION (object);
-
- switch (prop_id) {
- case PROP_CONNECTION:
- g_value_set_object (value, nm_exported_connection_get_connection (exported));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_exported_connection_dispose (GObject *object)
-{
- NMExportedConnectionPrivate *priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (object);
-
- if (priv->wrapped) {
- g_object_unref (priv->wrapped);
- priv->wrapped = NULL;
- }
-
- G_OBJECT_CLASS (nm_exported_connection_parent_class)->dispose (object);
-}
-
-static void
-nm_exported_connection_class_init (NMExportedConnectionClass *exported_connection_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (exported_connection_class);
-
- g_type_class_add_private (object_class, sizeof (NMExportedConnectionPrivate));
-
- /* virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = nm_exported_connection_dispose;
-
- exported_connection_class->get_settings = real_get_settings;
-
- /* Properties */
- g_object_class_install_property
- (object_class, PROP_CONNECTION,
- g_param_spec_object (NM_EXPORTED_CONNECTION_CONNECTION,
- "Connection",
- "Wrapped connection",
- NM_TYPE_CONNECTION,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /* signals */
- connection_signals[EC_UPDATED] =
- g_signal_new ("updated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMExportedConnectionClass, updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1,
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT);
-
- connection_signals[EC_REMOVED] =
- g_signal_new ("removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMExportedConnectionClass, removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (exported_connection_class),
- &dbus_glib_nm_exported_connection_object_info);
-}
-
-NMConnection *
-nm_exported_connection_get_connection (NMExportedConnection *connection)
-{
- g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), NULL);
-
- return NM_EXPORTED_CONNECTION_GET_PRIVATE (connection)->wrapped;
-}
-
-void
-nm_exported_connection_register_object (NMExportedConnection *connection,
- NMConnectionScope scope,
- DBusGConnection *dbus_connection)
-{
- NMExportedConnectionPrivate *priv;
- static guint32 ec_counter = 0;
- char *path;
-
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
- g_return_if_fail (dbus_connection != NULL);
-
- priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (connection);
- /* Don't allow the connection to be exported twice */
- g_return_if_fail (nm_connection_get_path (priv->wrapped) == NULL);
-
- path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
- nm_connection_set_path (priv->wrapped, path);
- nm_connection_set_scope (priv->wrapped, scope);
-
- dbus_g_connection_register_g_object (dbus_connection,
- path,
- G_OBJECT (connection));
- g_free (path);
-}
-
-gboolean
-nm_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings,
- GError **err)
-{
- gboolean success = TRUE;
- GError *error = NULL;
-
- g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE);
- g_return_val_if_fail (new_settings != NULL, FALSE);
-
- if (EXPORTED_CONNECTION_CLASS (connection)->update)
- success = EXPORTED_CONNECTION_CLASS (connection)->update (connection, new_settings, err);
-
- if (success) {
- if (!nm_connection_replace_settings (NM_EXPORTED_CONNECTION_GET_PRIVATE (connection)->wrapped, new_settings, &error)) {
- g_warning ("%s: '%s' / '%s' invalid: %d",
- __func__,
- error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)",
- (error && error->message) ? error->message : "(none)",
- error ? error->code : -1);
- g_clear_error (&error);
- success = FALSE;
- } else
- nm_exported_connection_signal_updated (connection, new_settings);
- }
-
- return success;
-}
-
-gboolean
-nm_exported_connection_delete (NMExportedConnection *connection, GError **err)
-{
- gboolean success = TRUE;
-
- g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE);
-
- if (EXPORTED_CONNECTION_CLASS (connection)->do_delete)
- success = EXPORTED_CONNECTION_CLASS (connection)->do_delete (connection, err);
-
- if (success)
- nm_exported_connection_signal_removed (connection);
-
- return success;
-}
-
-void
-nm_exported_connection_signal_updated (NMExportedConnection *connection, GHashTable *settings)
-{
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
-
- g_signal_emit (connection, connection_signals[EC_UPDATED], 0, settings);
-}
-
-void
-nm_exported_connection_signal_removed (NMExportedConnection *connection)
-{
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
-
- g_signal_emit (connection, connection_signals[EC_REMOVED], 0);
-}
diff --git a/libnm-glib/nm-settings.h b/libnm-glib/nm-settings.h
deleted file mode 100644
index a4c2dec8cb..0000000000
--- a/libnm-glib/nm-settings.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*
- * libnm_glib -- Access network status & information from glib applications
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2008 Red Hat, Inc.
- */
-
-#ifndef __NM_SETTINGS_H__
-#define __NM_SETTINGS_H__
-
-#include
-#include
-
-#include
-
-G_BEGIN_DECLS
-
-typedef enum
-{
- NM_SETTINGS_ERROR_INVALID_CONNECTION = 0,
- NM_SETTINGS_ERROR_READ_ONLY_CONNECTION,
- NM_SETTINGS_ERROR_INTERNAL_ERROR,
- NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
- NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED,
- NM_SETTINGS_ERROR_PERMISSION_DENIED
-} NMSettingsError;
-
-#define NM_SETTINGS_ERROR (nm_settings_error_quark ())
-GQuark nm_settings_error_quark (void);
-
-
-#define NM_TYPE_EXPORTED_CONNECTION (nm_exported_connection_get_type ())
-#define NM_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnection))
-#define NM_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass))
-#define NM_IS_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION))
-#define NM_IS_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION))
-#define NM_EXPORTED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass))
-
-#define NM_EXPORTED_CONNECTION_CONNECTION "connection"
-
-#define NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION "nm-exported-connection-dbus-method-invocation"
-
-typedef struct {
- GObject parent;
-} NMExportedConnection;
-
-typedef struct {
- GObjectClass parent_class;
-
- /* virtual methods */
- GHashTable * (*get_settings) (NMExportedConnection *connection);
-
- /* service_get_secrets is used in a D-Bus service (like the system settings
- * service) to respond to GetSecrets requests from clients.
- */
- void (*service_get_secrets) (NMExportedConnection *connection,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context);
-
- gboolean (*update) (NMExportedConnection *connection,
- GHashTable *new_settings,
- GError **err);
-
- gboolean (*do_delete) (NMExportedConnection *connection,
- GError **err);
-
- /* signals */
- void (*updated) (NMExportedConnection *connection, GHashTable *settings);
- void (*removed) (NMExportedConnection *connection);
-} NMExportedConnectionClass;
-
-GType nm_exported_connection_get_type (void);
-
-NMExportedConnection *nm_exported_connection_new (NMConnection *wrapped);
-
-void nm_exported_connection_register_object (NMExportedConnection *connection,
- NMConnectionScope scope,
- DBusGConnection *dbus_connection);
-
-NMConnection *nm_exported_connection_get_connection (NMExportedConnection *connection);
-
-gboolean nm_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings,
- GError **err);
-
-gboolean nm_exported_connection_delete (NMExportedConnection *connection,
- GError **err);
-
-void nm_exported_connection_signal_updated (NMExportedConnection *connection,
- GHashTable *new_settings);
-
-void nm_exported_connection_signal_removed (NMExportedConnection *connection);
-
-
-
-#define NM_TYPE_SETTINGS (nm_settings_get_type ())
-#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings))
-#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass))
-#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS))
-#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS))
-#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass))
-
-typedef struct {
- GObject parent;
-} NMSettings;
-
-typedef struct {
- GObjectClass parent_class;
-
- /* virtual methods */
- /* Returns a list of NMExportedConnections. Caller should free the list. */
- GSList * (*list_connections) (NMSettings *settings);
-
- /* signals */
- void (* new_connection) (NMSettings *settings, NMExportedConnection *connection);
-} NMSettingsClass;
-
-GType nm_settings_get_type (void);
-
-GSList *nm_settings_list_connections (NMSettings *settings);
-
-void nm_settings_signal_new_connection (NMSettings *settings, NMExportedConnection *connection);
-
-
-G_END_DECLS
-
-#endif
diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list
index 6b855f9a07..cb166f5d2c 100644
--- a/marshallers/nm-marshal.list
+++ b/marshallers/nm-marshal.list
@@ -18,7 +18,6 @@ VOID:STRING,INT
VOID:STRING,UINT
VOID:OBJECT,OBJECT,ENUM
VOID:POINTER,STRING
-POINTER:POINTER
VOID:STRING,BOXED
BOOLEAN:POINTER,STRING,BOOLEAN,UINT,STRING,STRING
BOOLEAN:VOID
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 731589c40a..7e90d85547 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -49,6 +49,8 @@
#include "nm-bluez-common.h"
#include "nm-sysconfig-settings.h"
#include "nm-secrets-provider-interface.h"
+#include "nm-settings-interface.h"
+#include "nm-settings-system-interface.h"
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
#define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd"
@@ -862,18 +864,16 @@ user_query_connections (NMManager *manager)
/*******************************************************************/
static void
-system_connection_updated_cb (NMExportedConnection *exported,
+system_connection_updated_cb (NMSettingsConnectionInterface *connection,
gpointer unused,
NMManager *manager)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
const char *path;
- NMConnection *existing;
- NMConnection *connection;
+ NMSettingsConnectionInterface *existing;
GError *error = NULL;
- connection = nm_exported_connection_get_connection (exported);
- path = nm_connection_get_path (connection);
+ path = nm_connection_get_path (NM_CONNECTION (connection));
existing = g_hash_table_lookup (priv->system_connections, path);
if (!existing)
@@ -883,14 +883,14 @@ system_connection_updated_cb (NMExportedConnection *exported,
return;
}
- if (!nm_connection_verify (existing, &error)) {
+ if (!nm_connection_verify (NM_CONNECTION (existing), &error)) {
/* Updated connection invalid, remove existing connection */
nm_warning ("%s: Invalid connection: '%s' / '%s' invalid: %d",
__func__,
g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)),
error->message, error->code);
g_error_free (error);
- remove_connection (manager, existing, priv->system_connections);
+ remove_connection (manager, NM_CONNECTION (existing), priv->system_connections);
return;
}
@@ -901,37 +901,33 @@ system_connection_updated_cb (NMExportedConnection *exported,
}
static void
-system_connection_removed_cb (NMExportedConnection *exported,
+system_connection_removed_cb (NMSettingsConnectionInterface *connection,
NMManager *manager)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
const char *path;
- NMConnection *connection;
- connection = nm_exported_connection_get_connection (exported);
- path = nm_connection_get_path (connection);
+ path = nm_connection_get_path (NM_CONNECTION (connection));
connection = g_hash_table_lookup (priv->system_connections, path);
if (connection)
- remove_connection (manager, connection, priv->system_connections);
+ remove_connection (manager, NM_CONNECTION (connection), priv->system_connections);
}
static void
system_internal_new_connection (NMManager *manager,
- NMExportedConnection *exported)
+ NMSettingsConnectionInterface *connection)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- NMConnection *connection;
const char *path;
- g_return_if_fail (exported != NULL);
+ g_return_if_fail (connection != NULL);
- g_signal_connect (exported, "updated",
+ g_signal_connect (connection, "updated",
G_CALLBACK (system_connection_updated_cb), manager);
- g_signal_connect (exported, "removed",
+ g_signal_connect (connection, "removed",
G_CALLBACK (system_connection_removed_cb), manager);
- connection = nm_exported_connection_get_connection (exported);
path = nm_connection_get_path (NM_CONNECTION (connection));
g_hash_table_insert (priv->system_connections, g_strdup (path),
g_object_ref (connection));
@@ -939,10 +935,10 @@ system_internal_new_connection (NMManager *manager,
static void
system_new_connection_cb (NMSysconfigSettings *settings,
- NMExportedConnection *exported,
+ NMSettingsConnectionInterface *connection,
NMManager *manager)
{
- system_internal_new_connection (manager, exported);
+ system_internal_new_connection (manager, connection);
}
static void
@@ -951,9 +947,9 @@ system_query_connections (NMManager *manager)
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
GSList *system_connections, *iter;
- system_connections = nm_sysconfig_settings_list_connections (priv->sys_settings);
+ system_connections = nm_settings_interface_list_connections (NM_SETTINGS_INTERFACE (priv->sys_settings));
for (iter = system_connections; iter; iter = g_slist_next (iter))
- system_internal_new_connection (manager, NM_EXPORTED_CONNECTION (iter->data));
+ system_internal_new_connection (manager, NM_SETTINGS_CONNECTION_INTERFACE (iter->data));
g_slist_free (system_connections);
}
@@ -1679,43 +1675,55 @@ user_get_secrets (NMManager *self,
return info;
}
+static void
+system_get_secrets_reply_cb (NMSettingsConnectionInterface *connection,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ GetSecretsInfo *info = user_data;
+
+ nm_secrets_provider_interface_get_secrets_result (info->provider,
+ info->setting_name,
+ info->caller,
+ error ? NULL : secrets,
+ error);
+ free_get_secrets_info (info);
+}
+
static gboolean
-system_get_secrets_cb (gpointer user_data)
+system_get_secrets_idle_cb (gpointer user_data)
{
GetSecretsInfo *info = user_data;
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager);
- GHashTable *settings;
- NMSysconfigConnection *exported;
+ NMSettingsConnectionInterface *connection;
GError *error = NULL;
const char *hints[3] = { NULL, NULL, NULL };
- exported = nm_sysconfig_settings_get_connection_by_path (priv->sys_settings,
- info->connection_path);
- if (!exported) {
- g_set_error (&error, 0, 0, "%s", "unknown connection (not exported by "
- "system settings)");
+ info->idle_id = 0;
+
+ connection = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (priv->sys_settings),
+ info->connection_path);
+ if (!connection) {
+ error = g_error_new_literal (0, 0, "unknown connection (not exported by system settings)");
nm_secrets_provider_interface_get_secrets_result (info->provider,
info->setting_name,
info->caller,
NULL,
error);
- g_clear_error (&error);
+ g_error_free (error);
+ free_get_secrets_info (info);
return FALSE;
}
hints[0] = info->hint1;
hints[1] = info->hint2;
- settings = nm_sysconfig_connection_get_secrets (exported,
- info->setting_name,
- hints,
- info->request_new,
- &error);
- nm_secrets_provider_interface_get_secrets_result (info->provider,
- info->setting_name,
- info->caller,
- settings,
- NULL);
- g_hash_table_destroy (settings);
+ nm_settings_connection_interface_get_secrets (connection,
+ info->setting_name,
+ hints,
+ info->request_new,
+ system_get_secrets_reply_cb,
+ info);
return FALSE;
}
@@ -1744,9 +1752,9 @@ system_get_secrets (NMManager *self,
g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info);
info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
- system_get_secrets_cb,
+ system_get_secrets_idle_cb,
info,
- free_get_secrets_info);
+ NULL);
return info;
}
@@ -2455,7 +2463,7 @@ nm_manager_get (const char *config_file, const char *plugins, GError **error)
g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
- g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME,
+ g_signal_connect (priv->sys_settings, "notify::" NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME,
G_CALLBACK (system_hostname_changed_cb), singleton);
g_signal_connect (priv->sys_settings, "new-connection",
G_CALLBACK (system_new_connection_cb), singleton);
diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am
index e5c9313f6e..7be27ddc17 100644
--- a/src/system-settings/Makefile.am
+++ b/src/system-settings/Makefile.am
@@ -15,7 +15,6 @@ libsystem_settings_la_SOURCES = \
nm-sysconfig-settings.h \
nm-inotify-helper.c \
nm-inotify-helper.h \
- nm-polkit-helpers.c \
nm-polkit-helpers.h \
nm-system-config-error.c \
nm-system-config-error.h \
diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c
index d95c1bac86..0fbd40bd4b 100644
--- a/src/system-settings/nm-default-wired-connection.c
+++ b/src/system-settings/nm-default-wired-connection.c
@@ -24,7 +24,6 @@
#include
#include
-#include
#include
#include
#include
@@ -32,8 +31,15 @@
#include "nm-dbus-glib-types.h"
#include "nm-marshal.h"
#include "nm-default-wired-connection.h"
+#include "nm-settings-connection-interface.h"
-G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION)
+static NMSettingsConnectionInterface *parent_settings_connection_iface;
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ settings_connection_interface_init))
#define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate))
@@ -86,18 +92,13 @@ nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired)
}
static GByteArray *
-dup_wired_mac (NMExportedConnection *exported)
+dup_wired_mac (NMConnection *connection)
{
- NMConnection *wrapped;
NMSettingWired *s_wired;
const GByteArray *mac;
GByteArray *dup;
- wrapped = nm_exported_connection_get_connection (exported);
- if (!wrapped)
- return NULL;
-
- s_wired = (NMSettingWired *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_WIRED);
+ s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
if (!s_wired)
return NULL;
@@ -111,53 +112,59 @@ dup_wired_mac (NMExportedConnection *exported)
}
static gboolean
-update (NMExportedConnection *exported,
- GHashTable *new_settings,
- GError **error)
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
{
- NMDefaultWiredConnection *connection = NM_DEFAULT_WIRED_CONNECTION (exported);
- gboolean success;
+ NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
GByteArray *mac;
+ gboolean failed = FALSE;
/* Ensure object stays alive across signal emission */
- g_object_ref (exported);
+ g_object_ref (self);
/* Save a copy of the current MAC address just in case the user
* changed it when updating the connection.
*/
- mac = dup_wired_mac (exported);
+ mac = dup_wired_mac (NM_CONNECTION (self));
- /* Let NMSysconfigConnection check permissions */
- success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->update (exported, new_settings, error);
- if (success) {
- g_signal_emit_by_name (connection, "try-update", new_settings, error);
- success = *error ? FALSE : TRUE;
-
- if (success)
- g_signal_emit (connection, signals[DELETED], 0, mac);
- }
+ g_signal_emit (self, signals[TRY_UPDATE], 0, &failed);
+ if (!failed)
+ g_signal_emit (connection, signals[DELETED], 0, mac);
g_byte_array_free (mac, TRUE);
- g_object_unref (exported);
- return success;
+ g_object_unref (self);
+
+ return parent_settings_connection_iface->update (connection, callback, user_data);
}
-static gboolean
-do_delete (NMExportedConnection *exported, GError **error)
+static gboolean
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
{
- gboolean success;
+ NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection);
GByteArray *mac;
- g_object_ref (exported);
- mac = dup_wired_mac (exported);
+ g_object_ref (self);
+ mac = dup_wired_mac (NM_CONNECTION (self));
- success = NM_EXPORTED_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->do_delete (exported, error);
- if (success)
- g_signal_emit (exported, signals[DELETED], 0, mac);
+ g_signal_emit (self, signals[DELETED], 0, mac);
g_byte_array_free (mac, TRUE);
- g_object_unref (exported);
- return success;
+ g_object_unref (self);
+
+ return parent_settings_connection_iface->delete (connection, callback, user_data);
+}
+
+/****************************************************************/
+
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *iface)
+{
+ parent_settings_connection_iface = g_type_interface_peek_parent (iface);
+ iface->update = update;
+ iface->delete = do_delete;
}
static void
@@ -172,7 +179,6 @@ constructor (GType type,
{
GObject *object;
NMDefaultWiredConnectionPrivate *priv;
- NMConnection *wrapped;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
char *id, *uuid;
@@ -183,8 +189,6 @@ constructor (GType type,
priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object);
- wrapped = nm_connection_new ();
-
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
id = g_strdup_printf (_("Auto %s"), nm_device_get_iface (priv->device));
@@ -201,15 +205,12 @@ constructor (GType type,
g_free (id);
g_free (uuid);
- nm_connection_add_setting (wrapped, NM_SETTING (s_con));
+ nm_connection_add_setting (NM_CONNECTION (object), NM_SETTING (s_con));
/* Lock the connection to the specific device */
s_wired = NM_SETTING_WIRED (nm_setting_wired_new ());
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, priv->mac, NULL);
- nm_connection_add_setting (wrapped, NM_SETTING (s_wired));
-
- g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL);
- g_object_unref (wrapped);
+ nm_connection_add_setting (NM_CONNECTION (object), NM_SETTING (s_wired));
return object;
}
@@ -288,19 +289,20 @@ try_update_signal_accumulator (GSignalInvocationHint *ihint,
const GValue *handler_return,
gpointer data)
{
- gpointer new_ptr = g_value_get_pointer (handler_return);
+ if (g_value_get_boolean (handler_return)) {
+ g_value_set_boolean (return_accu, TRUE);
+ /* Stop */
+ return FALSE;
+ }
- g_value_set_pointer (return_accu, new_ptr);
-
- /* Continue if no error was returned from the handler */
- return new_ptr ? FALSE : TRUE;
+ /* Continue if handler didn't fail */
+ return TRUE;
}
static void
nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- NMExportedConnectionClass *exported_class = NM_EXPORTED_CONNECTION_CLASS (klass);
g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate));
@@ -310,9 +312,6 @@ nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass)
object_class->get_property = get_property;
object_class->finalize = finalize;
- exported_class->update = update;
- exported_class->do_delete = do_delete;
-
/* Properties */
g_object_class_install_property
(object_class, PROP_MAC,
@@ -343,16 +342,14 @@ nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass)
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
0, try_update_signal_accumulator, NULL,
- _nm_marshal_POINTER__POINTER,
- G_TYPE_POINTER, 1,
- DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT);
+ _nm_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
/* The 'deleted' signal is used to signal intentional deletions (like
* updating or user-requested deletion) rather than using the
- * NMExportedConnection superclass' 'removed' signal, since that signal
- * doesn't have the semantics we want; it gets emitted as a side-effect
- * of various operations and is meant more for D-Bus clients instead
- * of in-service uses.
+ * superclass' 'removed' signal, since that signal doesn't have the
+ * semantics we want; it gets emitted as a side-effect of various operations
+ * and is meant more for D-Bus clients instead of in-service uses.
*/
signals[DELETED] =
g_signal_new ("deleted",
diff --git a/src/system-settings/nm-default-wired-connection.h b/src/system-settings/nm-default-wired-connection.h
index 22a2276d96..de89b67567 100644
--- a/src/system-settings/nm-default-wired-connection.h
+++ b/src/system-settings/nm-default-wired-connection.h
@@ -22,7 +22,6 @@
#ifndef NM_DEFAULT_WIRED_CONNECTION_H
#define NM_DEFAULT_WIRED_CONNECTION_H
-#include
#include "nm-sysconfig-connection.h"
#include "nm-device.h"
diff --git a/src/system-settings/nm-polkit-helpers.c b/src/system-settings/nm-polkit-helpers.c
deleted file mode 100644
index 638f2a8c14..0000000000
--- a/src/system-settings/nm-polkit-helpers.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager system settings service
- *
- * 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 2008 Novell, Inc.
- * (C) Copyright 2008 Red Hat, Inc.
- */
-
-#include
-#include "nm-polkit-helpers.h"
-#include "nm-system-config-error.h"
-
-static gboolean
-pk_io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
-{
- int fd;
- PolKitContext *pk_context = (PolKitContext *) user_data;
-
- fd = g_io_channel_unix_get_fd (channel);
- polkit_context_io_func (pk_context, fd);
-
- return TRUE;
-}
-
-static int
-pk_io_add_watch (PolKitContext *pk_context, int fd)
-{
- guint id = 0;
- GIOChannel *channel;
-
- channel = g_io_channel_unix_new (fd);
- if (channel == NULL)
- goto out;
- id = g_io_add_watch (channel, G_IO_IN, pk_io_watch_have_data, pk_context);
- if (id == 0) {
- g_io_channel_unref (channel);
- goto out;
- }
- g_io_channel_unref (channel);
-
- out:
- return id;
-}
-
-static void
-pk_io_remove_watch (PolKitContext *pk_context, int watch_id)
-{
- g_source_remove (watch_id);
-}
-
-PolKitContext *
-create_polkit_context (GError **error)
-{
- static PolKitContext *global_context = NULL;
- PolKitError *pk_err = NULL;
-
- if (G_LIKELY (global_context))
- return polkit_context_ref (global_context);
-
- global_context = polkit_context_new ();
- polkit_context_set_io_watch_functions (global_context, pk_io_add_watch, pk_io_remove_watch);
- if (!polkit_context_init (global_context, &pk_err)) {
- g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "%s (%d): %s",
- pk_err ? polkit_error_get_error_name (pk_err) : "(unknown)",
- pk_err ? polkit_error_get_error_code (pk_err) : -1,
- pk_err ? polkit_error_get_error_message (pk_err) : "(unknown)");
- if (pk_err)
- polkit_error_free (pk_err);
-
- /* PK 0.6's polkit_context_init() unrefs the global_context on failure */
-#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR >= 7)
- polkit_context_unref (global_context);
-#endif
- global_context = NULL;
- }
-
- return global_context;
-}
-
-gboolean
-check_polkit_privileges (DBusGConnection *dbus_connection,
- PolKitContext *pol_ctx,
- DBusGMethodInvocation *context,
- GError **err)
-{
- DBusConnection *tmp;
- DBusError dbus_error;
- char *sender;
- gulong sender_uid = G_MAXULONG;
- PolKitCaller *pk_caller;
- PolKitAction *pk_action;
- PolKitResult pk_result;
-
- /* Always allow uid 0 */
- tmp = dbus_g_connection_get_connection (dbus_connection);
- if (!tmp) {
- g_set_error (err,
- NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Could not get D-Bus connection.");
- return FALSE;
- }
-
- sender = dbus_g_method_get_sender (context);
-
- dbus_error_init (&dbus_error);
- /* FIXME: do this async */
- sender_uid = dbus_bus_get_unix_user (tmp, sender, &dbus_error);
- if (dbus_error_is_set (&dbus_error)) {
- g_set_error (err,
- NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "Could not determine the Unix user ID of the requestor: %s: %s",
- dbus_error.name, dbus_error.message);
- dbus_error_free (&dbus_error);
- return FALSE;
- }
-
- /* PolicyKit < 1.0 is not compatible with root processes spawned outside
- * the session manager, and when asking ConsoleKit for the session of the
- * process, ConsoleKit won't be able to get XDG_SESSION_COOKIE because it
- * doesn't exist in the caller's environment for non-session-managed
- * processes. So, for PK < 1.0, ignore PolicyKit for uid 0.
- */
- if (0 == sender_uid)
- return TRUE;
-
- /* Non-root users need to auth via PolicyKit */
- dbus_error_init (&dbus_error);
- pk_caller = polkit_caller_new_from_dbus_name (dbus_g_connection_get_connection (dbus_connection),
- sender,
- &dbus_error);
- g_free (sender);
-
- if (dbus_error_is_set (&dbus_error)) {
- *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "Error getting information about caller: %s: %s",
- dbus_error.name, dbus_error.message);
- dbus_error_free (&dbus_error);
-
- if (pk_caller)
- polkit_caller_unref (pk_caller);
-
- return FALSE;
- }
-
- pk_action = polkit_action_new ();
- polkit_action_set_action_id (pk_action, NM_SYSCONFIG_POLICY_ACTION);
-
-#if (POLKIT_VERSION_MAJOR == 0) && (POLKIT_VERSION_MINOR < 7)
- pk_result = polkit_context_can_caller_do_action (pol_ctx, pk_action, pk_caller);
-#else
- pk_result = polkit_context_is_caller_authorized (pol_ctx, pk_action, pk_caller, TRUE, NULL);
-#endif
- polkit_caller_unref (pk_caller);
- polkit_action_unref (pk_action);
-
- if (pk_result != POLKIT_RESULT_YES) {
- *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
- "%s %s",
- NM_SYSCONFIG_POLICY_ACTION,
- polkit_result_to_string_representation (pk_result));
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/src/system-settings/nm-polkit-helpers.h b/src/system-settings/nm-polkit-helpers.h
index 1382648c13..af7cd7a95c 100644
--- a/src/system-settings/nm-polkit-helpers.h
+++ b/src/system-settings/nm-polkit-helpers.h
@@ -22,16 +22,8 @@
#ifndef NM_POLKIT_HELPERS_H
#define NM_POLKIT_HELPERS_H
-#include
-#include
-#include
+#include
#define NM_SYSCONFIG_POLICY_ACTION "org.freedesktop.network-manager-settings.system.modify"
-PolKitContext *create_polkit_context (GError **error);
-gboolean check_polkit_privileges (DBusGConnection *dbus_connection,
- PolKitContext *pol_ctx,
- DBusGMethodInvocation *context,
- GError **err);
-
#endif /* NM_POLKIT_HELPERS_H */
diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c
index 3ed0eda8f1..4dbef0daf5 100644
--- a/src/system-settings/nm-sysconfig-connection.c
+++ b/src/system-settings/nm-sysconfig-connection.c
@@ -16,51 +16,55 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* (C) Copyright 2008 Novell, Inc.
+ * (C) Copyright 2008 - 2009 Red Hat, Inc.
*/
#include
+#include
+
#include "nm-sysconfig-connection.h"
#include "nm-system-config-error.h"
-#include "nm-polkit-helpers.h"
#include "nm-dbus-glib-types.h"
+#include "nm-settings-connection-interface.h"
+#include "nm-settings-interface.h"
+#include "nm-polkit-helpers.h"
-G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION)
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *klass);
+
+G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ settings_connection_interface_init))
#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SYSCONFIG_CONNECTION, \
NMSysconfigConnectionPrivate))
typedef struct {
- DBusGConnection *dbus_connection;
- PolKitContext *pol_ctx;
-
- DBusGProxy *proxy;
+ DBusGConnection *bus;
+ PolkitAuthority *authority;
} NMSysconfigConnectionPrivate;
+/**************************************************************/
+
static gboolean
-update (NMExportedConnection *exported,
- GHashTable *new_settings,
- GError **err)
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
{
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported);
- DBusGMethodInvocation *context;
-
- context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION);
- g_return_val_if_fail (context != NULL, FALSE);
-
- return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err);
+ /* Default handler for subclasses */
+ callback (connection, NULL, user_data);
+ return TRUE;
}
static gboolean
-do_delete (NMExportedConnection *exported, GError **err)
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
{
- NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (exported);
- DBusGMethodInvocation *context;
-
- context = g_object_get_data (G_OBJECT (exported), NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION);
- g_return_val_if_fail (context != NULL, FALSE);
-
- return check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, context, err);
+ /* Default handler for subclasses */
+ callback (connection, NULL, user_data);
+ return TRUE;
}
static GValue *
@@ -118,25 +122,28 @@ destroy_gvalue (gpointer data)
g_slice_free (GValue, value);
}
-GHashTable *
-nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- GError **error)
+static gboolean
+get_secrets (NMSettingsConnectionInterface *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new,
+ NMSettingsConnectionInterfaceGetSecretsFunc callback,
+ gpointer user_data)
{
- NMConnection *connection;
GHashTable *settings = NULL;
GHashTable *secrets = NULL;
NMSetting *setting;
+ GError *error = NULL;
- connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (self));
- setting = nm_connection_get_setting_by_name (connection, setting_name);
+ setting = nm_connection_get_setting_by_name (NM_CONNECTION (connection), setting_name);
if (!setting) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
- "%s.%d - Connection didn't have requested setting '%s'.",
- __FILE__, __LINE__, setting_name);
- return NULL;
+ error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
+ "%s.%d - Connection didn't have requested setting '%s'.",
+ __FILE__, __LINE__, setting_name);
+ (*callback) (connection, NULL, error, user_data);
+ g_error_free (error);
+ return TRUE;
}
/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
@@ -150,166 +157,349 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self,
nm_setting_enumerate_values (setting, add_secrets, secrets);
g_hash_table_insert (settings, g_strdup (setting_name), secrets);
- return settings;
+ callback (connection, settings, NULL, user_data);
+ g_hash_table_destroy (settings);
+ return TRUE;
}
+/**************************************************************/
+
typedef struct {
NMSysconfigConnection *self;
- char *setting_name;
DBusGMethodInvocation *context;
-} GetUnixUserInfo;
+ PolkitSubject *subject;
+ GCancellable *cancellable;
-static GetUnixUserInfo *
-get_unix_user_info_new (NMSysconfigConnection *self,
- const char *setting_name,
- DBusGMethodInvocation *context)
+ /* Update */
+ NMConnection *connection;
+
+ /* Secrets */
+ char *setting_name;
+ char **hints;
+ gboolean request_new;
+} PolkitCall;
+
+static PolkitCall *
+polkit_call_new (NMSysconfigConnection *self,
+ DBusGMethodInvocation *context,
+ NMConnection *connection,
+ const char *setting_name,
+ const char **hints,
+ gboolean request_new)
{
- GetUnixUserInfo *info;
+ PolkitCall *call;
+ char *sender;
g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (setting_name != NULL, NULL);
g_return_val_if_fail (context != NULL, NULL);
- info = g_malloc0 (sizeof (GetUnixUserInfo));
- info->self = self;
- info->setting_name = g_strdup (setting_name);
- info->context = context;
- return info;
+ call = g_malloc0 (sizeof (PolkitCall));
+ call->self = self;
+ call->context = context;
+ call->cancellable = g_cancellable_new ();
+ call->connection = connection;
+ call->setting_name = g_strdup (setting_name);
+ if (hints)
+ call->hints = g_strdupv ((char **) hints);
+ call->request_new = request_new;
+
+ sender = dbus_g_method_get_sender (context);
+ call->subject = polkit_system_bus_name_new (sender);
+ g_free (sender);
+
+ return call;
}
static void
-get_unix_user_info_free (gpointer user_data)
+polkit_call_free (PolkitCall *call)
{
- GetUnixUserInfo *info = user_data;
+ if (call->connection)
+ g_object_unref (call->connection);
+ g_free (call->setting_name);
+ if (call->hints)
+ g_strfreev (call->hints);
- g_free (info->setting_name);
- g_free (info);
+ g_object_unref (call->subject);
+ g_object_unref (call->cancellable);
+ g_free (call);
}
static void
-get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+con_update_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
{
- GetUnixUserInfo *info = user_data;
- NMSysconfigConnection *self;
- NMSysconfigConnectionPrivate *priv;
+ PolkitCall *call = user_data;
+
+ if (error)
+ dbus_g_method_return_error (call->context, error);
+ else
+ dbus_g_method_return (call->context);
+
+ polkit_call_free (call);
+}
+
+static void
+pk_update_cb (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ PolkitCall *call = user_data;
+ NMSysconfigConnection *self = call->self;
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
+ PolkitAuthorizationResult *pk_result;
GError *error = NULL;
- guint32 requestor_uid = G_MAXUINT32;
- GHashTable *secrets;
+ GHashTable *settings;
- g_return_if_fail (info != NULL);
-
- self = info->self;
- priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
-
- if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_UINT, &requestor_uid, G_TYPE_INVALID))
- goto error;
-
- /* Non-root users need PolicyKit authorization */
- if (requestor_uid != 0) {
- if (!check_polkit_privileges (priv->dbus_connection, priv->pol_ctx, info->context, &error))
- goto error;
- }
-
- secrets = nm_sysconfig_connection_get_secrets (self, info->setting_name, NULL, FALSE, &error);
- if (secrets) {
- /* success; return secrets to caller */
- dbus_g_method_return (info->context, secrets);
- g_hash_table_destroy (secrets);
+ pk_result = polkit_authority_check_authorization_finish (priv->authority,
+ result,
+ &error);
+ /* Some random error happened */
+ if (error) {
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
return;
}
- if (!error) {
- /* Shouldn't happen, but... */
- g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "%s", "Could not get secrets from connection (unknown error ocurred)");
+ /* Caller didn't successfully authenticate */
+ if (!polkit_authorization_result_get_is_authorized (pk_result)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ goto out;
}
-error:
- dbus_g_method_return_error (info->context, error);
- g_clear_error (&error);
+ /* Update our settings internally so the update() call will save the new
+ * ones.
+ */
+ settings = nm_connection_to_hash (call->connection);
+ if (!nm_connection_replace_settings (NM_CONNECTION (self), settings, &error)) {
+ /* Shouldn't really happen since we've already validated the settings */
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ goto out;
+ }
+ g_hash_table_destroy (settings);
+
+ /* Caller is authenticated, now we can finally try to update */
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self),
+ con_update_cb,
+ call);
+
+out:
+ g_object_unref (pk_result);
}
static void
-service_get_secrets (NMExportedConnection *exported,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- DBusGMethodInvocation *context)
+dbus_update (NMExportedConnection *exported,
+ GHashTable *new_settings,
+ DBusGMethodInvocation *context)
{
NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- GetUnixUserInfo *info;
+ PolkitCall *call;
+ NMConnection *tmp;
GError *error = NULL;
- char *sender = NULL;
- sender = dbus_g_method_get_sender (context);
- if (!sender) {
- g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "%s", "Could not determine D-Bus requestor to authorize GetSecrets request");
- goto out;
- }
-
- if (priv->proxy)
- g_object_unref (priv->proxy);
-
- priv->proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
- if (!priv->proxy) {
- g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "%s", "Could not connect to D-Bus to authorize GetSecrets request");
- goto out;
- }
-
- info = get_unix_user_info_new (self, setting_name, context);
- if (!info) {
- g_set_error (&error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_GENERAL,
- "%s", "Not enough memory to authorize GetSecrets request");
- goto out;
- }
-
- dbus_g_proxy_begin_call_with_timeout (priv->proxy, "GetConnectionUnixUser",
- get_unix_user_cb,
- info,
- get_unix_user_info_free,
- 5000,
- G_TYPE_STRING, sender,
- G_TYPE_INVALID);
-
-out:
- if (error) {
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (new_settings, &error);
+ if (!tmp) {
+ g_assert (error);
dbus_g_method_return_error (context, error);
g_error_free (error);
+ return;
}
+
+ call = polkit_call_new (self, context, tmp, NULL, NULL, FALSE);
+ g_assert (call);
+ polkit_authority_check_authorization (priv->authority,
+ call->subject,
+ NM_SYSCONFIG_POLICY_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ call->cancellable,
+ pk_update_cb,
+ call);
}
-/* GObject */
+static void
+con_delete_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ PolkitCall *call = user_data;
+
+ if (error)
+ dbus_g_method_return_error (call->context, error);
+ else
+ dbus_g_method_return (call->context);
+
+ polkit_call_free (call);
+}
+
+static void
+pk_delete_cb (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ PolkitCall *call = user_data;
+ NMSysconfigConnection *self = call->self;
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
+ PolkitAuthorizationResult *pk_result;
+ GError *error = NULL;
+
+ pk_result = polkit_authority_check_authorization_finish (priv->authority,
+ result,
+ &error);
+ /* Some random error happened */
+ if (error) {
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ return;
+ }
+
+ /* Caller didn't successfully authenticate */
+ if (!polkit_authorization_result_get_is_authorized (pk_result)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ goto out;
+ }
+
+ /* Caller is authenticated, now we can finally try to delete */
+ nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (self),
+ con_delete_cb,
+ call);
+
+out:
+ g_object_unref (pk_result);
+}
+
+static void
+dbus_delete (NMExportedConnection *exported,
+ DBusGMethodInvocation *context)
+{
+ NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
+ PolkitCall *call;
+
+ call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE);
+ g_assert (call);
+ polkit_authority_check_authorization (priv->authority,
+ call->subject,
+ NM_SYSCONFIG_POLICY_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ call->cancellable,
+ pk_delete_cb,
+ call);
+}
+
+static void
+con_secrets_cb (NMSettingsConnectionInterface *connection,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ PolkitCall *call = user_data;
+
+ if (error)
+ dbus_g_method_return_error (call->context, error);
+ else
+ dbus_g_method_return (call->context, secrets);
+
+ polkit_call_free (call);
+}
+
+static void
+pk_secrets_cb (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ PolkitCall *call = user_data;
+ NMSysconfigConnection *self = call->self;
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
+ PolkitAuthorizationResult *pk_result;
+ GError *error = NULL;
+
+ pk_result = polkit_authority_check_authorization_finish (priv->authority,
+ result,
+ &error);
+ /* Some random error happened */
+ if (error) {
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ return;
+ }
+
+ /* Caller didn't successfully authenticate */
+ if (!polkit_authorization_result_get_is_authorized (pk_result)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ dbus_g_method_return_error (call->context, error);
+ g_error_free (error);
+ polkit_call_free (call);
+ goto out;
+ }
+
+ /* Caller is authenticated, now we can finally try to update */
+ nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (self),
+ call->setting_name,
+ (const char **) call->hints,
+ call->request_new,
+ con_secrets_cb,
+ call);
+
+out:
+ g_object_unref (pk_result);
+}
+
+static void
+dbus_get_secrets (NMExportedConnection *exported,
+ const gchar *setting_name,
+ const gchar **hints,
+ gboolean request_new,
+ DBusGMethodInvocation *context)
+{
+ NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported);
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
+ PolkitCall *call;
+
+ call = polkit_call_new (self, context, NULL, setting_name, hints, request_new);
+ g_assert (call);
+ polkit_authority_check_authorization (priv->authority,
+ call->subject,
+ NM_SYSCONFIG_POLICY_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ call->cancellable,
+ pk_secrets_cb,
+ call);
+}
+
+/**************************************************************/
+
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *iface)
+{
+ iface->update = update;
+ iface->delete = do_delete;
+ iface->get_secrets = get_secrets;
+}
static void
nm_sysconfig_connection_init (NMSysconfigConnection *self)
{
NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
- GError *err = NULL;
- priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
- if (err) {
- g_warning ("%s: error getting D-Bus connection: %s",
- __func__,
- (err && err->message) ? err->message : "(unknown)");
- g_error_free (err);
- }
-
- priv->pol_ctx = create_polkit_context (&err);
- if (!priv->pol_ctx) {
- g_warning ("%s: error creating PolicyKit context: %s",
- __func__,
- (err && err->message) ? err->message : "(unknown)");
- }
+ priv->authority = polkit_authority_get ();
+ if (!priv->authority)
+ g_warning ("%s: error creating PolicyKit authority", __func__);
}
static void
@@ -317,30 +507,23 @@ dispose (GObject *object)
{
NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object);
- if (priv->proxy)
- g_object_unref (priv->proxy);
-
- if (priv->pol_ctx)
- polkit_context_unref (priv->pol_ctx);
-
- if (priv->dbus_connection)
- dbus_g_connection_unref (priv->dbus_connection);
+ if (priv->authority)
+ g_object_unref (priv->authority);
G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object);
}
static void
-nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *sysconfig_connection_class)
+nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (sysconfig_connection_class);
- NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (sysconfig_connection_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ NMExportedConnectionClass *ec_class = NM_EXPORTED_CONNECTION_CLASS (class);
- g_type_class_add_private (sysconfig_connection_class, sizeof (NMSysconfigConnectionPrivate));
+ g_type_class_add_private (class, sizeof (NMSysconfigConnectionPrivate));
/* Virtual methods */
object_class->dispose = dispose;
-
- connection_class->update = update;
- connection_class->do_delete = do_delete;
- connection_class->service_get_secrets = service_get_secrets;
+ ec_class->update = dbus_update;
+ ec_class->delete = dbus_delete;
+ ec_class->get_secrets = dbus_get_secrets;
}
diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h
index 694cc58e14..3e67f52473 100644
--- a/src/system-settings/nm-sysconfig-connection.h
+++ b/src/system-settings/nm-sysconfig-connection.h
@@ -21,7 +21,8 @@
#ifndef NM_SYSCONFIG_CONNECTION_H
#define NM_SYSCONFIG_CONNECTION_H
-#include
+#include
+#include
G_BEGIN_DECLS
@@ -42,13 +43,6 @@ typedef struct {
GType nm_sysconfig_connection_get_type (void);
-/* Only for internal NM usage */
-GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *self,
- const gchar *setting_name,
- const gchar **hints,
- gboolean request_new,
- GError **error);
-
G_END_DECLS
#endif /* NM_SYSCONFIG_CONNECTION_H */
diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c
index 99f71c166b..64259d83c1 100644
--- a/src/system-settings/nm-sysconfig-settings.c
+++ b/src/system-settings/nm-sysconfig-settings.c
@@ -19,7 +19,7 @@
* 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 - 2008 Red Hat, Inc.
+ * (C) Copyright 2007 - 2009 Red Hat, Inc.
* (C) Copyright 2008 Novell, Inc.
*/
@@ -32,9 +32,12 @@
#include
#include
#include
+#include
#include
#include
#include
+#include
+#include
#include "../nm-device-ethernet.h"
#include "nm-dbus-glib-types.h"
@@ -60,20 +63,30 @@ EXPORT(nm_inotify_helper_remove_watch)
EXPORT(nm_sysconfig_connection_get_type)
/* END LINKER CRACKROCK */
+static void claim_connection (NMSysconfigSettings *self,
+ NMSettingsConnectionInterface *connection,
+ gboolean do_export);
-static gboolean
-impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context);
+static gboolean impl_settings_list_connections (NMSysconfigSettings *self,
+ GPtrArray **connections,
+ GError **error);
-static gboolean
-impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DBusGMethodInvocation *context);
+static void impl_settings_add_connection (NMSysconfigSettings *self,
+ GHashTable *settings,
+ DBusGMethodInvocation *context);
+static void impl_settings_save_hostname (NMSysconfigSettings *self,
+ const char *hostname,
+ DBusGMethodInvocation *context);
+
+#include "nm-settings-glue.h"
#include "nm-settings-system-glue.h"
-static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer user_data);
+static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
typedef struct {
NMDBusManager *dbus_mgr;
- PolKitContext *pol_ctx;
+ PolkitAuthority *authority;
char *config_file;
GSList *plugins;
@@ -83,7 +96,15 @@ typedef struct {
char *orig_hostname;
} NMSysconfigSettingsPrivate;
-G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS);
+static void settings_interface_init (NMSettingsInterface *klass);
+
+static void settings_system_interface_init (NMSettingsSystemInterface *klass);
+
+G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE,
+ settings_interface_init)
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE,
+ settings_system_interface_init))
#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate))
@@ -125,7 +146,7 @@ load_connections (NMSysconfigSettings *self)
// priority plugin.
for (elt = plugin_connections; elt; elt = g_slist_next (elt))
- nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (elt->data), TRUE);
+ claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (elt->data), TRUE);
g_slist_free (plugin_connections);
}
@@ -133,71 +154,53 @@ load_connections (NMSysconfigSettings *self)
priv->connections_loaded = TRUE;
/* FIXME: Bad hack */
- unmanaged_devices_changed (NULL, self);
+ unmanaged_specs_changed (NULL, self);
}
-static void
-hash_keys_to_slist (gpointer key, gpointer val, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_prepend (*list, key);
-}
-
-GSList *
-nm_sysconfig_settings_list_connections (NMSysconfigSettings *self)
+static gboolean
+impl_settings_list_connections (NMSysconfigSettings *self,
+ GPtrArray **connections,
+ GError **error)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GSList *list = NULL;
+ GHashTableIter iter;
+ gpointer key;
load_connections (self);
- g_hash_table_foreach (priv->connections, hash_keys_to_slist, &list);
+ *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections));
- return list;
-}
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ NMSettingsConnectionInterface *connection = key;
+ char *path = NULL;
-static GSList *
-list_connections (NMSettings *settings)
-{
- return nm_sysconfig_settings_list_connections (NM_SYSCONFIG_SETTINGS (settings));
-}
-
-typedef struct {
- const char *path;
- NMSysconfigConnection *found;
-} FindConnectionInfo;
-
-static void
-find_by_path (gpointer key, gpointer data, gpointer user_data)
-{
- FindConnectionInfo *info = user_data;
- NMSysconfigConnection *exported = NM_SYSCONFIG_CONNECTION (data);
- const char *path;
-
- if (!info->found) {
- NMConnection *connection;
-
- connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (exported));
- g_assert (connection);
- path = nm_connection_get_path (connection);
+ g_object_get (G_OBJECT (connection), NM_SETTINGS_CONNECTION_INTERFACE_PATH, &path, NULL);
g_assert (path);
- if (!strcmp (path, info->path))
- info->found = exported;
+ g_ptr_array_add (*connections, path);
}
+ return TRUE;
}
-NMSysconfigConnection *
-nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self,
- const char *path)
+static NMSettingsConnectionInterface *
+get_connection_by_path (NMSettingsInterface *self,
+ const char *path)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- FindConnectionInfo info;
+ GHashTableIter iter;
+ gpointer key;
- info.path = path;
- info.found = NULL;
- g_hash_table_foreach (priv->connections, find_by_path, &info);
- return info.found;
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ NMConnection *candidate = NM_CONNECTION (key);
+ const char *candidate_path;
+
+ candidate_path = nm_connection_get_path (candidate);
+ g_assert (candidate_path);
+ if (!strcmp (path, candidate_path))
+ return NM_SETTINGS_CONNECTION_INTERFACE (candidate);
+ }
+ return NULL;
}
static void
@@ -210,30 +213,6 @@ clear_unmanaged_specs (NMSysconfigSettings *self)
priv->unmanaged_specs = NULL;
}
-static void
-finalize (GObject *object)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
-
- g_hash_table_destroy (priv->connections);
-
- clear_unmanaged_specs (self);
-
- g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
- g_slist_free (priv->plugins);
-
- if (priv->pol_ctx)
- polkit_context_unref (priv->pol_ctx);
-
- g_object_unref (priv->dbus_mgr);
-
- g_free (priv->orig_hostname);
- g_free (priv->config_file);
-
- G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
-}
-
static char*
uscore_to_wincaps (const char *uscore)
{
@@ -288,9 +267,8 @@ nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self)
return priv->unmanaged_specs;
}
-NMSystemConfigInterface *
-nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self,
- guint32 capability)
+static NMSystemConfigInterface *
+get_plugin (NMSysconfigSettings *self, guint32 capability)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
@@ -338,125 +316,12 @@ nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self)
return hostname;
}
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
- const GSList *specs, *iter;
- GSList *copy = NULL;
-
- switch (prop_id) {
- case PROP_UNMANAGED_SPECS:
- specs = nm_sysconfig_settings_get_unmanaged_specs (self);
- for (iter = specs; iter; iter = g_slist_next (iter))
- copy = g_slist_append (copy, g_strdup (iter->data));
- g_value_take_boxed (value, copy);
- break;
- case PROP_HOSTNAME:
- g_value_take_string (value, nm_sysconfig_settings_get_hostname (self));
-
- /* Don't ever pass NULL through D-Bus */
- if (!g_value_get_string (value))
- g_value_set_static_string (value, "");
- break;
- case PROP_CAN_MODIFY:
- g_value_set_boolean (value, !!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class);
-
- g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate));
-
- /* virtual methods */
- object_class->notify = notify;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
- settings_class->list_connections = list_connections;
-
- /* properties */
- g_object_class_install_property
- (object_class, PROP_UNMANAGED_SPECS,
- g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
- "Unamanged device specs",
- "Unmanaged device specs",
- DBUS_TYPE_G_LIST_OF_STRING,
- G_PARAM_READABLE));
-
- g_object_class_install_property
- (object_class, PROP_HOSTNAME,
- g_param_spec_string (NM_SYSCONFIG_SETTINGS_HOSTNAME,
- "Hostname",
- "Hostname",
- NULL,
- G_PARAM_READABLE));
-
- g_object_class_install_property
- (object_class, PROP_CAN_MODIFY,
- g_param_spec_boolean (NM_SYSCONFIG_SETTINGS_CAN_MODIFY,
- "CanModify",
- "Can modify",
- FALSE,
- G_PARAM_READABLE));
-
- /* signals */
- signals[PROPERTIES_CHANGED] =
- g_signal_new ("properties-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
-
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class),
- &dbus_glib_nm_settings_system_object_info);
-
- dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_DBUS_IFACE_SETTINGS_SYSTEM,
- NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
-}
-
-static void
-nm_sysconfig_settings_init (NMSysconfigSettings *self)
-{
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- char hostname[HOST_NAME_MAX + 2];
- GError *error = NULL;
-
- priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
-
- priv->pol_ctx = create_polkit_context (&error);
- if (!priv->pol_ctx) {
- g_warning ("%s: failed to create PolicyKit context: %s",
- __func__,
- (error && error->message) ? error->message : "(unknown)");
- }
-
- /* Grab hostname on startup and use that if no plugins provide one */
- memset (hostname, 0, sizeof (hostname));
- if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) {
- /* only cache it if it's a valid hostname */
- if (strlen (hostname) && strcmp (hostname, "localhost") && strcmp (hostname, "localhost.localdomain"))
- priv->orig_hostname = g_strdup (hostname);
- }
-}
-
static void
plugin_connection_added (NMSystemConfigInterface *config,
- NMExportedConnection *connection,
+ NMSettingsConnectionInterface *connection,
gpointer user_data)
{
- nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE);
+ claim_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE);
}
static gboolean
@@ -473,8 +338,8 @@ find_unmanaged_device (NMSysconfigSettings *self, const char *needle)
}
static void
-unmanaged_devices_changed (NMSystemConfigInterface *config,
- gpointer user_data)
+unmanaged_specs_changed (NMSystemConfigInterface *config,
+ gpointer user_data)
{
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
@@ -482,7 +347,7 @@ unmanaged_devices_changed (NMSystemConfigInterface *config,
clear_unmanaged_specs (self);
- /* Ask all the plugins for their unmanaged devices */
+ /* Ask all the plugins for their unmanaged specs */
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
GSList *specs, *specs_iter;
@@ -505,7 +370,7 @@ hostname_changed (NMSystemConfigInterface *config,
GParamSpec *pspec,
gpointer user_data)
{
- g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME);
+ g_object_notify (G_OBJECT (user_data), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
}
static void
@@ -522,8 +387,10 @@ add_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *plugin)
priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
- g_signal_connect (plugin, "connection-added", G_CALLBACK (plugin_connection_added), self);
- g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self);
+ g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
+ G_CALLBACK (plugin_connection_added), self);
+ g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
+ G_CALLBACK (unmanaged_specs_changed), self);
g_signal_connect (plugin, "notify::hostname", G_CALLBACK (hostname_changed), self);
nm_system_config_interface_init (plugin, NULL);
@@ -639,23 +506,45 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error)
}
static void
-connection_removed (NMExportedConnection *connection,
- gpointer user_data)
+connection_removed (NMSettingsConnectionInterface *connection,
+ gpointer user_data)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
g_hash_table_remove (priv->connections, connection);
}
-void
-nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
- NMExportedConnection *connection,
- gboolean do_export)
+static void
+export_connection (NMSysconfigSettings *self,
+ NMSettingsConnectionInterface *connection)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ static guint32 ec_counter = 0;
+ char *path;
+ DBusGConnection *bus;
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
+
+ path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++);
+ nm_connection_set_path (NM_CONNECTION (connection), path);
+ nm_connection_set_scope (NM_CONNECTION (connection), NM_CONNECTION_SCOPE_SYSTEM);
+
+ bus = nm_dbus_manager_get_connection (priv->dbus_mgr);
+ dbus_g_connection_register_g_object (bus, path, G_OBJECT (connection));
+
+ g_free (path);
+}
+
+static void
+claim_connection (NMSysconfigSettings *self,
+ NMSettingsConnectionInterface *connection,
+ gboolean do_export)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
if (g_hash_table_lookup (priv->connections, connection))
/* A plugin is lying to us. */
@@ -665,52 +554,85 @@ nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
if (do_export) {
- DBusGConnection *g_connection;
-
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- nm_exported_connection_register_object (connection, NM_CONNECTION_SCOPE_SYSTEM, g_connection);
- nm_settings_signal_new_connection (NM_SETTINGS (self), connection);
+ export_connection (self, connection);
+ g_signal_emit_by_name (self, "new-connection", connection);
}
}
-void
-nm_sysconfig_settings_remove_connection (NMSysconfigSettings *self,
- NMExportedConnection *connection,
- gboolean do_signal)
+static void
+remove_connection (NMSysconfigSettings *self,
+ NMSettingsConnectionInterface *connection,
+ gboolean do_signal)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
+ g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection));
if (g_hash_table_lookup (priv->connections, connection)) {
- nm_exported_connection_signal_removed (connection);
+ g_signal_emit_by_name (G_OBJECT (connection), "removed");
g_hash_table_remove (priv->connections, connection);
}
}
-gboolean
-nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self,
- GHashTable *hash,
- GError **error)
+typedef struct {
+ NMSysconfigSettings *self;
+ DBusGMethodInvocation *context;
+ PolkitSubject *subject;
+ GCancellable *cancellable;
+
+ NMConnection *connection;
+ char *hostname;
+} PolkitCall;
+
+static PolkitCall *
+polkit_call_new (NMSysconfigSettings *self,
+ DBusGMethodInvocation *context,
+ NMConnection *connection,
+ const char *hostname)
+{
+ PolkitCall *call;
+ char *sender;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (context != NULL, NULL);
+
+ call = g_malloc0 (sizeof (PolkitCall));
+ call->self = self;
+ call->context = context;
+ call->connection = connection;
+ if (hostname)
+ call->hostname = g_strdup (hostname);
+ call->cancellable = g_cancellable_new ();
+
+ sender = dbus_g_method_get_sender (context);
+ call->subject = polkit_system_bus_name_new (sender);
+ g_free (sender);
+
+ return call;
+}
+
+static void
+polkit_call_free (PolkitCall *call)
+{
+ if (call->connection)
+ g_object_unref (call->connection);
+ g_free (call->hostname);
+ g_object_unref (call->subject);
+ g_object_unref (call->cancellable);
+ g_free (call);
+}
+
+static gboolean
+add_new_connection (NMSysconfigSettings *self,
+ NMConnection *connection,
+ GError **error)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- NMConnection *connection;
GError *tmp_error = NULL, *last_error = NULL;
GSList *iter;
gboolean success = FALSE;
- connection = nm_connection_new_from_hash (hash, &tmp_error);
- if (!connection) {
- /* Invalid connection hash */
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
- "Invalid connection: '%s' / '%s' invalid: %d",
- tmp_error ? g_type_name (nm_connection_lookup_setting_type_by_quark (tmp_error->domain)) : "(unknown)",
- tmp_error ? tmp_error->message : "(unknown)", tmp_error ? tmp_error->code : -1);
- g_clear_error (&tmp_error);
- return FALSE;
- }
-
/* Here's how it works:
1) plugin writes a connection.
2) plugin notices that a new connection is available for reading.
@@ -720,82 +642,133 @@ nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self,
for (iter = priv->plugins; iter && !success; iter = iter->next) {
success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data),
- connection, &tmp_error);
+ connection,
+ &tmp_error);
g_clear_error (&last_error);
if (!success)
last_error = tmp_error;
}
- g_object_unref (connection);
-
- if (!success) {
- g_set_error (error, NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED,
- "Saving connection failed: (%d) %s",
- last_error ? last_error->code : -1,
- last_error && last_error->message ? last_error->message : "(unknown)");
- g_clear_error (&last_error);
- }
-
+ if (!success)
+ *error = last_error;
return success;
}
-static gboolean
+static void
+pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ PolkitCall *call = user_data;
+ NMSysconfigSettings *self = call->self;
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ PolkitAuthorizationResult *pk_result;
+ GError *error = NULL, *add_error = NULL;
+
+ pk_result = polkit_authority_check_authorization_finish (priv->authority,
+ result,
+ &error);
+ /* Some random error happened */
+ if (error) {
+ dbus_g_method_return_error (call->context, error);
+ goto out;
+ }
+
+ /* Caller didn't successfully authenticate */
+ if (!polkit_authorization_result_get_is_authorized (pk_result)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ dbus_g_method_return_error (call->context, error);
+ goto out;
+ }
+
+ if (add_new_connection (self, call->connection, &add_error)) {
+ dbus_g_method_return (call->context);
+ } else {
+ error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED,
+ "Saving connection failed: (%d) %s",
+ add_error ? add_error->code : -1,
+ (add_error && add_error->message) ? add_error->message : "(unknown)");
+ g_error_free (add_error);
+ dbus_g_method_return_error (call->context, error);
+ }
+
+out:
+ g_clear_error (&error);
+ polkit_call_free (call);
+ if (pk_result)
+ g_object_unref (pk_result);
+}
+
+static void
impl_settings_add_connection (NMSysconfigSettings *self,
- GHashTable *hash,
+ GHashTable *settings,
DBusGMethodInvocation *context)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- DBusGConnection *g_connection;
- GError *err = NULL;
+ PolkitCall *call;
+ NMConnection *tmp;
+ GError *error = NULL;
/* Do any of the plugins support adding? */
- if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
- err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
- "%s", "None of the registered plugins support add.");
- goto out;
+ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED,
+ "None of the registered plugins support add.");
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
}
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err))
- goto out;
-
- nm_sysconfig_settings_add_new_connection (self, hash, &err);
-
- out:
- if (err) {
- dbus_g_method_return_error (context, err);
- g_error_free (err);
- return FALSE;
- } else {
- dbus_g_method_return (context);
- return TRUE;
+ /* Check if the settings are valid first */
+ tmp = nm_connection_new_from_hash (settings, &error);
+ if (!tmp) {
+ g_assert (error);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
}
+
+ call = polkit_call_new (self, context, tmp, NULL);
+ g_assert (call);
+ polkit_authority_check_authorization (priv->authority,
+ call->subject,
+ NM_SYSCONFIG_POLICY_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ call->cancellable,
+ pk_add_cb,
+ call);
}
-static gboolean
-impl_settings_save_hostname (NMSysconfigSettings *self,
- const char *hostname,
- DBusGMethodInvocation *context)
+static void
+pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data)
{
+ PolkitCall *call = user_data;
+ NMSysconfigSettings *self = call->self;
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- GError *err = NULL;
+ PolkitAuthorizationResult *pk_result;
+ GError *error = NULL;
GSList *iter;
gboolean success = FALSE;
- DBusGConnection *g_connection;
- /* Do any of the plugins support setting the hostname? */
- if (!nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
- err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
- "%s", "None of the registered plugins support setting the hostname.");
+ pk_result = polkit_authority_check_authorization_finish (priv->authority,
+ result,
+ &error);
+ /* Some random error happened */
+ if (error) {
+ dbus_g_method_return_error (call->context, error);
goto out;
}
- g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
- if (!check_polkit_privileges (g_connection, priv->pol_ctx, context, &err))
+ /* Caller didn't successfully authenticate */
+ if (!polkit_authorization_result_get_is_authorized (pk_result)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "Insufficient privileges.");
+ dbus_g_method_return_error (call->context, error);
goto out;
+ }
/* Set the hostname in all plugins */
for (iter = priv->plugins; iter; iter = iter->next) {
@@ -803,32 +776,64 @@ impl_settings_save_hostname (NMSysconfigSettings *self,
g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL);
if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) {
- g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL);
+ g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, call->hostname, NULL);
success = TRUE;
}
}
- if (!success) {
- err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
- NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
- "%s", "Saving the hostname failed.");
+ if (success) {
+ dbus_g_method_return (call->context);
+ } else {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED,
+ "Saving the hostname failed.");
+ dbus_g_method_return_error (call->context, error);
}
- out:
- if (err) {
- dbus_g_method_return_error (context, err);
- g_error_free (err);
- return FALSE;
- } else {
- dbus_g_method_return (context);
- return TRUE;
+out:
+ g_clear_error (&error);
+ polkit_call_free (call);
+ if (pk_result)
+ g_object_unref (pk_result);
+}
+
+static void
+impl_settings_save_hostname (NMSysconfigSettings *self,
+ const char *hostname,
+ DBusGMethodInvocation *context)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ PolkitCall *call;
+ GError *error = NULL;
+
+ /* Do any of the plugins support setting the hostname? */
+ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) {
+ error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED,
+ "None of the registered plugins support setting the hostname.");
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
}
+
+ call = polkit_call_new (self, context, NULL, hostname);
+ g_assert (call);
+ polkit_authority_check_authorization (priv->authority,
+ call->subject,
+ NM_SYSCONFIG_POLICY_ACTION,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ call->cancellable,
+ pk_hostname_cb,
+ call);
}
static gboolean
have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac)
{
- GSList *list, *iter;
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ GHashTableIter iter;
+ gpointer key;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
const GByteArray *setting_mac;
@@ -838,16 +843,11 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac)
g_return_val_if_fail (mac != NULL, FALSE);
/* Find a wired connection locked to the given MAC address, if any */
- list = nm_settings_list_connections (NM_SETTINGS (self));
- for (iter = list; iter; iter = g_slist_next (iter)) {
- NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data);
- NMConnection *connection;
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, &key, NULL)) {
+ NMConnection *connection = NM_CONNECTION (key);
const char *connection_type;
- connection = nm_exported_connection_get_connection (exported);
- if (!connection)
- continue;
-
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
connection_type = nm_setting_connection_get_connection_type (s_con);
@@ -877,7 +877,6 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac)
}
}
- g_slist_free (list);
return ret;
}
@@ -932,7 +931,6 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
NMSysconfigSettings *self)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- NMConnection *wrapped;
NMSettingConnection *s_con;
char *tmp;
GKeyFile *config;
@@ -951,9 +949,8 @@ default_wired_deleted (NMDefaultWiredConnection *wired,
* connection for that device again.
*/
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired));
- g_assert (wrapped);
- s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
+ NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
/* Ignore removals of read-only connections, since they couldn't have
@@ -1015,13 +1012,11 @@ cleanup:
NULL);
}
-static void
+static gboolean
default_wired_try_update (NMDefaultWiredConnection *wired,
- GHashTable *new_settings,
NMSysconfigSettings *self)
{
GError *error = NULL;
- NMConnection *wrapped;
NMSettingConnection *s_con;
const char *id;
@@ -1029,32 +1024,32 @@ default_wired_try_update (NMDefaultWiredConnection *wired,
* persistent storage.
*/
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired));
- g_assert (wrapped);
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
+ NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
- nm_sysconfig_settings_remove_connection (self, NM_EXPORTED_CONNECTION (wired), FALSE);
- if (nm_sysconfig_settings_add_new_connection (self, new_settings, &error)) {
+ remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE);
+ if (add_new_connection (self, NM_CONNECTION (wired), &error)) {
g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)),
DEFAULT_WIRED_TAG,
NULL);
g_message ("Saved default wired connection '%s' to persistent storage", id);
- return;
+ return FALSE;
}
g_warning ("%s: couldn't save default wired connection '%s': %d / %s",
- __func__, id, error ? error->code : -1,
+ __func__, id,
+ error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
- g_clear_error (&error);
/* If there was an error, don't destroy the default wired connection,
* but add it back to the system settings service. Connection is already
* exported on the bus, don't export it again, thus do_export == FALSE.
*/
- nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (wired), FALSE);
+ claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE);
+ return TRUE;
}
void
@@ -1062,9 +1057,8 @@ nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device)
{
GByteArray *mac = NULL;
struct ether_addr tmp;
- NMDefaultWiredConnection *connection;
+ NMDefaultWiredConnection *wired;
NMSettingConnection *s_con;
- NMConnection *wrapped;
gboolean read_only = TRUE;
const char *id;
@@ -1087,28 +1081,27 @@ nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device)
|| is_mac_auto_wired_blacklisted (self, mac))
goto ignore;
- if (nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
+ if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS))
read_only = FALSE;
- connection = nm_default_wired_connection_new (mac, device, read_only);
- if (!connection)
+ wired = nm_default_wired_connection_new (mac, device, read_only);
+ if (!wired)
goto ignore;
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
- g_assert (wrapped);
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (wired),
+ NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
id = nm_setting_connection_get_id (s_con);
g_assert (id);
g_message ("Added default wired connection '%s' for %s", id, nm_device_get_udi (device));
- g_signal_connect (connection, "try-update", (GCallback) default_wired_try_update, self);
- g_signal_connect (connection, "deleted", (GCallback) default_wired_deleted, self);
- nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (connection), TRUE);
- g_object_unref (connection);
+ g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self);
+ g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self);
+ claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), TRUE);
+ g_object_unref (wired);
- g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, connection);
+ g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired);
ignore:
g_byte_array_free (mac, TRUE);
@@ -1117,14 +1110,14 @@ ignore:
void
nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device)
{
- NMExportedConnection *exported;
+ NMDefaultWiredConnection *connection;
if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET)
return;
- exported = (NMExportedConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
- if (exported)
- nm_sysconfig_settings_remove_connection (self, exported, TRUE);
+ connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG);
+ if (connection)
+ remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (connection), TRUE);
}
NMSysconfigSettings *
@@ -1161,3 +1154,144 @@ nm_sysconfig_settings_new (const char *config_file,
return self;
}
+/***************************************************************/
+
+static void
+finalize (GObject *object)
+{
+ NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+
+ g_hash_table_destroy (priv->connections);
+
+ clear_unmanaged_specs (self);
+
+ g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->plugins);
+
+ if (priv->authority)
+ g_object_unref (priv->authority);
+
+ g_object_unref (priv->dbus_mgr);
+
+ g_free (priv->orig_hostname);
+ g_free (priv->config_file);
+
+ G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
+}
+
+static void
+settings_interface_init (NMSettingsInterface *iface)
+{
+ iface->get_connection_by_path = get_connection_by_path;
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface),
+ &dbus_glib_nm_settings_object_info);
+}
+
+static void
+settings_system_interface_init (NMSettingsSystemInterface *iface)
+{
+ dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface),
+ &dbus_glib_nm_settings_system_object_info);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
+ const GSList *specs, *iter;
+ GSList *copy = NULL;
+
+ switch (prop_id) {
+ case PROP_UNMANAGED_SPECS:
+ specs = nm_sysconfig_settings_get_unmanaged_specs (self);
+ for (iter = specs; iter; iter = g_slist_next (iter))
+ copy = g_slist_append (copy, g_strdup (iter->data));
+ g_value_take_boxed (value, copy);
+ break;
+ case PROP_HOSTNAME:
+ g_value_take_string (value, nm_sysconfig_settings_get_hostname (self));
+
+ /* Don't ever pass NULL through D-Bus */
+ if (!g_value_get_string (value))
+ g_value_set_static_string (value, "");
+ break;
+ case PROP_CAN_MODIFY:
+ g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate));
+
+ /* virtual methods */
+ object_class->notify = notify;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ /* properties */
+ g_object_class_install_property
+ (object_class, PROP_UNMANAGED_SPECS,
+ g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS,
+ "Unamanged device specs",
+ "Unmanaged device specs",
+ DBUS_TYPE_G_LIST_OF_STRING,
+ G_PARAM_READABLE));
+
+ g_object_class_override_property (object_class,
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME,
+ NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME);
+
+ g_object_class_override_property (object_class,
+ NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY,
+ NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY);
+
+ /* signals */
+ signals[PROPERTIES_CHANGED] =
+ g_signal_new ("properties-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
+ &dbus_glib_nm_settings_object_info);
+
+ dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_DBUS_IFACE_SETTINGS_SYSTEM,
+ NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
+}
+
+static void
+nm_sysconfig_settings_init (NMSysconfigSettings *self)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ char hostname[HOST_NAME_MAX + 2];
+
+ priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
+
+ priv->authority = polkit_authority_get ();
+ if (!priv->authority)
+ g_warning ("%s: failed to create PolicyKit authority.", __func__);
+
+ /* Grab hostname on startup and use that if no plugins provide one */
+ memset (hostname, 0, sizeof (hostname));
+ if (gethostname (&hostname[0], HOST_NAME_MAX) == 0) {
+ /* only cache it if it's a valid hostname */
+ if (strlen (hostname) && strcmp (hostname, "localhost") && strcmp (hostname, "localhost.localdomain"))
+ priv->orig_hostname = g_strdup (hostname);
+ }
+}
+
diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h
index 632c75daf8..badb6442e9 100644
--- a/src/system-settings/nm-sysconfig-settings.h
+++ b/src/system-settings/nm-sysconfig-settings.h
@@ -27,15 +27,11 @@
#define __NM_SYSCONFIG_SETTINGS_H__
#include
-#include
#include "nm-sysconfig-connection.h"
#include "nm-system-config-interface.h"
#include "nm-device.h"
-typedef struct _NMSysconfigSettings NMSysconfigSettings;
-typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
-
#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ())
#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings))
#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
@@ -44,21 +40,17 @@ typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
#define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs"
-#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname"
-#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify"
-struct _NMSysconfigSettings
-{
- NMSettings parent_instance;
-};
+typedef struct {
+ GObject parent_instance;
+} NMSysconfigSettings;
-struct _NMSysconfigSettingsClass
-{
- NMSettingsClass parent_class;
+typedef struct {
+ GObjectClass parent_class;
/* Signals */
- void (*properties_changed) (NMSysconfigSettings *settings, GHashTable *properties);
-};
+ void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties);
+} NMSysconfigSettingsClass;
GType nm_sysconfig_settings_get_type (void);
@@ -66,34 +58,10 @@ NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file,
const char *plugins,
GError **error);
-/* Registers an exising connection with the settings service */
-void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
- NMExportedConnection *connection,
- gboolean do_export);
-
-void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
- NMExportedConnection *connection,
- gboolean do_signal);
-
-NMSystemConfigInterface *nm_sysconfig_settings_get_plugin (NMSysconfigSettings *self,
- guint32 capability);
-
-/* Adds a new connection from a hash of that connection's settings,
- * potentially saving the new connection to persistent storage.
- */
-gboolean nm_sysconfig_settings_add_new_connection (NMSysconfigSettings *self,
- GHashTable *hash,
- GError **error);
-
const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self);
char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self);
-GSList *nm_sysconfig_settings_list_connections (NMSysconfigSettings *self);
-
-NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self,
- const char *path);
-
void nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device);
void nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device);
diff --git a/src/system-settings/nm-system-config-interface.c b/src/system-settings/nm-system-config-interface.c
index 2f33e59069..90fd93ba3d 100644
--- a/src/system-settings/nm-system-config-interface.c
+++ b/src/system-settings/nm-system-config-interface.c
@@ -66,19 +66,19 @@ interface_init (gpointer g_iface)
G_PARAM_READWRITE));
/* Signals */
- g_signal_new ("connection-added",
+ g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED,
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigInterface, connection_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
- NM_TYPE_EXPORTED_CONNECTION);
+ NM_TYPE_SETTINGS_CONNECTION_INTERFACE);
- g_signal_new ("unmanaged-devices-changed",
+ g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED,
iface_type,
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_devices_changed),
+ G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_specs_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h
index 1be49a7ee0..c5bbaaa917 100644
--- a/src/system-settings/nm-system-config-interface.h
+++ b/src/system-settings/nm-system-config-interface.h
@@ -25,7 +25,7 @@
#include
#include
#include
-#include
+#include
G_BEGIN_DECLS
@@ -61,6 +61,9 @@ GObject * nm_system_config_factory (void);
#define NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES "capabilities"
#define NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME "hostname"
+#define NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed"
+#define NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED "connection-added"
+
typedef enum {
NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE = 0x00000000,
NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS = 0x00000001,
@@ -87,8 +90,9 @@ struct _NMSystemConfigInterface {
/* Called when the plugin is loaded to initialize it */
void (*init) (NMSystemConfigInterface *config);
- /* Returns the plugins currently known list of connections. The returned
- * list is freed by the system settings service.
+ /* Returns a GSList of objects that implement NMSettingsConnectionInterface
+ * that represent connections the plugin knows about. The returned list
+ * is freed by the system settings service.
*/
GSList * (*get_connections) (NMSystemConfigInterface *config);
@@ -109,15 +113,18 @@ struct _NMSystemConfigInterface {
/*
* Add a new connection.
*/
- gboolean (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection, GError **error);
+ gboolean (*add_connection) (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ GError **error);
/* Signals */
/* Emitted when a new connection has been found by the plugin */
- void (*connection_added) (NMSystemConfigInterface *config, NMExportedConnection *connection);
+ void (*connection_added) (NMSystemConfigInterface *config,
+ NMSettingsConnectionInterface *connection);
- /* Emitted when the list of unmanaged devices changes */
- void (*unmanaged_devices_changed) (NMSystemConfigInterface *config);
+ /* Emitted when the list of unmanaged device specifications changes */
+ void (*unmanaged_specs_changed) (NMSystemConfigInterface *config);
};
GType nm_system_config_interface_get_type (void);
diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
index 4767b5183c..aafc41e9f4 100644
--- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
+++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include "common.h"
#include "nm-ifcfg-connection.h"
@@ -40,7 +41,13 @@
#include "writer.h"
#include "nm-inotify-helper.h"
-G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECTION)
+static NMSettingsConnectionInterface *parent_settings_connection_iface;
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *klass);
+
+G_DEFINE_TYPE_EXTENDED (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ settings_connection_interface_init))
#define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate))
@@ -97,24 +104,32 @@ nm_ifcfg_connection_new (const char *filename,
{
GObject *object;
NMIfcfgConnectionPrivate *priv;
- NMConnection *wrapped;
+ NMConnection *tmp;
char *unmanaged = NULL;
char *keyfile = NULL;
NMInotifyHelper *ih;
+ GHashTable *settings;
g_return_val_if_fail (filename != NULL, NULL);
- wrapped = connection_from_file (filename, NULL, NULL, &unmanaged, &keyfile, error, ignore_error);
- if (!wrapped)
+ tmp = connection_from_file (filename, NULL, NULL, &unmanaged, &keyfile, error, ignore_error);
+ if (!tmp)
return NULL;
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
NM_IFCFG_CONNECTION_FILENAME, filename,
NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
- NM_EXPORTED_CONNECTION_CONNECTION, wrapped,
NULL);
- if (!object)
- goto out;
+ if (!object) {
+ g_object_unref (tmp);
+ return NULL;
+ }
+
+ /* Update our settings with what was read from the file */
+ settings = nm_connection_to_hash (tmp);
+ nm_connection_replace_settings (NM_CONNECTION (object), settings, NULL);
+ g_hash_table_destroy (settings);
+ g_object_unref (tmp);
priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
@@ -126,9 +141,7 @@ nm_ifcfg_connection_new (const char *filename,
priv->keyfile = keyfile;
priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile);
-out:
- g_object_unref (wrapped);
- return (NMIfcfgConnection *) object;
+ return NM_IFCFG_CONNECTION (object);
}
const char *
@@ -147,43 +160,51 @@ nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self)
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged;
}
-gboolean
-nm_ifcfg_connection_update (NMIfcfgConnection *self, GHashTable *new_settings, GError **error)
+static gboolean
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
{
- NMExportedConnection *exported = NM_EXPORTED_CONNECTION (self);
- NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (exported);
- NMConnection *connection;
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
+ GError *error = NULL;
- connection = nm_exported_connection_get_connection (exported);
- if (!nm_connection_replace_settings (connection, new_settings, error))
+ if (!writer_update_connection (NM_CONNECTION (connection),
+ IFCFG_DIR,
+ priv->filename,
+ priv->keyfile,
+ &error)) {
+ callback (connection, error, user_data);
+ g_error_free (error);
return FALSE;
+ }
- return writer_update_connection (connection, IFCFG_DIR, priv->filename, priv->keyfile, error);
+ return parent_settings_connection_iface->update (connection, callback, user_data);
}
-static gboolean
-update (NMExportedConnection *exported, GHashTable *new_settings, GError **error)
+static gboolean
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
{
- if (!NM_EXPORTED_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->update (exported, new_settings, error))
- return FALSE;
-
- return nm_ifcfg_connection_update (NM_IFCFG_CONNECTION (exported), new_settings, error);
-}
-
-static gboolean
-do_delete (NMExportedConnection *exported, GError **error)
-{
- NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (exported);
+ NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
g_unlink (priv->filename);
if (priv->keyfile)
g_unlink (priv->keyfile);
- return TRUE;
+ return parent_settings_connection_iface->delete (connection, callback, user_data);
}
/* GObject */
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *iface)
+{
+ parent_settings_connection_iface = g_type_interface_peek_parent (iface);
+ iface->update = update;
+ iface->delete = do_delete;
+}
+
static void
nm_ifcfg_connection_init (NMIfcfgConnection *connection)
{
@@ -193,14 +214,11 @@ static void
finalize (GObject *object)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
- NMConnection *wrapped;
NMInotifyHelper *ih;
g_free (priv->udi);
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (object));
- if (wrapped)
- nm_connection_clear_secrets (wrapped);
+ nm_connection_clear_secrets (NM_CONNECTION (object));
ih = nm_inotify_helper_get ();
@@ -267,7 +285,6 @@ static void
nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class);
- NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (ifcfg_connection_class);
g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate));
@@ -276,9 +293,6 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
object_class->get_property = get_property;
object_class->finalize = finalize;
- connection_class->update = update;
- connection_class->do_delete = do_delete;
-
/* Properties */
g_object_class_install_property
(object_class, PROP_FILENAME,
diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c
index 361a858005..f861aebebd 100644
--- a/system-settings/plugins/ifcfg-rh/plugin.c
+++ b/system-settings/plugins/ifcfg-rh/plugin.c
@@ -88,7 +88,7 @@ connection_unmanaged_changed (NMIfcfgConnection *connection,
GParamSpec *pspec,
gpointer user_data)
{
- g_signal_emit_by_name (SC_PLUGIN_IFCFG (user_data), "unmanaged-devices-changed");
+ g_signal_emit_by_name (SC_PLUGIN_IFCFG (user_data), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
static void
@@ -117,13 +117,10 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename)
connection = nm_ifcfg_connection_new (filename, &error, &ignore_error);
if (connection) {
- NMConnection *wrapped;
NMSettingConnection *s_con;
const char *cid;
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
- g_assert (wrapped);
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
cid = nm_setting_connection_get_id (s_con);
@@ -137,7 +134,7 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename)
if (nm_ifcfg_connection_get_unmanaged_spec (connection)) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
"device because NM_CONTROLLED was false.", cid);
- g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
+ g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
} else {
/* Wait for the connection to become unmanaged once it knows the
* UDI of it's device, if/when the device gets plugged in.
@@ -227,6 +224,13 @@ read_connections (SCPluginIfcfg *plugin)
/* Monitoring */
+static void
+ignore_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+}
+
static void
connection_changed_handler (SCPluginIfcfg *plugin,
const char *path,
@@ -234,7 +238,7 @@ connection_changed_handler (SCPluginIfcfg *plugin,
gboolean *do_remove,
gboolean *do_new)
{
- NMIfcfgConnection *tmp;
+ NMIfcfgConnection *new;
GError *error = NULL;
GHashTable *settings;
gboolean ignore_error = FALSE;
@@ -248,8 +252,8 @@ connection_changed_handler (SCPluginIfcfg *plugin,
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path);
- tmp = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error);
- if (!tmp) {
+ new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error);
+ if (!new) {
/* errors reading connection; remove it */
if (!ignore_error) {
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s",
@@ -265,7 +269,7 @@ connection_changed_handler (SCPluginIfcfg *plugin,
/* Successfully read connection changes */
old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection));
- new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (tmp));
+ new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new));
if (new_unmanaged) {
if (!old_unmanaged) {
@@ -273,16 +277,11 @@ connection_changed_handler (SCPluginIfcfg *plugin,
*do_remove = *do_new = TRUE;
}
} else {
- NMConnection *old_wrapped, *new_wrapped;
-
- new_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (tmp));
- old_wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
-
if (old_unmanaged) { /* now managed */
NMSettingConnection *s_con;
const char *cid;
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (new_wrapped, NM_TYPE_SETTING_CONNECTION));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (new), NM_TYPE_SETTING_CONNECTION);
g_assert (s_con);
cid = nm_setting_connection_get_id (s_con);
@@ -290,25 +289,30 @@ connection_changed_handler (SCPluginIfcfg *plugin,
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its "
"device because NM_CONTROLLED was true.", cid);
- g_signal_emit_by_name (plugin, "connection-added", connection);
+ g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
}
/* Only update if different */
- if (!nm_connection_compare (new_wrapped, old_wrapped, NM_SETTING_COMPARE_FLAG_EXACT)) {
- settings = nm_connection_to_hash (new_wrapped);
- if (!nm_ifcfg_connection_update (connection, settings, &error)) {
+ if (!nm_connection_compare (NM_CONNECTION (new),
+ NM_CONNECTION (connection),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ settings = nm_connection_to_hash (NM_CONNECTION (new));
+ if (!nm_connection_replace_settings (NM_CONNECTION (connection), settings, &error)) {
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s",
(error && error->message) ? error->message : "(unknown)");
g_clear_error (&error);
}
g_hash_table_destroy (settings);
+ nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
+ ignore_cb,
+ NULL);
}
/* Update unmanaged status */
g_object_set (connection, "unmanaged", new_unmanaged, NULL);
- g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
+ g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
- g_object_unref (tmp);
+ g_object_unref (new);
}
static void
@@ -330,18 +334,18 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin,
unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection);
g_hash_table_remove (priv->connections, path);
- nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection));
+ g_signal_emit_by_name (connection, "removed");
/* Emit unmanaged changes _after_ removing the connection */
if (unmanaged)
- g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
+ g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
if (do_new) {
connection = read_one_connection (plugin, path);
if (connection) {
- if (!nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection)))
- g_signal_emit_by_name (plugin, "connection-added", connection);
+ if (!nm_ifcfg_connection_get_unmanaged_spec (connection))
+ g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
}
}
}
diff --git a/system-settings/plugins/ifcfg-suse/plugin.c b/system-settings/plugins/ifcfg-suse/plugin.c
index c07ff2df60..86d3abea88 100644
--- a/system-settings/plugins/ifcfg-suse/plugin.c
+++ b/system-settings/plugins/ifcfg-suse/plugin.c
@@ -190,7 +190,7 @@ read_connection (SCPluginIfcfg *self, GUdevDevice *device, NMDeviceType dev_type
if (address && (strlen (address) == 17)) {
spec = g_strdup_printf ("mac:%s", address);
g_hash_table_insert (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex), spec);
- g_signal_emit_by_name (self, "unmanaged-devices-changed");
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
} else
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " (%s) error getting hardware address", iface);
} else {
@@ -201,7 +201,7 @@ read_connection (SCPluginIfcfg *self, GUdevDevice *device, NMDeviceType dev_type
g_hash_table_insert (priv->connections,
GUINT_TO_POINTER (ifindex),
connection);
- g_signal_emit_by_name (self, "connection-added", connection);
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
}
}
}
@@ -281,7 +281,7 @@ handle_uevent (GUdevClient *client,
ifindex = (guint32) g_udev_device_get_property_as_uint64 (device, "IFINDEX");
if (g_hash_table_remove (priv->unmanaged_specs, GUINT_TO_POINTER (ifindex)))
- g_signal_emit_by_name (self, "unmanaged-devices-changed");
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections,
GUINT_TO_POINTER (ifindex));
diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c
index 00c3ffc30d..a38f40cfca 100644
--- a/system-settings/plugins/ifupdown/plugin.c
+++ b/system-settings/plugins/ifupdown/plugin.c
@@ -255,7 +255,7 @@ udev_device_added (SCPluginIfupdown *self, GUdevDevice *device)
g_hash_table_insert (priv->well_known_ifaces, g_strdup (iface), g_object_ref (device));
if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
- g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed");
+ g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
else
bind_device_to_connection (self, device, exported);
}
@@ -278,7 +278,7 @@ udev_device_removed (SCPluginIfupdown *self, GUdevDevice *device)
return;
if (ALWAYS_UNMANAGE || priv->unmanage_well_known)
- g_signal_emit_by_name (G_OBJECT (self), "unmanaged-devices-changed");
+ g_signal_emit_by_name (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
}
static void
diff --git a/system-settings/plugins/keyfile/io/writer.c b/system-settings/plugins/keyfile/io/writer.c
index bbf40c7937..efa5d1d4e5 100644
--- a/system-settings/plugins/keyfile/io/writer.c
+++ b/system-settings/plugins/keyfile/io/writer.c
@@ -34,7 +34,7 @@
#include
#include
#include
-#include
+#include
#include "nm-dbus-glib-types.h"
#include "writer.h"
@@ -437,14 +437,18 @@ write_connection (NMConnection *connection,
g_file_set_contents (path, data, len, error);
if (chown (path, owner_uid, owner_grp) < 0) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ g_set_error (error,
+ NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
"%s.%d: error chowning '%s': %d", __FILE__, __LINE__,
path, errno);
unlink (path);
} else {
err = chmod (path, S_IRUSR | S_IWUSR);
if (err) {
- g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR,
+ g_set_error (error,
+ NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
"%s.%d: error setting permissions on '%s': %d", __FILE__,
__LINE__, path, errno);
unlink (path);
diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c
index 9d9427b340..2b12da7591 100644
--- a/system-settings/plugins/keyfile/nm-keyfile-connection.c
+++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c
@@ -22,16 +22,22 @@
#include
#include
#include
-#include
#include
#include
+#include
#include "nm-dbus-glib-types.h"
#include "nm-keyfile-connection.h"
#include "reader.h"
#include "writer.h"
-G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION)
+static NMSettingsConnectionInterface *parent_settings_connection_iface;
+
+static void settings_connection_interface_init (NMSettingsConnectionInterface *klass);
+
+G_DEFINE_TYPE_EXTENDED (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ settings_connection_interface_init))
#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate))
@@ -65,50 +71,52 @@ nm_keyfile_connection_get_filename (NMKeyfileConnection *self)
}
static gboolean
-update (NMExportedConnection *exported,
- GHashTable *new_settings,
- GError **error)
+update (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceUpdateFunc callback,
+ gpointer user_data)
{
- NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (exported);
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
+ char *filename = NULL;
+ GError *error = NULL;
gboolean success;
- success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->update (exported, new_settings, error);
- if (success) {
- NMConnection *connection;
- char *filename = NULL;
-
- connection = nm_exported_connection_get_connection (exported);
- success = nm_connection_replace_settings (connection, new_settings, error);
- if (success) {
- success = write_connection (connection, KEYFILE_DIR, 0, 0, &filename, error);
- if (success && filename && strcmp (priv->filename, filename)) {
- /* Update the filename if it changed */
- g_free (priv->filename);
- priv->filename = filename;
- } else
- g_free (filename);
- }
+ success = write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &filename, &error);
+ if (success && filename && strcmp (priv->filename, filename)) {
+ /* Update the filename if it changed */
+ g_free (priv->filename);
+ priv->filename = filename;
+ success = parent_settings_connection_iface->update (connection, callback, user_data);
+ } else {
+ callback (connection, error, user_data);
+ g_error_free (error);
+ g_free (filename);
}
return success;
}
-static gboolean
-do_delete (NMExportedConnection *exported, GError **err)
+static gboolean
+do_delete (NMSettingsConnectionInterface *connection,
+ NMSettingsConnectionInterfaceDeleteFunc callback,
+ gpointer user_data)
{
- NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (exported);
- gboolean success;
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection);
- success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->do_delete (exported, err);
+ g_unlink (priv->filename);
- if (success)
- g_unlink (priv->filename);
-
- return success;
+ return parent_settings_connection_iface->delete (connection, callback, user_data);
}
/* GObject */
+static void
+settings_connection_interface_init (NMSettingsConnectionInterface *iface)
+{
+ parent_settings_connection_iface = g_type_interface_peek_parent (iface);
+ iface->update = update;
+ iface->delete = do_delete;
+}
+
static void
nm_keyfile_connection_init (NMKeyfileConnection *connection)
{
@@ -121,8 +129,9 @@ constructor (GType type,
{
GObject *object;
NMKeyfileConnectionPrivate *priv;
- NMConnection *wrapped;
NMSettingConnection *s_con;
+ NMConnection *tmp;
+ GHashTable *settings;
object = G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->constructor (type, n_construct_params, construct_params);
@@ -131,17 +140,21 @@ constructor (GType type,
priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
- if (!priv->filename) {
- g_warning ("Keyfile file name not provided.");
- goto err;
- }
+ g_assert (priv->filename);
- wrapped = connection_from_file (priv->filename);
- if (!wrapped)
- goto err;
+ tmp = connection_from_file (priv->filename);
+ if (!tmp) {
+ g_object_unref (object);
+ return NULL;
+ }
+
+ settings = nm_connection_to_hash (tmp);
+ nm_connection_replace_settings (NM_CONNECTION (object), settings, NULL);
+ g_hash_table_destroy (settings);
+ g_object_unref (tmp);
/* if for some reason the connection didn't have a UUID, add one */
- s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (object), NM_TYPE_SETTING_CONNECTION);
if (s_con && !nm_setting_connection_get_uuid (s_con)) {
GError *error = NULL;
char *uuid;
@@ -150,23 +163,16 @@ constructor (GType type,
g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL);
g_free (uuid);
- if (!write_connection (wrapped, KEYFILE_DIR, 0, 0, NULL, &error)) {
+ if (!write_connection (NM_CONNECTION (object), KEYFILE_DIR, 0, 0, NULL, &error)) {
g_warning ("Couldn't update connection %s with a UUID: (%d) %s",
- nm_setting_connection_get_id (s_con), error ? error->code : 0,
- error ? error->message : "unknown");
+ nm_setting_connection_get_id (s_con),
+ error ? error->code : 0,
+ (error && error->message) ? error->message : "unknown");
g_error_free (error);
}
}
- g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL);
- g_object_unref (wrapped);
-
return object;
-
- err:
- g_object_unref (object);
-
- return NULL;
}
static void
@@ -174,6 +180,8 @@ finalize (GObject *object)
{
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object);
+ nm_connection_clear_secrets (NM_CONNECTION (object));
+
g_free (priv->filename);
G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object);
@@ -216,7 +224,6 @@ static void
nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class);
- NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (keyfile_connection_class);
g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate));
@@ -226,9 +233,6 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c
object_class->get_property = get_property;
object_class->finalize = finalize;
- connection_class->update = update;
- connection_class->do_delete = do_delete;
-
/* Properties */
g_object_class_install_property
(object_class, PROP_FILENAME,
diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c
index f981f34e37..37908c5a78 100644
--- a/system-settings/plugins/keyfile/plugin.c
+++ b/system-settings/plugins/keyfile/plugin.c
@@ -112,15 +112,13 @@ find_by_uuid (gpointer key, gpointer data, gpointer user_data)
{
NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (data);
FindByUUIDInfo *info = user_data;
- NMConnection *connection;
NMSettingConnection *s_con;
const char *uuid;
if (info->found)
return;
- connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (keyfile));
- s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (keyfile), NM_TYPE_SETTING_CONNECTION);
uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL;
if (uuid && !strcmp (info->uuid, uuid))
@@ -128,17 +126,15 @@ find_by_uuid (gpointer key, gpointer data, gpointer user_data)
}
static void
-update_connection_settings (NMExportedConnection *orig,
- NMExportedConnection *new)
+update_connection_settings (NMConnection *orig,
+ NMConnection *new)
{
- NMConnection *wrapped;
GHashTable *new_settings;
GError *error = NULL;
- new_settings = nm_connection_to_hash (nm_exported_connection_get_connection (new));
- wrapped = nm_exported_connection_get_connection (orig);
- if (nm_connection_replace_settings (wrapped, new_settings, &error))
- nm_exported_connection_signal_updated (orig, new_settings);
+ new_settings = nm_connection_to_hash (new);
+ if (nm_connection_replace_settings (orig, new_settings, &error))
+ nm_settings_connection_interface_emit_updated (NM_SETTINGS_CONNECTION_INTERFACE (orig));
else {
g_warning ("%s: '%s' / '%s' invalid: %d",
__func__,
@@ -146,7 +142,7 @@ update_connection_settings (NMExportedConnection *orig,
(error && error->message) ? error->message : "(none)",
error ? error->code : -1);
g_clear_error (&error);
- nm_exported_connection_signal_removed (orig);
+ g_signal_emit_by_name (orig, "removed");
}
g_hash_table_destroy (new_settings);
@@ -175,7 +171,7 @@ dir_changed (GFileMonitor *monitor,
/* Removing from the hash table should drop the last reference */
g_object_ref (connection);
g_hash_table_remove (priv->hash, name);
- nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection));
+ g_signal_emit_by_name (connection, "removed");
g_object_unref (connection);
}
break;
@@ -183,18 +179,17 @@ dir_changed (GFileMonitor *monitor,
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
if (connection) {
/* Update */
- NMExportedConnection *tmp;
+ NMKeyfileConnection *tmp;
- tmp = (NMExportedConnection *) nm_keyfile_connection_new (name);
+ tmp = (NMKeyfileConnection *) nm_keyfile_connection_new (name);
if (tmp) {
- update_connection_settings (NM_EXPORTED_CONNECTION (connection), tmp);
+ update_connection_settings (NM_CONNECTION (connection), NM_CONNECTION (tmp));
g_object_unref (tmp);
}
} else {
/* New */
connection = nm_keyfile_connection_new (name);
if (connection) {
- NMConnection *tmp;
NMSettingConnection *s_con;
const char *connection_uuid;
NMKeyfileConnection *found = NULL;
@@ -202,8 +197,7 @@ dir_changed (GFileMonitor *monitor,
/* Connection renames will show up as different files but with
* the same UUID. Try to find the original connection.
*/
- tmp = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
- s_con = (NMSettingConnection *) nm_connection_get_setting (tmp, NM_TYPE_SETTING_CONNECTION);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
connection_uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL;
if (connection_uuid) {
@@ -228,8 +222,8 @@ dir_changed (GFileMonitor *monitor,
/* Updating settings should update the NMKeyfileConnection's
* filename property too.
*/
- update_connection_settings (NM_EXPORTED_CONNECTION (found),
- NM_EXPORTED_CONNECTION (connection));
+ update_connection_settings (NM_CONNECTION (found),
+ NM_CONNECTION (connection));
/* Re-insert the connection back into the hash with the new filename */
g_hash_table_insert (priv->hash,
@@ -242,7 +236,7 @@ dir_changed (GFileMonitor *monitor,
g_hash_table_insert (priv->hash,
(gpointer) nm_keyfile_connection_get_filename (connection),
connection);
- g_signal_emit_by_name (config, "connection-added", connection);
+ g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
}
}
}
@@ -269,7 +263,7 @@ conf_file_changed (GFileMonitor *monitor,
case G_FILE_MONITOR_EVENT_DELETED:
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
- g_signal_emit_by_name (self, "unmanaged-devices-changed");
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
/* hostname */
tmp = plugin_get_hostname (self);