From eb883e34a5889812d35e5c2d7bc6051723001a3a Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 26 Oct 2018 13:17:31 +0200 Subject: [PATCH] core: Add option to AddAndActivateConnection2 to bind the lifetime This allows binding the lifetime of the created connection to the existance of the requesting dbus client. This feature is useful if one has a service specific connection (e.g. P2P wireless) which will not be useful without the specific service. This is simply a mechanism to ensure proper connection cleanup if the requesting service has a failure. --- .../org.freedesktop.NetworkManager.xml | 1 + src/nm-active-connection.c | 17 ++++++++++++++ src/nm-active-connection.h | 4 ++++ src/nm-manager.c | 23 ++++++++++++++++++- 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/introspection/org.freedesktop.NetworkManager.xml b/introspection/org.freedesktop.NetworkManager.xml index 86131c8d33..715e182eda 100644 --- a/introspection/org.freedesktop.NetworkManager.xml +++ b/introspection/org.freedesktop.NetworkManager.xml @@ -129,6 +129,7 @@ parameters. At this time the following options are supported: * persist: A string value of either "disk" (default), "memory" or "volatile". If "memory" is passed, the connection will not be saved to disk. If "volatile" is passed, the connection will not be saved to disk and will be destroyed when disconnected. + * bind: Bind the connections lifetime. Set to "dbus-name" to automatically disconnect when the requesting process disappears from the bus. The default of "none" means the connection is kept alive normally. If restricted, then persist must be set to "volatile". --> diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index d8c886b147..84c86ce5de 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -1014,6 +1014,23 @@ nm_active_connection_set_parent (NMActiveConnection *self, NMActiveConnection *p g_object_weak_ref ((GObject *) priv->parent, parent_destroyed, self); } +/** + * nm_active_connection_bind_dbus_client: + * @self: the #NMActiveConnection + * @dbus_client: The dbus client to watch. + * + * Binds the lifetime of this active connection to the given dbus client. If + * the dbus client disappears, then the connection will be disconnected. + */ +void +nm_active_connection_bind_dbus_client (NMActiveConnection *self, GDBusConnection *dbus_con, const char *dbus_client) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + nm_keep_alive_set_dbus_client_watch (priv->keep_alive, dbus_con, dbus_client, NULL); + nm_keep_alive_sink (priv->keep_alive); +} + /*****************************************************************************/ static void diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 85689a6bfd..5b2e421507 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -190,4 +190,8 @@ gboolean nm_active_connection_get_keep_alive (NMActiveConnection *self); void nm_active_connection_clear_secrets (NMActiveConnection *self); +void nm_active_connection_bind_dbus_client (NMActiveConnection *self, + GDBusConnection *dbus_con, + const char *dbus_name); + #endif /* __NETWORKMANAGER_ACTIVE_CONNECTION_H__ */ diff --git a/src/nm-manager.c b/src/nm-manager.c index a9b12878ac..e5a0964192 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -5224,7 +5224,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMConnection *incompl_conn = NULL; - NMActiveConnection *active = NULL; + gs_unref_object NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; NMDevice *device = NULL; @@ -5235,6 +5235,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, const char *specific_object_path; gs_free NMConnection **conns = NULL; NMSettingsConnectionPersistMode persist = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK; + const char *bind_lifetime = "none"; if (g_strcmp0 (method_info->parent.name, "AddAndActivateConnection2") == 0) g_variant_get (parameters, "(@a{sa{sv}}&o&o@a{sv})", &settings, &device_path, &specific_object_path, &options); @@ -5270,6 +5271,19 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, goto error; } + } else if ((g_strcmp0 (option_name, "bind") == 0) && + g_variant_is_of_type (option_value, G_VARIANT_TYPE_STRING)) { + s = g_variant_get_string (option_value, NULL); + + if (!NM_IN_STRSET (s, "dbus-client", "none")) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, + "Option \"bind\" must be one of \"dbus-client\" or \"none\"."); + goto error; + } + + bind_lifetime = s; + } else { /* Unknown argument */ error = g_error_new_literal (NM_MANAGER_ERROR, @@ -5350,6 +5364,13 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, if (!active) goto error; + if (g_strcmp0 (bind_lifetime, "dbus-client") == 0) { + if (persist != NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_ONLY) + goto error; + + nm_active_connection_bind_dbus_client (active, dbus_connection, sender); + } + nm_active_connection_authorize (active, incompl_conn, _async_op_complete_ac_auth_cb,