summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog54
-rw-r--r--Makefile.am3
-rw-r--r--configure.in9
-rw-r--r--introspection/nm-exported-connection.xml2
-rw-r--r--introspection/nm-settings-system.xml1
-rw-r--r--libnm-glib/nm-dbus-connection.c20
-rw-r--r--libnm-glib/nm-dbus-settings-system.c20
-rw-r--r--libnm-glib/nm-dbus-settings-system.h5
-rw-r--r--libnm-glib/nm-settings.c78
-rw-r--r--libnm-glib/nm-settings.h21
-rw-r--r--system-settings/plugins/ifcfg-suse/nm-suse-connection.c8
-rw-r--r--system-settings/plugins/ifcfg-suse/nm-suse-connection.h6
-rw-r--r--system-settings/plugins/keyfile/nm-keyfile-connection.c29
-rw-r--r--system-settings/plugins/keyfile/nm-keyfile-connection.h6
-rw-r--r--system-settings/plugins/keyfile/plugin.c3
-rw-r--r--system-settings/src/Makefile.am6
-rw-r--r--system-settings/src/dbus-settings.c34
-rw-r--r--system-settings/src/nm-polkit-helpers.c140
-rw-r--r--system-settings/src/nm-polkit-helpers.h30
-rw-r--r--system-settings/src/nm-sysconfig-connection.c86
-rw-r--r--system-settings/src/nm-sysconfig-connection.h29
21 files changed, 511 insertions, 79 deletions
diff --git a/ChangeLog b/ChangeLog
index b3f58b079c..3ecd40a3cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,60 @@
2008-05-08 Tambet Ingo <tambet@gmail.com>
+ Use PolicyKit to authorize the system settings' AddConnection method
+ and the system settings connections' Update and Delete methods.
+
+ * libnm-glib/nm-settings.c (impl_exported_connection_update)
+ (impl_exported_connection_delete, nm_exported_connection_update)
+ (nm_exported_connection_delete): Return boolean and fill GError
+ to notify the callers of the reasons why it might have failed.
+
+ * libnm-glib/nm-dbus-settings-system.c
+ (nm_dbus_settings_system_add_connection): Return the error from dbus
+ call so that the callers can see why it failed.
+
+ * libnm-glib/nm-dbus-connection.c (update, delete): Update the
+ signatures.
+
+ * system-settings/src/nm-polkit-helpers.[ch]: Implement.
+
+ * system-settings/src/nm-sysconfig-connection.[ch]: Implement. New
+ abstract base class that checks PolicyKit permissions.
+
+ * system-settings/src/dbus-settings.c:
+ (impl_settings_add_connection): Check the policy before carring out
+ the request.
+
+ * system-settings/plugins/keyfile/nm-keyfile-connection.c:
+ Inherit from NMSysconfigConnection, check the policies before
+ allowing updating or removing.
+
+ * system-settings/plugins/ifcfg-suse/nm-suse-connection.c:
+ Inherit from NMSysconfigConnection.
+
+ * introspection/nm-exported-connection.xml: Annotate "Update" and
+ "Delete" methods with async flag so that the implementations can get
+ access to DBusGMethodInvocation.
+
+ * system-settings/src/dbus-settings.c
+ (settings_add_connection_check_privileges): Implement.
+ (impl_settings_add_connection): Check the privileges before adding a new
+ connection. Improve error reporting.
+
+ * introspection/nm-settings-system.xml: Make the 'AddConnection' method
+ async so that the implementation can access DBusGMethodInvocation.
+
+ * configure.in: Check for PolicyKit.
+
+ * policy/org.freedesktop.network-manager-settings.system.policy:
+ New file.
+
+ * policy/Makefile.am: Install the policy file.
+
+ * configure.in: Add 'policy' subdir.
+
+2008-05-08 Tambet Ingo <tambet@gmail.com>
+
Rewrite the suse system settings plugin.
* system-settings/plugins/ifcfg-suse/plugin.c: Rewrite.
diff --git a/Makefile.am b/Makefile.am
index cd4d3e4650..89f24b7c87 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,8 @@ SUBDIRS = \
introspection \
callouts \
system-settings \
- tools
+ tools \
+ policy
EXTRA_DIST = \
CONTRIBUTING \
diff --git a/configure.in b/configure.in
index 95e430a268..f138e0256b 100644
--- a/configure.in
+++ b/configure.in
@@ -219,6 +219,14 @@ PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8)
AC_SUBST(LIBNL_CFLAGS)
AC_SUBST(LIBNL_LIBS)
+PKG_CHECK_MODULES(POLKIT, polkit-dbus)
+
+AC_CHECK_PROG([POLKIT_POLICY_FILE_VALIDATE],
+ [polkit-policy-file-validate], [polkit-policy-file-validate])
+if test -z "$POLKIT_POLICY_FILE_VALIDATE"; then
+ AC_MSG_ERROR([polkit-policy-file-validate not found])
+fi
+
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
@@ -331,6 +339,7 @@ man/Makefile
man/NetworkManager.8
man/nm-tool.1
po/Makefile.in
+policy/Makefile
NetworkManager.pc
])
AC_OUTPUT
diff --git a/introspection/nm-exported-connection.xml b/introspection/nm-exported-connection.xml
index 251ccafd40..d0a8a707fa 100644
--- a/introspection/nm-exported-connection.xml
+++ b/introspection/nm-exported-connection.xml
@@ -23,6 +23,7 @@
Update the connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_exported_connection_update"/>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="properties" type="a{sa{sv}}" direction="in">
<tp:docstring>
New connection properties.
@@ -35,6 +36,7 @@
Delete the connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_exported_connection_delete"/>
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="GetSettings">
diff --git a/introspection/nm-settings-system.xml b/introspection/nm-settings-system.xml
index a6e0e3b490..c7579714ef 100644
--- a/introspection/nm-settings-system.xml
+++ b/introspection/nm-settings-system.xml
@@ -11,6 +11,7 @@
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 properties.
diff --git a/libnm-glib/nm-dbus-connection.c b/libnm-glib/nm-dbus-connection.c
index 116bf557cf..ba649d9e08 100644
--- a/libnm-glib/nm-dbus-connection.c
+++ b/libnm-glib/nm-dbus-connection.c
@@ -69,28 +69,20 @@ get_secrets (NMExportedConnection *connection,
g_warning ("Implement me");
}
-static void
-update (NMExportedConnection *exported, GHashTable *new_settings)
+static gboolean
+update (NMExportedConnection *exported, GHashTable *new_settings, GError **err)
{
NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (exported);
- GError *err = NULL;
- if (!org_freedesktop_NetworkManagerSettings_Connection_update (priv->proxy, new_settings, &err)) {
- nm_warning ("Can not update dbus connection: %s", err->message);
- g_error_free (err);
- }
+ return org_freedesktop_NetworkManagerSettings_Connection_update (priv->proxy, new_settings, err);
}
-static void
-delete (NMExportedConnection *exported)
+static gboolean
+delete (NMExportedConnection *exported, GError **err)
{
NMDBusConnectionPrivate *priv = NM_DBUS_CONNECTION_GET_PRIVATE (exported);
- GError *err = NULL;
- if (!org_freedesktop_NetworkManagerSettings_Connection_delete (priv->proxy, &err)) {
- nm_warning ("Can not delete dbus connection: %s", err->message);
- g_error_free (err);
- }
+ return org_freedesktop_NetworkManagerSettings_Connection_delete (priv->proxy, err);
}
static void
diff --git a/libnm-glib/nm-dbus-settings-system.c b/libnm-glib/nm-dbus-settings-system.c
index e1bd037cc0..9c4fbb78cb 100644
--- a/libnm-glib/nm-dbus-settings-system.c
+++ b/libnm-glib/nm-dbus-settings-system.c
@@ -37,27 +37,25 @@ nm_dbus_settings_system_new (DBusGConnection *dbus_connection)
NULL);
}
-void
+gboolean
nm_dbus_settings_system_add_connection (NMDBusSettingsSystem *self,
- NMConnection *connection)
+ NMConnection *connection,
+ GError **err)
{
NMDBusSettingsSystemPrivate *priv;
GHashTable *settings;
- GError *err = NULL;
+ gboolean ret;
- g_return_if_fail (NM_IS_DBUS_SETTINGS_SYSTEM (self));
- g_return_if_fail (NM_IS_CONNECTION (connection));
+ 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);
- org_freedesktop_NetworkManagerSettings_System_add_connection (priv->settings_proxy, settings, &err);
- if (err) {
- g_warning ("Could not add system settings: %s", err->message);
- g_error_free (err);
- }
-
+ ret = org_freedesktop_NetworkManagerSettings_System_add_connection (priv->settings_proxy, settings, err);
g_hash_table_destroy (settings);
+
+ return ret;
}
static void
diff --git a/libnm-glib/nm-dbus-settings-system.h b/libnm-glib/nm-dbus-settings-system.h
index a378ad63cd..30146c6fb0 100644
--- a/libnm-glib/nm-dbus-settings-system.h
+++ b/libnm-glib/nm-dbus-settings-system.h
@@ -28,8 +28,9 @@ GType nm_dbus_settings_system_get_type (void);
NMDBusSettingsSystem *nm_dbus_settings_system_new (DBusGConnection *dbus_connection);
-void nm_dbus_settings_system_add_connection (NMDBusSettingsSystem *self,
- NMConnection *connection);
+gboolean nm_dbus_settings_system_add_connection (NMDBusSettingsSystem *self,
+ NMConnection *connection,
+ GError **err);
GSList *nm_dbus_settings_system_get_unmanaged_devices (NMDBusSettingsSystem *self);
diff --git a/libnm-glib/nm-settings.c b/libnm-glib/nm-settings.c
index c8e5a064fe..303f93cfc5 100644
--- a/libnm-glib/nm-settings.c
+++ b/libnm-glib/nm-settings.c
@@ -131,10 +131,10 @@ static gboolean impl_exported_connection_get_settings (NMExportedConnection *con
static gboolean impl_exported_connection_update (NMExportedConnection *connection,
GHashTable *new_settings,
- GError *err);
+ DBusGMethodInvocation *context);
static gboolean impl_exported_connection_delete (NMExportedConnection *connection,
- GError *err);
+ DBusGMethodInvocation *context);
static void impl_exported_connection_get_secrets (NMExportedConnection *connection,
const gchar *setting_name,
@@ -241,19 +241,46 @@ impl_exported_connection_get_settings (NMExportedConnection *connection,
static gboolean
impl_exported_connection_update (NMExportedConnection *connection,
GHashTable *new_settings,
- GError *err)
+ DBusGMethodInvocation *context)
{
- nm_exported_connection_update (connection, new_settings);
+ GError *err = NULL;
+ gboolean success;
+
+ /* 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_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 TRUE;
+ return success;
}
static gboolean
-impl_exported_connection_delete (NMExportedConnection *connection, GError *err)
+impl_exported_connection_delete (NMExportedConnection *connection,
+ DBusGMethodInvocation *context)
{
- nm_exported_connection_delete (connection);
+ GError *err = NULL;
+ gboolean success;
+
+ /* 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 TRUE;
+ return success;
}
static void
@@ -425,30 +452,41 @@ nm_exported_connection_register_object (NMExportedConnection *connection,
g_free (path);
}
-void
+gboolean
nm_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings)
+ GHashTable *new_settings,
+ GError **err)
{
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
- g_return_if_fail (new_settings != NULL);
+ gboolean success = TRUE;
- nm_connection_replace_settings (NM_EXPORTED_CONNECTION_GET_PRIVATE (connection)->wrapped, new_settings);
+ 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)
- EXPORTED_CONNECTION_CLASS (connection)->update (connection, new_settings);
+ success = EXPORTED_CONNECTION_CLASS (connection)->update (connection, new_settings, err);
- nm_exported_connection_signal_updated (connection, new_settings);
+ if (success) {
+ nm_connection_replace_settings (NM_EXPORTED_CONNECTION_GET_PRIVATE (connection)->wrapped, new_settings);
+ nm_exported_connection_signal_updated (connection, new_settings);
+ }
+
+ return success;
}
-void
-nm_exported_connection_delete (NMExportedConnection *connection)
+gboolean
+nm_exported_connection_delete (NMExportedConnection *connection, GError **err)
{
- g_return_if_fail (NM_IS_EXPORTED_CONNECTION (connection));
+ gboolean success = TRUE;
+
+ g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE);
if (EXPORTED_CONNECTION_CLASS (connection)->delete)
- EXPORTED_CONNECTION_CLASS (connection)->delete (connection);
+ success = EXPORTED_CONNECTION_CLASS (connection)->delete (connection, err);
+
+ if (success)
+ nm_exported_connection_signal_removed (connection);
- nm_exported_connection_signal_removed (connection);
+ return success;
}
void
diff --git a/libnm-glib/nm-settings.h b/libnm-glib/nm-settings.h
index 58d15f1365..35c5022848 100644
--- a/libnm-glib/nm-settings.h
+++ b/libnm-glib/nm-settings.h
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#ifndef __NM_SETTINGS_H__
#define __NM_SETTINGS_H__
@@ -21,6 +22,8 @@ GQuark nm_settings_error_quark (void);
#define NM_EXPORTED_CONNECTION_CONNECTION "connection"
+#define NM_EXPORTED_CONNECTION_DBUS_METHOD_INVOCATION "nm-exported-connection-dbus-method-invocation"
+
typedef struct {
GObject parent;
} NMExportedConnection;
@@ -37,10 +40,12 @@ typedef struct {
gboolean request_new,
DBusGMethodInvocation *context);
- void (*update) (NMExportedConnection *connection,
- GHashTable *new_settings);
+ gboolean (*update) (NMExportedConnection *connection,
+ GHashTable *new_settings,
+ GError **err);
- void (*delete) (NMExportedConnection *connection);
+ gboolean (*delete) (NMExportedConnection *connection,
+ GError **err);
/* signals */
void (* updated) (NMExportedConnection *connection, GHashTable *settings);
@@ -59,13 +64,15 @@ NMConnection *nm_exported_connection_get_connection (NMExportedConnection *conne
const char *nm_exported_connection_get_id (NMExportedConnection *connection);
-void nm_exported_connection_update (NMExportedConnection *connection,
- GHashTable *new_settings);
+gboolean nm_exported_connection_update (NMExportedConnection *connection,
+ GHashTable *new_settings,
+ GError **err);
-void nm_exported_connection_delete (NMExportedConnection *connection);
+gboolean nm_exported_connection_delete (NMExportedConnection *connection,
+ GError **err);
void nm_exported_connection_signal_updated (NMExportedConnection *connection,
- GHashTable *new_settings);
+ GHashTable *new_settings);
void nm_exported_connection_signal_removed (NMExportedConnection *connection);
diff --git a/system-settings/plugins/ifcfg-suse/nm-suse-connection.c b/system-settings/plugins/ifcfg-suse/nm-suse-connection.c
index 2f31e6e3bb..470a8a8e65 100644
--- a/system-settings/plugins/ifcfg-suse/nm-suse-connection.c
+++ b/system-settings/plugins/ifcfg-suse/nm-suse-connection.c
@@ -7,7 +7,7 @@
#include "nm-suse-connection.h"
#include "parser.h"
-G_DEFINE_TYPE (NMSuseConnection, nm_suse_connection, NM_TYPE_EXPORTED_CONNECTION)
+G_DEFINE_TYPE (NMSuseConnection, nm_suse_connection, NM_TYPE_SYSCONFIG_CONNECTION)
#define NM_SUSE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionPrivate))
@@ -37,14 +37,14 @@ file_changed (GFileMonitor *monitor,
new_connection = parse_ifcfg (priv->iface, priv->dev_type);
if (new_connection) {
new_settings = nm_connection_to_hash (new_connection);
- nm_exported_connection_update (exported, new_settings);
+ nm_exported_connection_update (exported, new_settings, NULL);
g_hash_table_destroy (new_settings);
g_object_unref (new_connection);
} else
- nm_exported_connection_delete (exported);
+ nm_exported_connection_delete (exported, NULL);
break;
case G_FILE_MONITOR_EVENT_DELETED:
- nm_exported_connection_delete (exported);
+ nm_exported_connection_delete (exported, NULL);
break;
default:
break;
diff --git a/system-settings/plugins/ifcfg-suse/nm-suse-connection.h b/system-settings/plugins/ifcfg-suse/nm-suse-connection.h
index 571ead62ba..75d5337b5c 100644
--- a/system-settings/plugins/ifcfg-suse/nm-suse-connection.h
+++ b/system-settings/plugins/ifcfg-suse/nm-suse-connection.h
@@ -4,7 +4,7 @@
#define NM_SUSE_CONNECTION_H
#include <NetworkManager.h>
-#include <nm-settings.h>
+#include <nm-sysconfig-connection.h>
G_BEGIN_DECLS
@@ -16,11 +16,11 @@ G_BEGIN_DECLS
#define NM_SUSE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUSE_CONNECTION, NMSuseConnectionClass))
typedef struct {
- NMExportedConnection parent;
+ NMSysconfigConnection parent;
} NMSuseConnection;
typedef struct {
- NMExportedConnectionClass parent;
+ NMSysconfigConnectionClass parent;
} NMSuseConnectionClass;
GType nm_suse_connection_get_type (void);
diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c
index d653874f41..b64f2c9146 100644
--- a/system-settings/plugins/keyfile/nm-keyfile-connection.c
+++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c
@@ -7,7 +7,7 @@
#include "reader.h"
#include "writer.h"
-G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_EXPORTED_CONNECTION)
+G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION)
#define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate))
@@ -52,18 +52,33 @@ get_id (NMExportedConnection *exported)
return NM_KEYFILE_CONNECTION_GET_PRIVATE (exported)->filename;
}
-static void
-update (NMExportedConnection *exported, GHashTable *new_settings)
+static gboolean
+update (NMExportedConnection *exported,
+ GHashTable *new_settings,
+ GError **err)
{
- write_connection (nm_exported_connection_get_connection (exported));
+ gboolean success;
+
+ success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->update (exported, new_settings, err);
+
+ if (success)
+ write_connection (nm_exported_connection_get_connection (exported));
+
+ return success;
}
-static void
-delete (NMExportedConnection *exported)
+static gboolean
+delete (NMExportedConnection *exported, GError **err)
{
NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (exported);
+ gboolean success;
+
+ success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (exported, err);
+
+ if (success)
+ g_unlink (priv->filename);
- g_unlink (priv->filename);
+ return success;
}
/* GObject */
diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.h b/system-settings/plugins/keyfile/nm-keyfile-connection.h
index bdd538c31f..28dfa96490 100644
--- a/system-settings/plugins/keyfile/nm-keyfile-connection.h
+++ b/system-settings/plugins/keyfile/nm-keyfile-connection.h
@@ -3,7 +3,7 @@
#ifndef NM_KEYFILE_CONNECTION_H
#define NM_KEYFILE_CONNECTION_H
-#include <nm-settings.h>
+#include <nm-sysconfig-connection.h>
G_BEGIN_DECLS
@@ -17,11 +17,11 @@ G_BEGIN_DECLS
#define NM_KEYFILE_CONNECTION_FILENAME "filename"
typedef struct {
- NMExportedConnection parent;
+ NMSysconfigConnection parent;
} NMKeyfileConnection;
typedef struct {
- NMExportedConnectionClass parent;
+ NMSysconfigConnectionClass parent;
} NMKeyfileConnectionClass;
GType nm_keyfile_connection_get_type (void);
diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c
index 5be931f73b..5320fb22b4 100644
--- a/system-settings/plugins/keyfile/plugin.c
+++ b/system-settings/plugins/keyfile/plugin.c
@@ -101,6 +101,7 @@ dir_changed (GFileMonitor *monitor,
nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection));
}
break;
+ case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
if (connection) {
/* Update */
@@ -111,7 +112,7 @@ dir_changed (GFileMonitor *monitor,
GHashTable *settings;
settings = nm_connection_to_hash (nm_exported_connection_get_connection (tmp));
- nm_exported_connection_update (NM_EXPORTED_CONNECTION (connection), settings);
+ nm_exported_connection_update (NM_EXPORTED_CONNECTION (connection), settings, NULL);
g_hash_table_destroy (settings);
g_object_unref (tmp);
}
diff --git a/system-settings/src/Makefile.am b/system-settings/src/Makefile.am
index 24e1b9ded8..0fbf652190 100644
--- a/system-settings/src/Makefile.am
+++ b/system-settings/src/Makefile.am
@@ -13,11 +13,15 @@ nm_system_settings_SOURCES = \
dbus-settings.c \
dbus-settings.h \
main.c \
+ nm-polkit-helpers.c \
+ nm-polkit-helpers.h \
nm-system-config-interface.c \
nm-system-config-interface.h \
nm-system-config-hal-manager.c \
nm-system-config-hal-manager.h \
nm-system-config-hal-manager-private.h \
+ nm-sysconfig-connection.c \
+ nm-sysconfig-connection.h \
sha1.c \
sha1.h
@@ -25,6 +29,7 @@ nm_system_settings_CPPFLAGS = \
$(DBUS_CFLAGS) \
$(GTHREAD_CFLAGS) \
$(GMODULE_CFLAGS) \
+ $(POLKIT_CFLAGS) \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \
@@ -40,6 +45,7 @@ nm_system_settings_LDADD = \
$(DBUS_LIBS) \
$(GTHREAD_LIBS) \
$(GMODULE_LIBS) \
+ $(POLKIT_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm_glib.la \
$(top_builddir)/marshallers/libmarshallers.la
diff --git a/system-settings/src/dbus-settings.c b/system-settings/src/dbus-settings.c
index 6e741feb4f..0dd84d974b 100644
--- a/system-settings/src/dbus-settings.c
+++ b/system-settings/src/dbus-settings.c
@@ -25,15 +25,15 @@
#include <nm-connection.h>
#include <dbus/dbus.h>
#include <string.h>
-
#include <nm-setting-connection.h>
#include "nm-dbus-glib-types.h"
#include "dbus-settings.h"
+#include "nm-polkit-helpers.h"
#include "nm-utils.h"
static gboolean
-impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, GError **err);
+impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, DBusGMethodInvocation *context);
#include "nm-settings-system-glue.h"
@@ -41,6 +41,7 @@ static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer
typedef struct {
DBusGConnection *g_connection;
+ PolKitContext *pol_ctx;
NMSystemConfigHalManager *hal_mgr;
GSList *plugins;
@@ -126,6 +127,9 @@ settings_finalize (GObject *object)
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
g_slist_free (priv->plugins);
+ if (priv->pol_ctx)
+ polkit_context_unref (priv->pol_ctx);
+
g_object_unref (priv->hal_mgr);
dbus_g_connection_unref (priv->g_connection);
@@ -218,7 +222,7 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class);
- g_type_class_add_private (settings_class, sizeof (NMSysconfigSettingsPrivate));
+ g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate));
/* virtual methods */
object_class->notify = notify;
@@ -247,6 +251,8 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class),
&dbus_glib_nm_settings_system_object_info);
+
+ dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NULL, NM_TYPE_SYSCONFIG_SETTINGS_ERROR);
}
static void
@@ -256,6 +262,8 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self)
priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL);
priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ priv->pol_ctx = create_polkit_context ();
}
NMSysconfigSettings *
@@ -404,13 +412,22 @@ nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *self,
}
static gboolean
-impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, GError **err)
+impl_settings_add_connection (NMSysconfigSettings *self,
+ GHashTable *hash,
+ DBusGMethodInvocation *context)
{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
NMConnection *connection;
+ GError *err = NULL;
+
+ if (!check_polkit_privileges (priv->g_connection, priv->pol_ctx, context, &err)) {
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
+ return FALSE;
+ }
connection = nm_connection_new_from_hash (hash);
if (connection) {
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
/* Here's how it works:
@@ -429,10 +446,15 @@ impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, GErro
nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), connection);
g_object_unref (connection);
+ dbus_g_method_return (context);
return TRUE;
} else {
/* Invalid connection hash */
- /* FIXME: Set error */
+ err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION,
+ "%s", "Invalid connection");
+ dbus_g_method_return_error (context, err);
+ g_error_free (err);
return FALSE;
}
}
diff --git a/system-settings/src/nm-polkit-helpers.c b/system-settings/src/nm-polkit-helpers.c
new file mode 100644
index 0000000000..2a2382886f
--- /dev/null
+++ b/system-settings/src/nm-polkit-helpers.c
@@ -0,0 +1,140 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include "nm-polkit-helpers.h"
+#include <nm-dbus-settings.h>
+
+GQuark
+nm_sysconfig_settings_error_quark (void)
+{
+ static GQuark ret = 0;
+
+ if (ret == 0)
+ ret = g_quark_from_static_string ("nm_sysconfig_settings_error");
+
+ return ret;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_sysconfig_settings_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"),
+ ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"),
+ ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("NMSysconfigSettingsError", values);
+ }
+
+ return etype;
+}
+
+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 (void)
+{
+ PolKitContext *pol_ctx;
+ PolKitError *err = NULL;
+
+ pol_ctx = polkit_context_new ();
+ polkit_context_set_io_watch_functions (pol_ctx, pk_io_add_watch, pk_io_remove_watch);
+ if (!polkit_context_init (pol_ctx, &err)) {
+ g_warning ("Cannot initialize libpolkit: %s", polkit_error_get_error_message (err));
+ polkit_error_free (err);
+
+ polkit_context_unref (pol_ctx);
+ pol_ctx = NULL;
+ }
+
+ return pol_ctx;
+}
+
+gboolean
+check_polkit_privileges (DBusGConnection *dbus_connection,
+ PolKitContext *pol_ctx,
+ DBusGMethodInvocation *context,
+ GError **err)
+{
+ DBusError dbus_error;
+ const char *sender;
+ PolKitCaller *pk_caller;
+ PolKitAction *pk_action;
+ PolKitResult pk_result;
+
+ dbus_error_init (&dbus_error);
+ sender = dbus_g_method_get_sender (context);
+ pk_caller = polkit_caller_new_from_dbus_name (dbus_g_connection_get_connection (dbus_connection),
+ sender,
+ &dbus_error);
+ if (!pk_caller) {
+ *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);
+ polkit_caller_unref (pk_caller);
+
+ return FALSE;
+ }
+
+ pk_action = polkit_action_new ();
+ polkit_action_set_action_id (pk_action, NM_SYSCONFIG_POLICY_ACTION);
+
+ pk_result = polkit_context_is_caller_authorized (pol_ctx, pk_action, pk_caller, TRUE, NULL);
+ polkit_caller_unref (pk_caller);
+ polkit_action_unref (pk_action);
+
+ if (pk_result != POLKIT_RESULT_YES) {
+ *err = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ "%s %s",
+ NM_SYSCONFIG_POLICY_ACTION,
+ polkit_result_to_string_representation (pk_result));
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/system-settings/src/nm-polkit-helpers.h b/system-settings/src/nm-polkit-helpers.h
new file mode 100644
index 0000000000..6b200aceae
--- /dev/null
+++ b/system-settings/src/nm-polkit-helpers.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#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>
+
+#define NM_SYSCONFIG_POLICY_ACTION "org.freedesktop.network-manager-settings.system.modify"
+
+enum {
+ NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0,
+ NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED,
+ NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION
+};
+
+#define NM_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_quark ())
+#define NM_TYPE_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_get_type ())
+
+GQuark nm_sysconfig_settings_error_quark (void);
+GType nm_sysconfig_settings_error_get_type (void);
+
+PolKitContext *create_polkit_context (void);
+gboolean check_polkit_privileges (DBusGConnection *dbus_connection,
+ PolKitContext *pol_ctx,
+ DBusGMethodInvocation *context,
+ GError **err);
+
+#endif /* NM_POLKIT_HELPERS_H */
diff --git a/system-settings/src/nm-sysconfig-connection.c b/system-settings/src/nm-sysconfig-connection.c
new file mode 100644
index 0000000000..4c1626cf35
--- /dev/null
+++ b/system-settings/src/nm-sysconfig-connection.c
@@ -0,0 +1,86 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <NetworkManager.h>
+#include "nm-sysconfig-connection.h"
+#include "nm-polkit-helpers.h"
+
+G_DEFINE_ABSTRACT_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION)
+
+#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;
+} NMSysconfigConnectionPrivate;
+
+static gboolean
+update (NMExportedConnection *exported,
+ GHashTable *new_settings,
+ GError **err)
+{
+ 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);
+}
+
+static gboolean
+delete (NMExportedConnection *exported, GError **err)
+{
+ 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);
+}
+
+/* GObject */
+
+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 ("Could not get DBus connection: %s", err->message);
+ g_error_free (err);
+ }
+
+ priv->pol_ctx = create_polkit_context ();
+}
+
+static void
+finalize (GObject *object)
+{
+ NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object);
+
+ if (priv->pol_ctx)
+ polkit_context_unref (priv->pol_ctx);
+
+ if (priv->dbus_connection)
+ dbus_g_connection_unref (priv->dbus_connection);
+
+ G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->finalize (object);
+}
+
+static void
+nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *sysconfig_connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (sysconfig_connection_class);
+ NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (sysconfig_connection_class);
+
+ g_type_class_add_private (sysconfig_connection_class, sizeof (NMSysconfigConnectionPrivate));
+
+ /* Virtual methods */
+ object_class->finalize = finalize;
+
+ connection_class->update = update;
+ connection_class->delete = delete;
+}
diff --git a/system-settings/src/nm-sysconfig-connection.h b/system-settings/src/nm-sysconfig-connection.h
new file mode 100644
index 0000000000..8526460f86
--- /dev/null
+++ b/system-settings/src/nm-sysconfig-connection.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef NM_SYSCONFIG_CONNECTION_H
+#define NM_SYSCONFIG_CONNECTION_H
+
+#include <nm-settings.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SYSCONFIG_CONNECTION (nm_sysconfig_connection_get_type ())
+#define NM_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnection))
+#define NM_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass))
+#define NM_IS_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION))
+#define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION))
+#define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass))
+
+typedef struct {
+ NMExportedConnection parent;
+} NMSysconfigConnection;
+
+typedef struct {
+ NMExportedConnectionClass parent;
+} NMSysconfigConnectionClass;
+
+GType nm_sysconfig_connection_get_type (void);
+
+G_END_DECLS
+
+#endif /* NM_SYSCONFIG_CONNECTION_H */