summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2014-09-11 09:09:12 +0200
committerJiří Klimeš <jklimes@redhat.com>2014-09-26 13:53:15 +0200
commit54a5f4513b5d137c299c21e37f27245eae7d5c07 (patch)
tree84eef51f84f79a3fa466444e80cca815a4b8d7f6
parentc9b9229c2e7de2bbb12e493a868921b7a788ee92 (diff)
downloadNetworkManager-54a5f4513b5d137c299c21e37f27245eae7d5c07.tar.gz
settings: do not clear secrets on Update() without any secrets (bgo #728920)
When a connection is updated by Update() and the new settings contain *no* secrets, leave the previous secrets untouched. This makes updating connection parameters much easier. Users (clients) need not to bother with secrets when they only want adjust a parameter. Use case: - GetSettings() - modify the settings - Update() E.g. nmcli con mod my-wifi connection.zone home https://bugzilla.gnome.org/show_bug.cgi?id=728920
-rw-r--r--src/settings/nm-settings-connection.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c
index 9fa2801dd3..c0e6794a85 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"
@@ -1209,6 +1209,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 +1312,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,