summaryrefslogtreecommitdiff
path: root/libnm-glib
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-12-03 15:36:46 -0600
committerDan Williams <dcbw@redhat.com>2013-04-08 11:30:32 -0500
commita87b5a15df45d7974c942ffa6bc4a5453c269d4e (patch)
tree479f1f35a935717ce4125aee8faeee8e8596e6ad /libnm-glib
parent661d09852d9b572932a6229a4092be6ee670cfab (diff)
libnm-glib: use private connection before trying the system bus
Use the D-Bus connection helper whenever we need a connection to NM, which by default tries to use a private connection instead of the shared bus connection whenever the user is root. Doing this by default will not change the behavior of libnm-glib, and allows tools like nmcli and libnm-glib-using clients to work in minimal environments (those without a bus daemon) by default.
Diffstat (limited to 'libnm-glib')
-rw-r--r--libnm-glib/nm-client.c128
-rw-r--r--libnm-glib/nm-object-private.h2
-rw-r--r--libnm-glib/nm-object.c14
-rw-r--r--libnm-glib/nm-remote-connection.c11
-rw-r--r--libnm-glib/nm-remote-settings.c111
-rw-r--r--libnm-glib/nm-secret-agent.c49
6 files changed, 170 insertions, 145 deletions
diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c
index 5709e0901..5121457cd 100644
--- a/libnm-glib/nm-client.c
+++ b/libnm-glib/nm-client.c
@@ -1271,25 +1271,9 @@ client_device_removed (NMObject *client, NMObject *device)
NMClient *
nm_client_new (void)
{
- DBusGConnection *connection;
- GError *err = NULL;
NMClient *client;
-#ifdef LIBNM_GLIB_TEST
- connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
-#else
- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
-#endif
- if (!connection) {
- g_warning ("Couldn't connect to system bus: %s", err->message);
- g_error_free (err);
- return NULL;
- }
-
- client = g_object_new (NM_TYPE_CLIENT,
- NM_OBJECT_DBUS_CONNECTION, connection,
- NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
- NULL);
+ client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL);
_nm_object_ensure_inited (NM_OBJECT (client));
return client;
}
@@ -1323,32 +1307,15 @@ client_inited (GObject *source, GAsyncResult *result, gpointer user_data)
* #NMRemoteSettings object.
**/
void
-nm_client_new_async (GCancellable *cancellable, GAsyncReadyCallback callback,
+nm_client_new_async (GCancellable *cancellable,
+ GAsyncReadyCallback callback,
gpointer user_data)
{
- DBusGConnection *connection;
- GError *err = NULL;
NMClient *client;
GSimpleAsyncResult *simple;
simple = g_simple_async_result_new (NULL, callback, user_data, nm_client_new_async);
-
-#ifdef LIBNM_GLIB_TEST
- connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
-#else
- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
-#endif
- if (!connection) {
- g_simple_async_result_take_error (simple, err);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
- return;
- }
-
- client = g_object_new (NM_TYPE_CLIENT,
- NM_OBJECT_DBUS_CONNECTION, connection,
- NM_OBJECT_DBUS_PATH, NM_DBUS_PATH,
- NULL);
+ client = g_object_new (NM_TYPE_CLIENT, NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL);
g_async_initable_init_async (G_ASYNC_INITABLE (client), G_PRIORITY_DEFAULT,
cancellable, client_inited, simple);
}
@@ -1495,18 +1462,23 @@ constructed (GObject *object)
object,
NULL);
- priv->bus_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
-
- dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->bus_proxy,
- "NameOwnerChanged",
- G_CALLBACK (proxy_name_owner_changed),
- object, NULL);
+ if (_nm_object_is_connection_private (NM_OBJECT (object)))
+ priv->manager_running = TRUE;
+ else {
+ priv->bus_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ g_assert (priv->bus_proxy);
+
+ dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->bus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (proxy_name_owner_changed),
+ object, NULL);
+ }
g_signal_connect (object, "notify::" NM_CLIENT_WIRELESS_ENABLED,
G_CALLBACK (wireless_enabled_cb), NULL);
@@ -1527,13 +1499,15 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
if (!nm_client_parent_initable_iface->init (initable, cancellable, error))
return FALSE;
- if (!dbus_g_proxy_call (priv->bus_proxy,
- "NameHasOwner", error,
- G_TYPE_STRING, NM_DBUS_SERVICE,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &priv->manager_running,
- G_TYPE_INVALID))
- return FALSE;
+ if (!_nm_object_is_connection_private (NM_OBJECT (client))) {
+ if (!dbus_g_proxy_call (priv->bus_proxy,
+ "NameHasOwner", error,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &priv->manager_running,
+ G_TYPE_INVALID))
+ return FALSE;
+ }
if (priv->manager_running && !get_permissions_sync (client, error))
return FALSE;
@@ -1590,6 +1564,22 @@ init_async_got_properties (GObject *source, GAsyncResult *result, gpointer user_
}
static void
+finish_init (NMClientInitData *init_data)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (init_data->client);
+
+ nm_client_parent_async_initable_iface->init_async (G_ASYNC_INITABLE (init_data->client),
+ G_PRIORITY_DEFAULT, NULL, /* FIXME cancellable */
+ init_async_got_properties, init_data);
+ init_data->properties_pending = TRUE;
+
+ dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions",
+ init_async_got_permissions, init_data, NULL,
+ G_TYPE_INVALID);
+ init_data->permissions_pending = TRUE;
+}
+
+static void
init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
gpointer user_data)
{
@@ -1610,15 +1600,7 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
return;
}
- nm_client_parent_async_initable_iface->init_async (G_ASYNC_INITABLE (init_data->client),
- G_PRIORITY_DEFAULT, NULL, /* FIXME cancellable */
- init_async_got_properties, init_data);
- init_data->properties_pending = TRUE;
-
- dbus_g_proxy_begin_call (priv->client_proxy, "GetPermissions",
- init_async_got_permissions, init_data, NULL,
- G_TYPE_INVALID);
- init_data->permissions_pending = TRUE;
+ finish_init (init_data);
}
static void
@@ -1635,12 +1617,16 @@ init_async (GAsyncInitable *initable, int io_priority,
user_data, init_async);
g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
- /* Check if NM is running */
- dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
- init_async_got_manager_running,
- init_data, NULL,
- G_TYPE_STRING, NM_DBUS_SERVICE,
- G_TYPE_INVALID);
+ if (_nm_object_is_connection_private (NM_OBJECT (init_data->client)))
+ finish_init (init_data);
+ else {
+ /* Check if NM is running */
+ dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner",
+ init_async_got_manager_running,
+ init_data, NULL,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID);
+ }
}
static gboolean
diff --git a/libnm-glib/nm-object-private.h b/libnm-glib/nm-object-private.h
index 3c99f59e9..1658c1dce 100644
--- a/libnm-glib/nm-object-private.h
+++ b/libnm-glib/nm-object-private.h
@@ -43,6 +43,8 @@ DBusGProxy *_nm_object_new_proxy (NMObject *self,
const char *path,
const char *interface);
+gboolean _nm_object_is_connection_private (NMObject *self);
+
void _nm_object_register_properties (NMObject *object,
DBusGProxy *proxy,
const NMPropertiesInfo *info);
diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c
index b133fee72..aa3ce799e 100644
--- a/libnm-glib/nm-object.c
+++ b/libnm-glib/nm-object.c
@@ -259,15 +259,13 @@ set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
- DBusGConnection *connection;
switch (prop_id) {
case PROP_CONNECTION:
/* Construct only */
- connection = (DBusGConnection *) g_value_get_boxed (value);
- if (!connection)
- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
- priv->connection = dbus_g_connection_ref (connection);
+ priv->connection = g_value_dup_boxed (value);
+ if (!priv->connection)
+ priv->connection = _nm_dbus_new_connection (NULL);
break;
case PROP_PATH:
/* Construct only */
@@ -1459,3 +1457,9 @@ _nm_object_new_proxy (NMObject *self, const char *path, const char *interface)
return _nm_dbus_new_proxy_for_connection (priv->connection, path ? path : priv->path, interface);
}
+gboolean
+_nm_object_is_connection_private (NMObject *self)
+{
+ return _nm_dbus_is_connection_private (NM_OBJECT_GET_PRIVATE (self)->connection);
+}
+
diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c
index 4e2bd2439..4951b649b 100644
--- a/libnm-glib/nm-remote-connection.c
+++ b/libnm-glib/nm-remote-connection.c
@@ -512,8 +512,15 @@ set_property (GObject *object, guint prop_id,
case PROP_BUS:
case PROP_DBUS_CONNECTION:
/* Construct only */
- if (g_value_get_boxed (value))
- priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value));
+ /* priv->bus is set from either of two properties so that it (a) remains
+ * backwards compatible with the previous "bus" property, and that (b)
+ * it can be created just like an NMObject using the "dbus-connection",
+ * even though it's not a subclass of NMObject. So don't overwrite the
+ * a valid value that the other property set with NULL, if one of the
+ * properties isn't specified at construction time.
+ */
+ if (!priv->bus)
+ priv->bus = g_value_dup_boxed (value);
break;
case PROP_DBUS_PATH:
/* Don't need to do anything; see constructor(). */
diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c
index 0bfe15074..5c5ff24c1 100644
--- a/libnm-glib/nm-remote-settings.c
+++ b/libnm-glib/nm-remote-settings.c
@@ -32,6 +32,7 @@
#include "nm-object-private.h"
#include "nm-dbus-helpers-private.h"
#include "nm-glib-compat.h"
+#include "nm-object-private.h"
static void nm_remote_settings_initable_iface_init (GInitableIface *iface);
static void nm_remote_settings_async_initable_iface_init (GAsyncInitableIface *iface);
@@ -45,6 +46,7 @@ G_DEFINE_TYPE_WITH_CODE (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT,
typedef struct {
DBusGConnection *bus;
+ gboolean private_bus;
gboolean inited;
DBusGProxy *proxy;
@@ -876,24 +878,26 @@ constructed (GObject *object)
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_glib_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);
+ if (priv->private_bus == FALSE) {
+ /* D-Bus proxy for clearing connections on NameOwnerChanged */
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ g_assert (priv->dbus_proxy);
+
+ dbus_g_object_register_marshaller (_nm_glib_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);
+ }
priv->proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
NM_DBUS_PATH_SETTINGS,
@@ -940,20 +944,23 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
GHashTable *props;
- if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error,
- G_TYPE_STRING, NM_DBUS_SERVICE,
- G_TYPE_INVALID,
- G_TYPE_BOOLEAN, &priv->service_running,
- G_TYPE_INVALID)) {
- priv->service_running = FALSE;
- return FALSE;
- }
+ if (priv->private_bus == FALSE) {
+ if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", error,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, &priv->service_running,
+ G_TYPE_INVALID)) {
+ priv->service_running = FALSE;
+ return FALSE;
+ }
- /* If NM isn't running we'll grab properties from name_owner_changed()
- * when it starts.
- */
- if (!priv->service_running)
- return TRUE;
+ /* If NM isn't running we'll grab properties from name_owner_changed()
+ * when it starts.
+ */
+ if (!priv->service_running)
+ return TRUE;
+ } else
+ priv->service_running = TRUE;
/* Get properties */
if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error,
@@ -1024,6 +1031,17 @@ init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call,
}
static void
+init_get_properties (NMRemoteSettingsInitData *init_data)
+{
+ NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (init_data->settings);
+
+ dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
+ init_async_got_properties, init_data, NULL,
+ G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS,
+ G_TYPE_INVALID);
+}
+
+static void
init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
gpointer user_data)
{
@@ -1045,10 +1063,7 @@ init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call,
return;
}
- dbus_g_proxy_begin_call (priv->props_proxy, "GetAll",
- init_async_got_properties, init_data, NULL,
- G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS,
- G_TYPE_INVALID);
+ init_get_properties (init_data);
}
static void
@@ -1064,12 +1079,16 @@ init_async (GAsyncInitable *initable, int io_priority,
init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
user_data, init_async);
- /* Check if NM is running */
- dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner",
- init_async_got_manager_running,
- init_data, NULL,
- G_TYPE_STRING, NM_DBUS_SERVICE,
- G_TYPE_INVALID);
+ if (priv->private_bus)
+ init_get_properties (init_data);
+ else {
+ /* Check if NM is running */
+ dbus_g_proxy_begin_call (priv->dbus_proxy, "NameHasOwner",
+ init_async_got_manager_running,
+ init_data, NULL,
+ G_TYPE_STRING, NM_DBUS_SERVICE,
+ G_TYPE_INVALID);
+ }
}
static gboolean
@@ -1127,15 +1146,15 @@ set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
- DBusGConnection *connection;
switch (prop_id) {
case PROP_BUS:
/* Construct only */
- connection = (DBusGConnection *) g_value_get_boxed (value);
- if (!connection)
- connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
- priv->bus = dbus_g_connection_ref (connection);
+ priv->bus = g_value_dup_boxed (value);
+ if (!priv->bus) {
+ priv->bus = _nm_dbus_new_connection (NULL);
+ priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
+ }
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c
index b636263b7..400d04276 100644
--- a/libnm-glib/nm-secret-agent.c
+++ b/libnm-glib/nm-secret-agent.c
@@ -66,6 +66,7 @@ typedef struct {
gboolean registered;
DBusGConnection *bus;
+ gboolean private_bus;
DBusGProxy *dbus_proxy;
DBusGProxy *manager_proxy;
DBusGProxyCall *reg_call;
@@ -226,6 +227,12 @@ verify_sender (NMSecretAgent *self,
g_return_val_if_fail (context != NULL, FALSE);
+ /* Private bus connection is always to NetworkManager, which is always
+ * UID 0.
+ */
+ if (priv->private_bus)
+ return TRUE;
+
/* Verify the sender's UID is 0, and that the sender is the same as
* NetworkManager's bus name owner.
*/
@@ -796,34 +803,34 @@ nm_secret_agent_init (NMSecretAgent *self)
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
GError *error = NULL;
- priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ priv->bus = _nm_dbus_new_connection (&error);
if (!priv->bus) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free (error);
return;
}
-
- priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
- DBUS_SERVICE_DBUS,
- DBUS_PATH_DBUS,
- DBUS_INTERFACE_DBUS);
- if (!priv->dbus_proxy) {
- g_warning ("Couldn't create messagebus proxy.");
- return;
+ priv->private_bus = _nm_dbus_is_connection_private (priv->bus);
+
+ if (priv->private_bus == FALSE) {
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ g_assert (priv->dbus_proxy);
+
+ dbus_g_object_register_marshaller (_nm_glib_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),
+ self, NULL);
}
- dbus_g_object_register_marshaller (_nm_glib_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),
- self, NULL);
-
priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus,
NM_DBUS_PATH_AGENT_MANAGER,
NM_DBUS_INTERFACE_AGENT_MANAGER);