diff options
Diffstat (limited to 'src/settings/nm-settings-connection.c')
-rw-r--r-- | src/settings/nm-settings-connection.c | 146 |
1 files changed, 133 insertions, 13 deletions
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 9fa2801dd3..6b0d38c738 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -15,8 +15,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2013 Red Hat, Inc. + * Copyright 2008 Novell, Inc. + * Copyright 2008 - 2014 Red Hat, Inc. */ #include "config.h" @@ -66,6 +66,9 @@ static void impl_settings_connection_get_secrets (NMSettingsConnection *connecti const gchar *setting_name, DBusGMethodInvocation *context); +static void impl_settings_connection_clear_secrets (NMSettingsConnection *connection, + DBusGMethodInvocation *context); + #include "nm-settings-connection-glue.h" static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface); @@ -1209,6 +1212,54 @@ typedef struct { } UpdateInfo; static void +has_some_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + GParamSpec *pspec; + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (setting)), key); + if (pspec) { + if ( (flags & NM_SETTING_PARAM_SECRET) + && !g_param_value_defaults (pspec, (GValue *)value)) + *((gboolean *) user_data) = TRUE; + } +} + +static gboolean +any_secrets_present (NMConnection *connection) +{ + gboolean has_secrets = FALSE; + + nm_connection_for_each_setting_value (connection, has_some_secrets_cb, &has_secrets); + return has_secrets; +} + +static void +cached_secrets_to_connection (NMSettingsConnection *self, NMConnection *connection) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GVariant *secrets_dict; + + if (priv->agent_secrets) { + secrets_dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (secrets_dict) { + (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } + } + if (priv->system_secrets) { + secrets_dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + if (secrets_dict) { + (void) nm_connection_update_secrets (connection, NULL, secrets_dict, NULL); + g_variant_unref (secrets_dict); + } + } +} + +static void update_complete (NMSettingsConnection *self, UpdateInfo *info, GError *error) @@ -1264,11 +1315,19 @@ update_auth_cb (NMSettingsConnection *self, return; } - /* Cache the new secrets from the agent, as stuff like inotify-triggered - * changes to connection's backing config files will blow them away if - * they're in the main connection. - */ - update_agent_secrets_cache (self, info->new_settings); + if (!any_secrets_present (info->new_settings)) { + /* If the new connection has no secrets, we do not want to remove all + * secrets, rather we keep all the existing ones. Do that by merging + * them in to the new connection. + */ + cached_secrets_to_connection (self, info->new_settings); + } else { + /* Cache the new secrets from the agent, as stuff like inotify-triggered + * changes to connection's backing config files will blow them away if + * they're in the main connection. + */ + update_agent_secrets_cache (self, info->new_settings); + } if (info->save_to_disk) { nm_settings_connection_replace_and_commit (self, @@ -1521,11 +1580,11 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, } static void -dbus_secrets_auth_cb (NMSettingsConnection *self, - DBusGMethodInvocation *context, - NMAuthSubject *subject, - GError *error, - gpointer user_data) +dbus_get_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + NMAuthSubject *subject, + GError *error, + gpointer user_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *setting_name = user_data; @@ -1569,7 +1628,7 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, context, subject, get_modify_permission_basic (self), - dbus_secrets_auth_cb, + dbus_get_secrets_auth_cb, g_strdup (setting_name)); g_object_unref (subject); } else { @@ -1578,6 +1637,67 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, } } +static void +clear_secrets_cb (NMSettingsConnection *self, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + +static void +dbus_clear_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + NMAuthSubject *subject, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if (error) + dbus_g_method_return_error (context, error); + else { + /* Clear secrets in connection and caches */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + if (priv->system_secrets) + nm_connection_clear_secrets (priv->system_secrets); + if (priv->agent_secrets) + nm_connection_clear_secrets (priv->agent_secrets); + + /* Tell agents to remove secrets for this connection */ + nm_agent_manager_delete_secrets (priv->agent_mgr, NM_CONNECTION (self)); + + nm_settings_connection_commit_changes (self, clear_secrets_cb, context); + } +} + +static void +impl_settings_connection_clear_secrets (NMSettingsConnection *self, + DBusGMethodInvocation *context) +{ + NMAuthSubject *subject; + GError *error = NULL; + + subject = _new_auth_subject (context, &error); + if (subject) { + auth_start (self, + context, + subject, + get_modify_permission_basic (self), + dbus_clear_secrets_auth_cb, + NULL); + g_object_unref (subject); + } else { + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + /**************************************************************/ void |