diff options
author | Dan Williams <dcbw@redhat.com> | 2012-12-03 15:36:46 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2013-04-08 11:30:32 -0500 |
commit | a87b5a15df45d7974c942ffa6bc4a5453c269d4e (patch) | |
tree | 479f1f35a935717ce4125aee8faeee8e8596e6ad /libnm-glib | |
parent | 661d09852d9b572932a6229a4092be6ee670cfab (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.c | 128 | ||||
-rw-r--r-- | libnm-glib/nm-object-private.h | 2 | ||||
-rw-r--r-- | libnm-glib/nm-object.c | 14 | ||||
-rw-r--r-- | libnm-glib/nm-remote-connection.c | 11 | ||||
-rw-r--r-- | libnm-glib/nm-remote-settings.c | 111 | ||||
-rw-r--r-- | libnm-glib/nm-secret-agent.c | 49 |
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); |