From 110a40358d26fa05604c59ecc1584635e40347b6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 5 Mar 2013 09:16:47 -0600 Subject: [PATCH] libnm-glib: never call NM D-Bus methods if NM isn't running Though the client shouldn't be calling anything when NM isn't running (because clients have nm_client_get_manager_running()), make sure that NMClient never calls a NetworkManager method when NM isn't on the bus. Next, ensure NMObject doesn't try to refresh properties when NM isn't running. Creating an NMClient may trigger a property refresh request, but if NM isn't running, defer that until NM starts, to ensure that we don't D-Bus autostart NM. Third, ensure NMRemoteSettings doesn't attempt to list connections unless NM is running. This prevents service activation of NetworkManager in lieu of dbus-glib learning about DBUS_HEADER_FLAG_NO_AUTO_START. --- libnm-glib/libnm-glib.ver | 2 + libnm-glib/nm-client.c | 142 ++++++++++++++++++++++++-------- libnm-glib/nm-client.h | 16 ++++ libnm-glib/nm-object.c | 133 +++++++++++++++++++++++++++--- libnm-glib/nm-remote-settings.c | 101 ++++++++++------------- libnm-glib/nm-secret-agent.c | 11 ++- 6 files changed, 296 insertions(+), 109 deletions(-) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index e17e368f75..1848171e6e 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -32,6 +32,8 @@ global: nm_client_activate_connection; nm_client_add_and_activate_connection; nm_client_deactivate_connection; + nm_client_error_get_type; + nm_client_error_quark; nm_client_get_active_connections; nm_client_get_device_by_iface; nm_client_get_device_by_path; diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index b42eaecd4a..4f7d1ed692 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -116,6 +116,29 @@ static void proxy_name_owner_changed (DBusGProxy *proxy, static void client_device_added (NMObject *client, NMObject *device); static void client_device_removed (NMObject *client, NMObject *device); +/**********************************************************************/ + +/** + * nm_client_error_quark: + * + * Registers an error quark for #NMClient if necessary. + * + * Returns: the error quark used for #NMClient errors. + * + * Since: 0.9.10 + **/ +GQuark +nm_client_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-client-error-quark"); + return quark; +} + +/**********************************************************************/ + static void nm_client_init (NMClient *client) { @@ -427,12 +450,15 @@ typedef struct { NMClientAddActivateFn add_act_fn; char *active_path; char *new_connection_path; + guint idle_id; gpointer user_data; } ActivateInfo; static void activate_info_free (ActivateInfo *info) { + if (info->idle_id) + g_source_remove (info->idle_id); g_free (info->active_path); g_free (info->new_connection_path); memset (info, 0, sizeof (*info)); @@ -535,6 +561,23 @@ activate_cb (DBusGProxy *proxy, } } +static gboolean +activate_nm_not_running (gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error; + + info->idle_id = 0; + + error = g_error_new_literal (NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); + activate_info_complete (info, NULL, error); + activate_info_free (info); + g_clear_error (&error); + return FALSE; +} + /** * nm_client_activate_connection: * @client: a #NMClient @@ -582,6 +625,11 @@ nm_client_activate_connection (NMClient *client, priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + if (priv->manager_running == FALSE) { + info->idle_id = g_idle_add (activate_nm_not_running, info); + return; + } + dbus_g_proxy_begin_call (priv->client_proxy, "ActivateConnection", activate_cb, info, NULL, DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), @@ -664,12 +712,16 @@ nm_client_add_and_activate_connection (NMClient *client, priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); - dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection", - add_activate_cb, info, NULL, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, - DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)), - DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", - G_TYPE_INVALID); + if (priv->manager_running) { + dbus_g_proxy_begin_call (priv->client_proxy, "AddAndActivateConnection", + add_activate_cb, info, NULL, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_object_get_path (NM_OBJECT (device)), + DBUS_TYPE_G_OBJECT_PATH, specific_object ? specific_object : "/", + G_TYPE_INVALID); + } else + info->idle_id = g_idle_add (activate_nm_not_running, info); + g_hash_table_unref (hash); } @@ -703,8 +755,10 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); - // FIXME: return errors priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) + return; + path = nm_object_get_path (NM_OBJECT (active)); if (!dbus_g_proxy_call (priv->client_proxy, "DeactivateConnection", &error, DBUS_TYPE_G_OBJECT_PATH, path, @@ -772,13 +826,16 @@ nm_client_wireless_set_enabled (NMClient *client, gboolean enabled) g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); _nm_object_set_property (NM_OBJECT (client), - NM_DBUS_INTERFACE, - "WirelessEnabled", - &value); + NM_DBUS_INTERFACE, + "WirelessEnabled", + &value); } /** @@ -829,6 +886,9 @@ nm_client_wwan_set_enabled (NMClient *client, gboolean enabled) g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); @@ -886,6 +946,9 @@ nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + g_value_init (&value, G_TYPE_BOOLEAN); g_value_set_boolean (&value, enabled); @@ -985,6 +1048,9 @@ nm_client_networking_set_enabled (NMClient *client, gboolean enable) g_return_if_fail (NM_IS_CLIENT (client)); + if (!NM_CLIENT_GET_PRIVATE (client)->manager_running) + return; + if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "Enable", &err, G_TYPE_BOOLEAN, enable, G_TYPE_INVALID, @@ -1062,28 +1128,30 @@ nm_client_get_permission_result (NMClient *client, NMClientPermission permission gboolean nm_client_get_logging (NMClient *client, char **level, char **domains, GError **error) { - GError *err = NULL; + NMClientPrivate *priv; g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (level == NULL || *level == NULL, FALSE); g_return_val_if_fail (domains == NULL || *domains == NULL, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!level && !domains) - return TRUE; - - if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "GetLogging", &err, - G_TYPE_INVALID, - G_TYPE_STRING, level, - G_TYPE_STRING, domains, - G_TYPE_INVALID)) { - if (error) - *error = g_error_copy (err); - g_error_free (err); + priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); return FALSE; } - return TRUE; + if (!level && !domains) + return TRUE; + + return dbus_g_proxy_call (priv->client_proxy, "GetLogging", error, + G_TYPE_INVALID, + G_TYPE_STRING, level, + G_TYPE_STRING, domains, + G_TYPE_INVALID); } /** @@ -1103,26 +1171,28 @@ nm_client_get_logging (NMClient *client, char **level, char **domains, GError ** gboolean nm_client_set_logging (NMClient *client, const char *level, const char *domains, GError **error) { - GError *err = NULL; + NMClientPrivate *priv; g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (!level && !domains) - return TRUE; - - if (!dbus_g_proxy_call (NM_CLIENT_GET_PRIVATE (client)->client_proxy, "SetLogging", &err, - G_TYPE_STRING, level ? level : "", - G_TYPE_STRING, domains ? domains : "", - G_TYPE_INVALID, - G_TYPE_INVALID)) { - if (error) - *error = g_error_copy (err); - g_error_free (err); + priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) { + g_set_error_literal (error, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); return FALSE; } - return TRUE; + if (!level && !domains) + return TRUE; + + return dbus_g_proxy_call (priv->client_proxy, "SetLogging", error, + G_TYPE_STRING, level ? level : "", + G_TYPE_STRING, domains ? domains : "", + G_TYPE_INVALID, + G_TYPE_INVALID); } /****************************************************************/ diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 6c83e4cebe..96c7d9866e 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -120,6 +120,22 @@ typedef enum { NM_CLIENT_PERMISSION_RESULT_NO } NMClientPermissionResult; +/** + * NMClientError: + * @NM_CLIENT_ERROR_UNKNOWN: unknown or unclassified error + * @NM_CLIENT_ERROR_CONNECTION_REMOVED: an operation that requires NetworkManager + * failed because NetworkManager is not running + * + * Describes errors that may result from operations involving a #NMClient. + * + **/ +typedef enum { + NM_CLIENT_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/ + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, /*< nick=ManagerNotRunning >*/ +} NMClientError; + +#define NM_CLIENT_ERROR nm_client_error_quark () +GQuark nm_client_error_quark (void); typedef struct { NMObject parent; diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index aa3ce799e8..70d6144b47 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -70,6 +70,9 @@ typedef struct { typedef struct { DBusGConnection *connection; + DBusGProxy *bus_proxy; + gboolean nm_running; + char *path; DBusGProxy *properties_proxy; GSList *property_interfaces; @@ -120,6 +123,27 @@ nm_object_error_quark (void) return quark; } +static void +proxy_name_owner_changed (DBusGProxy *proxy, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMObject *self = NM_OBJECT (user_data); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); + + if (g_strcmp0 (name, NM_DBUS_SERVICE) == 0) { + gboolean old_good = (old_owner && old_owner[0]); + gboolean new_good = (new_owner && new_owner[0]); + + if (!old_good && new_good) + priv->nm_running = TRUE; + else if (old_good && !new_good) + priv->nm_running = FALSE; + } +} + static void nm_object_init (NMObject *object) { @@ -153,14 +177,31 @@ constructor (GType type, static void constructed (GObject *object) { + NMObject *self = NM_OBJECT (object); NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); if (G_OBJECT_CLASS (nm_object_parent_class)->constructed) G_OBJECT_CLASS (nm_object_parent_class)->constructed (object); - priv->properties_proxy = _nm_object_new_proxy (NM_OBJECT (object), - NULL, - "org.freedesktop.DBus.Properties"); + priv->properties_proxy = _nm_object_new_proxy (self, NULL, "org.freedesktop.DBus.Properties"); + + if (_nm_object_is_connection_private (self)) + priv->nm_running = TRUE; + else { + priv->bus_proxy = dbus_g_proxy_new_for_name (priv->connection, + 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); + } } static gboolean @@ -168,25 +209,70 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable); + if (priv->bus_proxy) { + if (!dbus_g_proxy_call (priv->bus_proxy, + "NameHasOwner", error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &priv->nm_running, + G_TYPE_INVALID)) + return FALSE; + } + priv->inited = TRUE; return _nm_object_reload_properties (NM_OBJECT (initable), error); } +/* Takes ownership of @error */ +static void +init_async_complete (GSimpleAsyncResult *simple, GError *error) +{ + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + static void init_async_got_properties (GObject *object, GAsyncResult *result, gpointer user_data) { - NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); GSimpleAsyncResult *simple = user_data; GError *error = NULL; - priv->inited = TRUE; - if (_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - else - g_simple_async_result_take_error (simple, error); + NM_OBJECT_GET_PRIVATE (object)->inited = TRUE; + if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) + g_assert (error); + init_async_complete (simple, error); +} - g_simple_async_result_complete (simple); - g_object_unref (simple); +static void +init_async_got_manager_running (DBusGProxy *proxy, DBusGProxyCall *call, + gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + NMObject *self; + NMObjectPrivate *priv; + GError *error = NULL; + + self = NM_OBJECT (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + priv = NM_OBJECT_GET_PRIVATE (self); + + if (!dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_BOOLEAN, &priv->nm_running, + G_TYPE_INVALID)) { + init_async_complete (simple, error); + return; + } + + if (!priv->nm_running) { + priv->inited = TRUE; + init_async_complete (simple, NULL); + return; + } + + _nm_object_reload_properties_async (self, init_async_got_properties, simple); } static void @@ -194,10 +280,21 @@ init_async (GAsyncInitable *initable, int io_priority, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (initable); GSimpleAsyncResult *simple; simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async); - _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple); + + if (_nm_object_is_connection_private (NM_OBJECT (initable))) + _nm_object_reload_properties_async (NM_OBJECT (initable), init_async_got_properties, simple); + else { + /* Check if NM is running */ + dbus_g_proxy_begin_call (priv->bus_proxy, "NameHasOwner", + init_async_got_manager_running, + simple, NULL, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID); + } } static gboolean @@ -230,6 +327,7 @@ dispose (GObject *object) priv->property_interfaces = NULL; g_clear_object (&priv->properties_proxy); + g_clear_object (&priv->bus_proxy); if (priv->connection) { dbus_g_connection_unref (priv->connection); @@ -1031,7 +1129,7 @@ _nm_object_reload_properties (NMObject *object, GError **error) GHashTableIter pp; gpointer name, info; - if (!priv->property_interfaces) + if (!priv->property_interfaces || !priv->nm_running) return TRUE; for (p = priv->property_interfaces; p; p = p->next) { @@ -1095,6 +1193,9 @@ _nm_object_reload_property (NMObject *object, g_return_if_fail (interface != NULL); g_return_if_fail (prop_name != NULL); + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, "Get", 15000, &err, G_TYPE_STRING, interface, @@ -1132,6 +1233,9 @@ _nm_object_set_property (NMObject *object, g_return_if_fail (prop_name != NULL); g_return_if_fail (G_IS_VALUE (value)); + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + if (!dbus_g_proxy_call_with_timeout (NM_OBJECT_GET_PRIVATE (object)->properties_proxy, "Set", 2000, NULL, G_TYPE_STRING, interface, @@ -1284,6 +1388,9 @@ _nm_object_reload_pseudo_property (NMObject *object, g_return_if_fail (NM_IS_OBJECT (object)); g_return_if_fail (name != NULL); + if (!NM_OBJECT_GET_PRIVATE (object)->nm_running) + return; + ppi = g_hash_table_lookup (priv->pseudo_properties, name); g_return_if_fail (ppi != NULL); diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 5c5ff24c10..1e8e086f05 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -64,8 +64,7 @@ typedef struct { DBusGProxy *dbus_proxy; - guint fetch_id; - gboolean fetching; + DBusGProxyCall *listcon_call; } NMRemoteSettingsPrivate; enum { @@ -384,10 +383,8 @@ connection_inited (GObject *source, GAsyncResult *result, gpointer user_data) /* Let listeners know that all connections have been found */ priv->init_left--; - if (priv->init_left == 0) { - priv->fetching = FALSE; + if (priv->init_left == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); - } } static NMRemoteConnection * @@ -433,12 +430,15 @@ fetch_connections_done (DBusGProxy *proxy, GError *error = NULL; int i; + g_warn_if_fail (priv->listcon_call == call); + priv->listcon_call = NULL; + if (!dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &connections, G_TYPE_INVALID)) { - /* Ignore settings service spawn errors */ if ( !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) - && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER)) { + && !g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NAME_HAS_NO_OWNER) + && priv->service_running) { g_warning ("%s: error fetching connections: (%d) %s.", __func__, error->code, @@ -447,16 +447,14 @@ fetch_connections_done (DBusGProxy *proxy, g_clear_error (&error); /* We tried to read connections and failed */ - priv->fetching = FALSE; g_signal_emit (self, signals[CONNECTIONS_READ], 0); return; } /* Let listeners know we are done getting connections */ - if (connections->len == 0) { - priv->fetching = FALSE; + if (connections->len == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); - } else { + else { priv->init_left = connections->len; for (i = 0; i < connections->len; i++) { char *path = g_ptr_array_index (connections, i); @@ -469,20 +467,6 @@ fetch_connections_done (DBusGProxy *proxy, 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; - - dbus_g_proxy_begin_call (priv->proxy, "ListConnections", - fetch_connections_done, self, NULL, - G_TYPE_INVALID); - return FALSE; -} - /** * nm_remote_settings_list_connections: * @settings: the %NMRemoteSettings @@ -566,6 +550,9 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, _nm_remote_settings_ensure_inited (settings); + if (!priv->service_running) + return FALSE; + info = g_malloc0 (sizeof (AddConnectionInfo)); info->self = settings; info->callback = callback; @@ -608,17 +595,6 @@ clear_one_hash (GHashTable *table) g_hash_table_remove_all (table); } -static gboolean -remove_connections (gpointer user_data) -{ - NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - - clear_one_hash (priv->pending); - clear_one_hash (priv->connections); - return FALSE; -} - typedef struct { NMRemoteSettings *settings; NMRemoteSettingsSaveHostnameFunc callback; @@ -670,6 +646,9 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, _nm_remote_settings_ensure_inited (settings); + if (!priv->service_running) + return FALSE; + info = g_malloc0 (sizeof (SaveHostnameInfo)); info->settings = settings; info->callback = callback; @@ -738,21 +717,23 @@ name_owner_changed (DBusGProxy *proxy, const char *sname = NM_DBUS_SERVICE; 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); priv->service_running = TRUE; + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, self, NULL, + G_TYPE_INVALID); + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", nm_appeared_got_properties, self, NULL, G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, G_TYPE_INVALID); } else { - priv->fetch_id = g_idle_add (remove_connections, self); priv->service_running = FALSE; + clear_one_hash (priv->pending); + clear_one_hash (priv->connections); + /* Clear properties */ g_free (priv->hostname); priv->hostname = NULL; @@ -760,6 +741,11 @@ name_owner_changed (DBusGProxy *proxy, priv->can_modify = FALSE; g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY); + + if (priv->listcon_call) { + dbus_g_proxy_cancel_call (priv->proxy, priv->listcon_call); + priv->listcon_call = NULL; + } } g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_SERVICE_RUNNING); } @@ -782,7 +768,11 @@ name_owner_changed (DBusGProxy *proxy, NMRemoteSettings * nm_remote_settings_new (DBusGConnection *bus) { - return g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL); + NMRemoteSettings *self; + + self = g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, NULL); + _nm_remote_settings_ensure_inited (self); + return self; } static void @@ -913,10 +903,6 @@ constructed (GObject *object) object, NULL); - priv->fetching = TRUE; - priv->fetch_id = g_idle_add (fetch_connections, object); - - /* D-Bus properties proxy */ priv->props_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, NM_DBUS_PATH_SETTINGS, @@ -962,6 +948,10 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) } else priv->service_running = TRUE; + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, NM_REMOTE_SETTINGS (initable), NULL, + G_TYPE_INVALID); + /* Get properties */ if (!dbus_g_proxy_call (priv->props_proxy, "GetAll", error, G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, @@ -1020,14 +1010,12 @@ init_async_got_properties (DBusGProxy *proxy, DBusGProxyCall *call, } else g_simple_async_result_take_error (init_data->result, error); - if (priv->fetching) { - /* Still creating initial connections; wait for that to complete */ - g_signal_connect (init_data->settings, "connections-read", - G_CALLBACK (init_read_connections), init_data); - return; - } - - init_async_complete (init_data); + /* Read connections and wait for the result */ + priv->listcon_call = dbus_g_proxy_begin_call (priv->proxy, "ListConnections", + fetch_connections_done, init_data->settings, NULL, + G_TYPE_INVALID); + g_signal_connect (init_data->settings, "connections-read", + G_CALLBACK (init_read_connections), init_data); } static void @@ -1108,11 +1096,6 @@ dispose (GObject *object) NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - if (priv->fetch_id) { - g_source_remove (priv->fetch_id); - priv->fetch_id = 0; - } - while (g_slist_length (priv->add_list)) add_connection_info_dispose (self, (AddConnectionInfo *) priv->add_list->data); diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 400d042766..b573592d6b 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -589,6 +589,9 @@ nm_secret_agent_register (NMSecretAgent *self) g_return_val_if_fail (class->save_secrets != NULL, FALSE); g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + priv->suppress_auto = FALSE; /* Export our secret agent interface before registering with the manager */ @@ -631,6 +634,9 @@ nm_secret_agent_unregister (NMSecretAgent *self) g_return_val_if_fail (priv->bus != NULL, FALSE); g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + if (!priv->nm_owner && !priv->private_bus) + return FALSE; + dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID); _internal_unregister (self); @@ -829,6 +835,8 @@ nm_secret_agent_init (NMSecretAgent *self) "NameOwnerChanged", G_CALLBACK (name_owner_changed), self, NULL); + + get_nm_owner (self); } priv->manager_proxy = _nm_dbus_new_proxy_for_connection (priv->bus, @@ -839,7 +847,8 @@ nm_secret_agent_init (NMSecretAgent *self) return; } - priv->auto_register_id = g_idle_add (auto_register_cb, self); + if (priv->nm_owner || priv->private_bus) + priv->auto_register_id = g_idle_add (auto_register_cb, self); } static void