mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-14 20:18:39 +00:00
libnm-glib: implement new settings interfaces
The old NMExportedConnection was used for both client and server-side classes, which was a mistake and made the code very complicated to follow. Additionally, all PolicyKit operations were synchronous, and PK operations can block for a long time (ie for user input) before returning, so they need to be async. But NMExportedConnection and NMSysconfigConnection didn't allow for async PK ops at all. Use this opportunity to clean up the mess and create GInterfaces that both server and client objects implement, so that the connection editor and applet can operate on generic objects like they did before (using the interfaces) but can perform specific operations (like async PK verification of callers) depending on whether they are local or remote or whatever.
This commit is contained in:
parent
8f0652a9f0
commit
0d69dfe39e
34
configure.ac
34
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
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<method name="AddConnection">
|
||||
<tp:docstring>
|
||||
Add new connection.
|
||||
DEPRECATED. Adds new connection.
|
||||
</tp:docstring>
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
|
|
|
@ -18,9 +18,22 @@
|
|||
</arg>
|
||||
</method>
|
||||
|
||||
<method name="AddConnection">
|
||||
<tp:docstring>
|
||||
Add new connection.
|
||||
</tp:docstring>
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="connection" type="a{sa{sv}}" direction="in">
|
||||
<tp:docstring>
|
||||
Connection settings and properties.
|
||||
</tp:docstring>
|
||||
</arg>
|
||||
</method>
|
||||
|
||||
<signal name="NewConnection">
|
||||
<tp:docstring>
|
||||
Emitted when a new connection has been configured.
|
||||
Emitted when a new connection has been added.
|
||||
</tp:docstring>
|
||||
<arg name="connection" type="o">
|
||||
<tp:docstring>
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <string.h>
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-dbus-glib-types.h>
|
||||
#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));
|
||||
}
|
|
@ -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 <dbus/dbus-glib.h>
|
||||
#include <nm-settings.h>
|
||||
|
||||
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 */
|
|
@ -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 <NetworkManager.h>
|
||||
#include <nm-dbus-glib-types.h>
|
||||
#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));
|
||||
}
|
||||
|
|
@ -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 <nm-dbus-settings.h>
|
||||
|
||||
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 */
|
|
@ -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 <string.h>
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-connection.h>
|
||||
|
||||
#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));
|
||||
}
|
|
@ -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 <dbus/dbus-glib.h>
|
||||
#include <nm-connection.h>
|
||||
#include <nm-settings.h>
|
||||
#include <nm-dbus-connection.h>
|
||||
|
||||
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 */
|
306
libnm-glib/nm-exported-connection.c
Normal file
306
libnm-glib/nm-exported-connection.c
Normal file
|
@ -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 <NetworkManager.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
#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);
|
||||
}
|
71
libnm-glib/nm-exported-connection.h
Normal file
71
libnm-glib/nm-exported-connection.h
Normal file
|
@ -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 <nm-connection.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
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 */
|
419
libnm-glib/nm-remote-connection.c
Normal file
419
libnm-glib/nm-remote-connection.c
Normal file
|
@ -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 <string.h>
|
||||
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-utils.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#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));
|
||||
}
|
||||
|
57
libnm-glib/nm-remote-connection.h
Normal file
57
libnm-glib/nm-remote-connection.h
Normal file
|
@ -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 <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include <nm-connection.h>
|
||||
|
||||
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__ */
|
||||
|
259
libnm-glib/nm-remote-settings-system.c
Normal file
259
libnm-glib/nm-remote-settings-system.c
Normal file
|
@ -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 <string.h>
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-connection.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
55
libnm-glib/nm-remote-settings-system.h
Normal file
55
libnm-glib/nm-remote-settings-system.h
Normal file
|
@ -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 <glib.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#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 */
|
425
libnm-glib/nm-remote-settings.c
Normal file
425
libnm-glib/nm-remote-settings.c
Normal file
|
@ -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 <string.h>
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-connection.h>
|
||||
|
||||
#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));
|
||||
}
|
||||
|
58
libnm-glib/nm-remote-settings.h
Normal file
58
libnm-glib/nm-remote-settings.h
Normal file
|
@ -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 <glib.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <nm-connection.h>
|
||||
#include <nm-remote-connection.h>
|
||||
|
||||
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 */
|
210
libnm-glib/nm-settings-connection-interface.c
Normal file
210
libnm-glib/nm-settings-connection-interface.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
116
libnm-glib/nm-settings-connection-interface.h
Normal file
116
libnm-glib/nm-settings-connection-interface.h
Normal file
|
@ -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 <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include <nm-connection.h>
|
||||
|
||||
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__ */
|
||||
|
195
libnm-glib/nm-settings-interface.c
Normal file
195
libnm-glib/nm-settings-interface.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
93
libnm-glib/nm-settings-interface.h
Normal file
93
libnm-glib/nm-settings-interface.h
Normal file
|
@ -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 <glib-object.h>
|
||||
|
||||
#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 */
|
287
libnm-glib/nm-settings-service.c
Normal file
287
libnm-glib/nm-settings-service.c
Normal file
|
@ -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 <NetworkManager.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
#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);
|
||||
}
|
71
libnm-glib/nm-settings-service.h
Normal file
71
libnm-glib/nm-settings-service.h
Normal file
|
@ -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 <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
#include <nm-exported-connection.h>
|
||||
#include <nm-settings-interface.h>
|
||||
|
||||
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 */
|
114
libnm-glib/nm-settings-system-interface.c
Normal file
114
libnm-glib/nm-settings-system-interface.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
69
libnm-glib/nm-settings-system-interface.h
Normal file
69
libnm-glib/nm-settings-system-interface.h
Normal file
|
@ -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 <glib-object.h>
|
||||
|
||||
#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 */
|
|
@ -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 <NetworkManager.h>
|
||||
#include <nm-utils.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#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 #NMExportedConnection<!-- -->s
|
||||
**/
|
||||
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);
|
||||
}
|
|
@ -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 <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include <nm-connection.h>
|
||||
|
||||
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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <glib/gi18n.h>
|
||||
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-settings.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-setting-wired.h>
|
||||
#include <nm-utils.h>
|
||||
|
@ -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",
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#ifndef NM_DEFAULT_WIRED_CONNECTION_H
|
||||
#define NM_DEFAULT_WIRED_CONNECTION_H
|
||||
|
||||
#include <nm-settings.h>
|
||||
#include "nm-sysconfig-connection.h"
|
||||
#include "nm-device.h"
|
||||
|
||||
|
|
|
@ -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 <nm-dbus-settings.h>
|
||||
#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;
|
||||
}
|
|
@ -22,16 +22,8 @@
|
|||
#ifndef NM_POLKIT_HELPERS_H
|
||||
#define NM_POLKIT_HELPERS_H
|
||||
|
||||
#include <polkit-dbus/polkit-dbus.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
#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 */
|
||||
|
|
|
@ -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 <NetworkManager.h>
|
||||
#include <dbus/dbus-glib-lowlevel.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#ifndef NM_SYSCONFIG_CONNECTION_H
|
||||
#define NM_SYSCONFIG_CONNECTION_H
|
||||
|
||||
#include <nm-settings.h>
|
||||
#include <nm-connection.h>
|
||||
#include <nm-exported-connection.h>
|
||||
|
||||
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 */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,15 +27,11 @@
|
|||
#define __NM_SYSCONFIG_SETTINGS_H__
|
||||
|
||||
#include <nm-connection.h>
|
||||
#include <nm-settings.h>
|
||||
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <nm-connection.h>
|
||||
#include <nm-settings.h>
|
||||
#include <nm-settings-connection-interface.h>
|
||||
|
||||
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);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <nm-setting-pppoe.h>
|
||||
#include <nm-setting-wireless-security.h>
|
||||
#include <nm-setting-8021x.h>
|
||||
#include <nm-settings-connection-interface.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <nm-settings.h>
|
||||
#include <nm-settings-interface.h>
|
||||
|
||||
#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);
|
||||
|
|
|
@ -22,16 +22,22 @@
|
|||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <NetworkManager.h>
|
||||
#include <nm-settings.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-utils.h>
|
||||
#include <nm-settings-connection-interface.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue