diff options
author | Thomas Haller <thaller@redhat.com> | 2015-08-12 17:23:25 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2015-08-28 16:30:09 +0200 |
commit | 4b9ac03df8490dc9381816d76625b4c306d0374f (patch) | |
tree | e4c9533a905e78250ace4e22a7e1c30e61ac80b9 | |
parent | f95a350143a210b7191fe3664894b199bce127f8 (diff) | |
download | NetworkManager-lr/applied-connection-bgo724041-2.tar.gz |
squash! core: separate active and applied connectionlr/applied-connection-bgo724041-2
TODO: reword commit message
- split nm_active_connection_get_connection() into
nm_active_connection_get_initial_connection() and
nm_active_connection_get_settings_connection().
settings_connection is now of NMSettingsConnection
type.
- Also for NMVpnConnection it does not hold that
the settings-connection is known from the beginning.
Also for vpns we do add-and-activate.
- get rid of nm_active_connection_get_connection_type()
and nm_active_connection_get_connection_uuid(). From the
name it is unclear whether this returns the settings or applied
connection. The (very few) callers, should figure that out themselfes.
- rename nm_active_connection_get_id() to
nm_active_connection_get_settings_connection_id(). This function
is only used internally for logging.
-rw-r--r-- | src/devices/nm-device.c | 4 | ||||
-rw-r--r-- | src/nm-activation-request.c | 26 | ||||
-rw-r--r-- | src/nm-active-connection.c | 162 | ||||
-rw-r--r-- | src/nm-active-connection.h | 14 | ||||
-rw-r--r-- | src/nm-default-route-manager.c | 2 | ||||
-rw-r--r-- | src/nm-manager.c | 94 | ||||
-rw-r--r-- | src/nm-policy.c | 25 | ||||
-rw-r--r-- | src/vpn-manager/nm-vpn-connection.c | 204 | ||||
-rw-r--r-- | src/vpn-manager/nm-vpn-connection.h | 2 |
9 files changed, 316 insertions, 217 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7a6438a5c1..0e782053be 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6490,11 +6490,11 @@ nm_device_steal_connection (NMDevice *self, NMSettingsConnection *connection) nm_settings_connection_get_id (connection)); if ( priv->queued_act_request - && NM_CONNECTION (connection) == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request))) + && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->queued_act_request))) _clear_queued_act_request (priv); if ( priv->act_request - && NM_CONNECTION (connection) == nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (priv->act_request)) + && connection == nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (priv->act_request)) && priv->state < NM_DEVICE_STATE_DEACTIVATING) nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 679c93f475..88d14bbcda 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -88,24 +88,6 @@ nm_act_request_get_applied_connection (NMActRequest *req) /*******************************************************************/ -static gboolean -check_connection_unmodified (NMActRequest *self, GError **error) -{ - NMSettingsConnection *connection = nm_act_request_get_settings_connection (self); - NMConnection *applied = nm_act_request_get_applied_connection (self); - - if (nm_connection_compare (NM_CONNECTION (connection), applied, - NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)) { - g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "The connection was modified since activated, secrets invalid."); - return FALSE; - } - - return TRUE; -} - -/*******************************************************************/ - struct _NMActRequestGetSecretsCallId { NMActRequest *self; NMActRequestSecretsFunc callback; @@ -148,7 +130,8 @@ get_secrets_cb (NMSettingsConnection *connection, priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); if (!error) { - check_connection_unmodified (info->self, &local); + g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "The connection was modified since requesting secrets"); error = local; } @@ -192,8 +175,11 @@ nm_act_request_get_secrets (NMActRequest *self, priv->secrets_calls = g_slist_append (priv->secrets_calls, info); - if (!check_connection_unmodified (self, &local)) + if (nm_active_connection_is_modified (NM_ACTIVE_CONNECTION (info->self))) { + g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); goto schedule_dummy; + } if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 319bf4447a..3bc74bbc79 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -40,7 +40,8 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT NMActiveConnectionPrivate)) typedef struct { - NMConnection *connection; + NMConnection *initial_connection; + NMSettingsConnection *settings_connection; NMConnection *applied_connection; char *specific_object; NMDevice *device; @@ -175,7 +176,7 @@ nm_active_connection_set_state (NMActiveConnection *self, if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection), + nm_settings_connection_update_timestamp (priv->settings_connection, (guint64) time (NULL), TRUE); } @@ -208,67 +209,126 @@ nm_active_connection_set_state (NMActiveConnection *self, } const char * -nm_active_connection_get_id (NMActiveConnection *self) +nm_active_connection_get_settings_connection_id (NMActiveConnection *self) { + NMSettingsConnection *con; + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - return nm_connection_get_id (NM_CONNECTION (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection)); + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection; + return con + ? nm_connection_get_id (NM_CONNECTION (con)) + : NULL; } -const char * -nm_active_connection_get_uuid (NMActiveConnection *self) +NMConnection * +nm_active_connection_get_initial_connection (NMActiveConnection *self) { + NMConnection *con; + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - return nm_connection_get_uuid (NM_CONNECTION (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection)); + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->initial_connection; + + /* there is only one caller of nm_active_connection_get_initial_connection() + * during add-and-activate. In this case, assert that an initial_connection + * is available. */ + g_return_val_if_fail (con, NULL); + return con; } -NMConnection * -nm_active_connection_get_connection (NMActiveConnection *self) +NMSettingsConnection * +_nm_active_connection_get_settings_connection (NMActiveConnection *self) { - return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection; + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); + + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection; } NMSettingsConnection * nm_active_connection_get_settings_connection (NMActiveConnection *self) { - return NM_SETTINGS_CONNECTION (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection); + NMSettingsConnection *con; + + con = _nm_active_connection_get_settings_connection (self); + + /* Only call this function on an active-connection that is already + * fully set-up (i.e. that has a settings-connection). Other uses + * indicate a bug. */ + g_return_val_if_fail (con, NULL); + return con; } NMConnection * nm_active_connection_get_applied_connection (NMActiveConnection *self) { - return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection; -} + NMConnection *con; -const char * -nm_active_connection_get_connection_type (NMActiveConnection *self) -{ - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - if (priv->connection == NULL) - return NULL; + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection; - return nm_connection_get_connection_type (priv->applied_connection); + /* Only call this function on an active-connection that is already + * fully set-up (i.e. that has a settings-connection). Other uses + * indicate a bug. */ + g_return_val_if_fail (con, NULL); + return con; } void -nm_active_connection_set_connection (NMActiveConnection *self, - NMSettingsConnection *connection) +nm_active_connection_set_settings_connection (NMActiveConnection *self, + NMSettingsConnection *connection) { - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMActiveConnectionPrivate *priv; + + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (NM_IS_CONNECTION (priv->initial_connection)); + g_return_if_fail (!priv->settings_connection); + g_return_if_fail (!priv->applied_connection); /* Can't change connection after the ActiveConnection is exported over D-Bus. - * Also, if we would do that, we would have to cancel all pending secret requests - * from NMActRequest. */ + * + * Later, we want to change the settings-connection of an activated connection. + * When doing that, this changes the assumption that the settings-connection + * never changes (once it's set). That has effects for NMVpnConnection and + * NMActivationRequest. + * For example, we'd have to cancel all pending seret requests. */ g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self))); - g_return_if_fail (priv->connection == NULL || !NM_IS_SETTINGS_CONNECTION (priv->connection)); - if (priv->connection) - g_object_unref (priv->connection); - priv->connection = g_object_ref (connection); + priv->settings_connection = g_object_ref (connection); + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection)); + g_clear_object (&priv->initial_connection); } +/*******************************************************************/ + +gboolean +nm_active_connection_is_modified (NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (priv->applied_connection), FALSE); + + if (nm_connection_compare (NM_CONNECTION (priv->settings_connection), + priv->applied_connection, + NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)) { + return FALSE; + } + + return TRUE; +} + +/*******************************************************************/ + const char * nm_active_connection_get_specific_object (NMActiveConnection *self) { @@ -588,7 +648,7 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m } _LOGD ("master ActiveConnection is [%p] %s", - master, nm_active_connection_get_id (master)); + master, nm_active_connection_get_settings_connection_id (master)); priv->master = g_object_ref (master); g_signal_connect (priv->master, @@ -699,6 +759,7 @@ nm_active_connection_authorize (NMActiveConnection *self, { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); const char *wifi_permission = NULL; + NMConnection *con; g_return_if_fail (result_func != NULL); g_return_if_fail (priv->chain == NULL); @@ -710,7 +771,11 @@ nm_active_connection_authorize (NMActiveConnection *self, nm_auth_chain_add_call (priv->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE); /* Shared wifi connections require special permissions too */ - wifi_permission = nm_utils_get_shared_wifi_permission (priv->applied_connection); + if (priv->initial_connection) + con = priv->initial_connection; + else + con = priv->applied_connection; + wifi_permission = nm_utils_get_shared_wifi_permission (con); if (wifi_permission) { priv->wifi_shared_permission = wifi_permission; nm_auth_chain_add_call (priv->chain, wifi_permission, TRUE); @@ -735,25 +800,35 @@ constructed (GObject *object) NMActiveConnection *self = (NMActiveConnection *) object; NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + if (priv->settings_connection) + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection)); + G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); - g_assert (priv->subject); - g_return_if_fail (priv->connection); - priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->connection)); _LOGD ("constructed (%s)", G_OBJECT_TYPE_NAME (self)); + + g_return_if_fail (priv->subject); + g_return_if_fail ((!priv->initial_connection) != (!priv->settings_connection)); } static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); const char *tmp; + NMConnection *con; switch (prop_id) { case PROP_INT_CONNECTION: - g_warn_if_fail (priv->connection == NULL); - priv->connection = g_value_dup_object (value); + nm_assert (!priv->settings_connection && !priv->initial_connection); + con = g_value_get_object (value); + if (!con) + g_return_if_reached (); + if (NM_IS_SETTINGS_CONNECTION (con)) + priv->settings_connection = g_object_ref (con); + else + priv->initial_connection = g_object_ref (con); break; case PROP_INT_DEVICE: nm_active_connection_set_device (NM_ACTIVE_CONNECTION (object), g_value_get_object (value)); @@ -797,16 +872,16 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_CONNECTION: - g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->connection))); + g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->settings_connection))); break; case PROP_ID: - g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->connection))); + g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection))); break; case PROP_UUID: - g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->connection))); + g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection))); break; case PROP_TYPE: - g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->connection))); + g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection))); break; case PROP_SPECIFIC_OBJECT: g_value_set_string (value, priv->specific_object ? priv->specific_object : "/"); @@ -902,7 +977,8 @@ dispose (GObject *object) g_free (priv->specific_object); priv->specific_object = NULL; - g_clear_object (&priv->connection); + g_clear_object (&priv->initial_connection); + g_clear_object (&priv->settings_connection); g_clear_object (&priv->applied_connection); _device_cleanup (self); @@ -1047,7 +1123,7 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) (object_class, PROP_INT_CONNECTION, g_param_spec_object (NM_ACTIVE_CONNECTION_INT_CONNECTION, "", "", NM_TYPE_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 79a3bad600..0e97bdc4b5 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -96,20 +96,18 @@ void nm_active_connection_authorize (NMActiveConnection *self, gpointer user_data1, gpointer user_data2); -NMConnection *nm_active_connection_get_connection (NMActiveConnection *self); - +NMConnection *nm_active_connection_get_initial_connection (NMActiveConnection *self); NMSettingsConnection *nm_active_connection_get_settings_connection (NMActiveConnection *self); - NMConnection *nm_active_connection_get_applied_connection (NMActiveConnection *self); -void nm_active_connection_set_connection (NMActiveConnection *self, - NMSettingsConnection *connection); +NMSettingsConnection *_nm_active_connection_get_settings_connection (NMActiveConnection *self); -const char * nm_active_connection_get_id (NMActiveConnection *self); +void nm_active_connection_set_settings_connection (NMActiveConnection *self, + NMSettingsConnection *connection); -const char * nm_active_connection_get_uuid (NMActiveConnection *self); +gboolean nm_active_connection_is_modified (NMActiveConnection *self); -const char * nm_active_connection_get_connection_type (NMActiveConnection *self); +const char * nm_active_connection_get_settings_connection_id (NMActiveConnection *self); const char * nm_active_connection_get_specific_object (NMActiveConnection *self); diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index 5b92f56764..26baf1778b 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -96,7 +96,7 @@ NM_DEFINE_SINGLETON_GETTER (NMDefaultRouteManager, nm_default_route_manager_get, (entry_idx), \ NM_IS_DEVICE ((entry)->source.pointer) ? "dev" : "vpn", \ (entry)->source.pointer, \ - NM_IS_DEVICE ((entry)->source.pointer) ? nm_device_get_iface ((entry)->source.device) : nm_vpn_connection_get_connection_id ((entry)->source.vpn), \ + NM_IS_DEVICE ((entry)->source.pointer) ? nm_device_get_iface ((entry)->source.device) : nm_active_connection_get_settings_connection_id (NM_ACTIVE_CONNECTION ((entry)->source.vpn)), \ ((entry)->never_default ? '0' : '1'), \ ((entry)->synced ? '+' : '-') diff --git a/src/nm-manager.c b/src/nm-manager.c index 23cae275a2..93e353cd9b 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -339,19 +339,30 @@ find_ac_for_connection (NMManager *manager, NMConnection *connection) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); GSList *iter; - NMActiveConnection *ac; - NMConnection *ac_connection; - NMActiveConnectionState ac_state; - const char *uuid; + const char *uuid = NULL; + gboolean is_settings_connection; + + is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection); + + if (is_settings_connection) + uuid = nm_connection_get_uuid (connection); - uuid = nm_connection_get_uuid (connection); for (iter = priv->active_connections; iter; iter = iter->next) { - ac = iter->data; - ac_connection = nm_active_connection_get_connection (ac); - ac_state = nm_active_connection_get_state (ac); + NMActiveConnection *ac = iter->data; + NMSettingsConnection *con; + + con = nm_active_connection_get_settings_connection (ac); - if ( !strcmp (nm_connection_get_uuid (ac_connection), uuid) - && (ac_state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)) + /* depending on whether we have a NMSettingsConnection or a NMConnection, + * we lookup by UUID or by reference. */ + if (is_settings_connection) { + if (con != (NMSettingsConnection *) connection) + continue; + } else { + if (strcmp (uuid, nm_connection_get_uuid (NM_CONNECTION (con))) != 0) + continue; + } + if (nm_active_connection_get_state (ac) < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) return ac; } @@ -2617,10 +2628,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * subject, &error_desc)) { g_set_error (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Private connection already active on the device: %s", - error_desc); + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Private connection already active on the device: %s", + error_desc); g_free (error_desc); return FALSE; } @@ -2833,7 +2844,7 @@ _internal_activation_failed (NMManager *self, const char *error_desc) { nm_log_dbg (LOGD_CORE, "Failed to activate '%s': %s", - nm_active_connection_get_id (active), + nm_active_connection_get_settings_connection_id (active), error_desc); if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { @@ -3217,7 +3228,7 @@ typedef struct { } AddAndActivateInfo; static void -activation_add_done (NMSettings *self, +activation_add_done (NMSettings *settings, NMSettingsConnection *new_connection, GError *error, GDBusMethodInvocation *context, @@ -3225,44 +3236,46 @@ activation_add_done (NMSettings *self, gpointer user_data) { AddAndActivateInfo *info = user_data; + NMManager *self; + gs_unref_object NMActiveConnection *active = NULL; GError *local = NULL; + self = info->manager; + active = info->active; + g_slice_free (AddAndActivateInfo, info); + if (!error) { - nm_active_connection_set_connection (info->active, new_connection); + nm_active_connection_set_settings_connection (active, new_connection); - if (_internal_activate_generic (info->manager, info->active, &local)) { + if (_internal_activate_generic (self, active, &local)) { nm_settings_connection_commit_changes (new_connection, NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION | NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED, NULL, NULL); g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(oo)", - nm_connection_get_path (NM_CONNECTION (new_connection)), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (info->active)))); + context, + g_variant_new ("(oo)", + nm_connection_get_path (NM_CONNECTION (new_connection)), + nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)))); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, - nm_active_connection_get_settings_connection (info->active), + nm_active_connection_get_settings_connection (active), TRUE, - nm_active_connection_get_subject (info->active), + nm_active_connection_get_subject (active), NULL); - goto done; + return; } error = local; } g_assert (error); - _internal_activation_failed (info->manager, info->active, error->message); + _internal_activation_failed (self, active, error->message); nm_settings_connection_delete (new_connection, NULL, NULL); g_dbus_method_invocation_return_gerror (context, error); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, NULL, FALSE, - nm_active_connection_get_subject (info->active), + nm_active_connection_get_subject (active), error->message); g_clear_error (&local); - -done: - g_object_unref (info->active); - g_free (info); } static void @@ -3279,13 +3292,13 @@ _add_and_activate_auth_done (NMActiveConnection *active, GError *error = NULL; if (success) { - info = g_malloc0 (sizeof (*info)); + info = g_slice_new (AddAndActivateInfo); info->manager = self; info->active = g_object_ref (active); /* Basic sender auth checks performed; try to add the connection */ nm_settings_add_connection_dbus (priv->settings, - NM_CONNECTION (nm_active_connection_get_connection (active)), + nm_active_connection_get_initial_connection (active), FALSE, context, activation_add_done, @@ -4337,7 +4350,7 @@ policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED, G_CALLBACK (connection_metered_changed), self); } - nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_id (ac) : "(none)"); + nm_log_dbg (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION); g_object_notify (G_OBJECT (self), NM_MANAGER_PRIMARY_CONNECTION_TYPE); nm_manager_update_metered (self); @@ -4372,7 +4385,7 @@ policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer u if (ac != priv->activating_connection) { g_clear_object (&priv->activating_connection); priv->activating_connection = ac ? g_object_ref (ac) : NULL; - nm_log_dbg (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_id (ac) : "(none)"); + nm_log_dbg (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVATING_CONNECTION); } } @@ -4777,7 +4790,7 @@ periodic_update_active_connection_timestamps (gpointer user_data) NMSettingsConnection *connection; if (nm_active_connection_get_state (ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - connection = NM_SETTINGS_CONNECTION (nm_active_connection_get_connection (ac)); + connection = nm_active_connection_get_settings_connection (ac); nm_settings_connection_update_timestamp (connection, (guint64) time (NULL), FALSE); } } @@ -5024,7 +5037,14 @@ get_property (GObject *object, guint prop_id, nm_utils_g_value_set_object_path (value, priv->primary_connection); break; case PROP_PRIMARY_CONNECTION_TYPE: - type = priv->primary_connection ? nm_active_connection_get_connection_type (priv->primary_connection) : NULL; + type = NULL; + if (priv->primary_connection) { + NMConnection *con; + + con = nm_active_connection_get_applied_connection (priv->primary_connection); + if (con) + type = nm_connection_get_connection_type (con); + } g_value_set_string (value, type ? type : ""); break; case PROP_ACTIVATING_CONNECTION: diff --git a/src/nm-policy.c b/src/nm-policy.c index fdad453506..9af7865ae1 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -768,7 +768,7 @@ process_secondaries (NMPolicy *policy, if (connected) { nm_log_dbg (LOGD_DEVICE, "Secondary connection '%s' SUCCEEDED; active path '%s'", - nm_active_connection_get_id (active), + nm_active_connection_get_settings_connection_id (active), nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); /* Secondary connection activated */ @@ -784,7 +784,7 @@ process_secondaries (NMPolicy *policy, } } else { nm_log_dbg (LOGD_DEVICE, "Secondary connection '%s' FAILED; active path '%s'", - nm_active_connection_get_id (active), + nm_active_connection_get_settings_connection_id (active), nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); /* Secondary connection failed -> do not watch other connections */ @@ -983,7 +983,7 @@ static void activate_slave_connections (NMPolicy *policy, NMDevice *device) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - const char *master_device, *master_uuid = NULL; + const char *master_device, *master_uuid_settings = NULL, *master_uuid_applied = NULL; GSList *connections, *iter; NMActRequest *req; @@ -991,8 +991,19 @@ activate_slave_connections (NMPolicy *policy, NMDevice *device) g_assert (master_device); req = nm_device_get_act_request (device); - if (req) - master_uuid = nm_active_connection_get_uuid (NM_ACTIVE_CONNECTION (req)); + if (req) { + NMConnection *con; + + con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); + if (con) + master_uuid_applied = nm_connection_get_uuid (con); + con = NM_CONNECTION (nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req))); + if (con) { + master_uuid_settings = nm_connection_get_uuid (con); + if (!g_strcmp0 (master_uuid_settings, master_uuid_applied)) + master_uuid_settings = NULL; + } + } connections = nm_settings_get_connections (priv->settings); for (iter = connections; iter; iter = g_slist_next (iter)) { @@ -1009,7 +1020,9 @@ activate_slave_connections (NMPolicy *policy, NMDevice *device) if (!slave_master) continue; - if (!g_strcmp0 (slave_master, master_device) || !g_strcmp0 (slave_master, master_uuid)) + if ( !g_strcmp0 (slave_master, master_device) + || !g_strcmp0 (slave_master, master_uuid_applied) + || !g_strcmp0 (slave_master, master_uuid_settings)) nm_settings_connection_reset_autoconnect_retries (NM_SETTINGS_CONNECTION (slave)); } diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index a2cc5a756d..542a943770 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -76,8 +76,6 @@ typedef enum { } VpnState; typedef struct { - NMConnection *connection; - NMConnection *applied; gboolean service_can_persist; gboolean connection_can_persist; @@ -137,6 +135,9 @@ enum { LAST_PROP }; +static NMSettingsConnection *_get_settings_connection (NMVpnConnection *self, + gboolean allow_missing); + static void get_secrets (NMVpnConnection *self, SecretsReq secrets_idx, const char **hints); @@ -169,7 +170,7 @@ __LOG_create_prefix (char *buf, NMVpnConnection *self) priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - con = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self)); + con = NM_CONNECTION (_get_settings_connection (self, TRUE)); id = con ? nm_connection_get_id (con) : NULL; g_snprintf (buf, __NMLOG_prefix_buf_len, @@ -266,6 +267,31 @@ _state_to_ac_state (VpnState vpn_state) return NM_ACTIVE_CONNECTION_STATE_UNKNOWN; } +static NMSettingsConnection * +_get_settings_connection (NMVpnConnection *self, gboolean allow_missing) +{ + NMSettingsConnection *con; + + /* Currently we operate on the assumption, that the settings-connection + * never changes after it is set (though initially, it might be unset). + * Later we might want to change that, but then we need fixes here too. */ + + con = _nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (self)); + if (!con && !allow_missing) + g_return_val_if_reached (NULL); + return con; +} + +static NMConnection * +_get_applied_connection (NMVpnConnection *connection) +{ + NMConnection *con; + + con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (connection)); + g_return_val_if_fail (con, NULL); + return con; +} + static void call_plugin_disconnect (NMVpnConnection *self) { @@ -292,6 +318,7 @@ static void vpn_cleanup (NMVpnConnection *self, NMDevice *parent_dev) { NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMSettingsConnection *con; if (priv->ip_ifindex) { nm_platform_link_set_down (NM_PLATFORM_GET, priv->ip_ifindex); @@ -320,9 +347,9 @@ vpn_cleanup (NMVpnConnection *self, NMDevice *parent_dev) /* Clear out connection secrets to ensure that the settings service * gets asked for them next time the connection is activated. */ - if (priv->connection) - nm_connection_clear_secrets (priv->connection); - + con = _get_settings_connection (self, TRUE); + if (con) + nm_connection_clear_secrets (NM_CONNECTION (con)); } static void @@ -389,7 +416,8 @@ _set_vpn_state (NMVpnConnection *self, /* Clear any in-progress secrets request */ if (priv->secrets_id) { - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id); + nm_settings_connection_cancel_secrets (_get_settings_connection (self, FALSE), + priv->secrets_id); priv->secrets_id = 0; } @@ -424,7 +452,7 @@ _set_vpn_state (NMVpnConnection *self, break; case STATE_PRE_UP: if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_UP, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, priv->ip4_config, @@ -438,11 +466,11 @@ _set_vpn_state (NMVpnConnection *self, break; case STATE_ACTIVATED: /* Secrets no longer needed now that we're connected */ - nm_connection_clear_secrets (priv->connection); + nm_connection_clear_secrets (NM_CONNECTION (_get_settings_connection (self, FALSE))); /* Let dispatcher scripts know we're up and running */ nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_UP, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, priv->ip4_config, @@ -454,14 +482,14 @@ _set_vpn_state (NMVpnConnection *self, case STATE_DEACTIVATING: if (quitting) { nm_dispatcher_call_vpn_sync (DISPATCHER_ACTION_VPN_PRE_DOWN, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, priv->ip4_config, priv->ip6_config); } else { if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_DOWN, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, priv->ip4_config, @@ -481,14 +509,14 @@ _set_vpn_state (NMVpnConnection *self, /* Let dispatcher scripts know we're about to go down */ if (quitting) { nm_dispatcher_call_vpn_sync (DISPATCHER_ACTION_VPN_DOWN, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, NULL, NULL); } else { nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_DOWN, - NM_SETTINGS_CONNECTION (priv->connection), + _get_settings_connection (self, FALSE), parent_dev, priv->ip_iface, NULL, @@ -670,7 +698,7 @@ nm_vpn_connection_new (NMConnection *connection, const char *specific_object, NMAuthSubject *subject) { - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); return (NMVpnConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, @@ -682,18 +710,12 @@ nm_vpn_connection_new (NMConnection *connection, NULL); } -static NMConnection * -nm_vpn_connection_get_applied_connection (NMVpnConnection *self) -{ - return nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (self)); -} - static const char * nm_vpn_connection_get_service (NMVpnConnection *self) { NMSettingVpn *s_vpn; - s_vpn = nm_connection_get_setting_vpn (nm_vpn_connection_get_applied_connection (self)); + s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self)); return nm_setting_vpn_get_service_type (s_vpn); } @@ -823,7 +845,7 @@ plugin_state_changed (NMVpnConnection *self, NMVpnServiceState new_service_state /* Clear connection secrets to ensure secrets get requested each time the * connection is activated. */ - nm_connection_clear_secrets (priv->connection); + nm_connection_clear_secrets (NM_CONNECTION (_get_settings_connection (self, FALSE))); if ((priv->vpn_state >= STATE_WAITING) && (priv->vpn_state <= STATE_ACTIVATED)) { VpnState old_state = priv->vpn_state; @@ -1105,8 +1127,7 @@ nm_vpn_connection_config_maybe_complete (NMVpnConnection *self, /* Add the tunnel interface to the specified firewall zone */ if (priv->ip_iface) { - base_con = nm_vpn_connection_get_connection (self); - g_assert (base_con); + base_con = _get_applied_connection (self); s_con = nm_connection_get_setting_connection (base_con); zone = nm_setting_connection_get_zone (s_con); @@ -1256,31 +1277,25 @@ nm_vpn_connection_config_get (NMVpnConnection *self, GVariant *dict) guint32 nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *self) { - NMConnection *applied = nm_vpn_connection_get_applied_connection (self); - - if (applied) { - gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (applied)); + gint64 route_metric; + NMConnection *applied; - if (route_metric >= 0) - return route_metric; - } + applied = _get_applied_connection (self); + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (applied)); - return NM_VPN_ROUTE_METRIC_DEFAULT; + return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT; } guint32 nm_vpn_connection_get_ip6_route_metric (NMVpnConnection *self) { - NMConnection *applied = nm_vpn_connection_get_applied_connection (self); + gint64 route_metric; + NMConnection *applied; - if (applied) { - gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (applied)); + applied = _get_applied_connection (self); + route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (applied)); - if (route_metric >= 0) - return route_metric; - } - - return NM_VPN_ROUTE_METRIC_DEFAULT; + return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT; } static void @@ -1411,7 +1426,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) /* Merge in user overrides from the NMConnection's IPv4 setting */ nm_ip4_config_merge_setting (config, - nm_connection_get_setting_ip4_config (nm_vpn_connection_get_applied_connection (self)), + nm_connection_get_setting_ip4_config (_get_applied_connection (self)), route_metric); g_clear_object (&priv->ip4_config); @@ -1546,7 +1561,7 @@ next: /* Merge in user overrides from the NMConnection's IPv6 setting */ nm_ip6_config_merge_setting (config, - nm_connection_get_setting_ip6_config (nm_vpn_connection_get_applied_connection (self)), + nm_connection_get_setting_ip6_config (_get_applied_connection (self)), route_metric); g_clear_object (&priv->ip6_config); @@ -1680,7 +1695,7 @@ really_activate (NMVpnConnection *self, const char *username) g_return_if_fail (priv->vpn_state == STATE_NEED_AUTH); g_clear_pointer (&priv->connect_hash, g_variant_unref); - priv->connect_hash = _hash_with_username (nm_vpn_connection_get_applied_connection (self), username); + priv->connect_hash = _hash_with_username (_get_applied_connection (self), username); g_variant_ref_sink (priv->connect_hash); /* If at least one agent doesn't support VPN hints, then we can't use @@ -1847,7 +1862,7 @@ nm_vpn_connection_activate (NMVpnConnection *self) priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - s_vpn = nm_connection_get_setting_vpn (nm_vpn_connection_get_applied_connection (self)); + s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self)); g_assert (s_vpn); priv->connection_can_persist = nm_setting_vpn_get_persistent (s_vpn); @@ -1865,25 +1880,6 @@ nm_vpn_connection_activate (NMVpnConnection *self) self); } -NMConnection * -nm_vpn_connection_get_connection (NMVpnConnection *self) -{ - g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL); - - return NM_VPN_CONNECTION_GET_PRIVATE (self)->connection; -} - -const char* -nm_vpn_connection_get_connection_id (NMVpnConnection *self) -{ - NMConnection *c; - - g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL); - - c = NM_VPN_CONNECTION_GET_PRIVATE (self)->connection; - return c ? nm_connection_get_id (NM_CONNECTION (c)) : NULL; -} - NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *self) { @@ -2057,12 +2053,21 @@ get_secrets_cb (NMSettingsConnection *connection, NMVpnConnection *self = NM_VPN_CONNECTION (user_data); NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GVariant *dict; + GError *local = NULL; - g_return_if_fail (connection == NM_SETTINGS_CONNECTION (priv->connection)); + g_return_if_fail (connection && connection == _get_settings_connection (self, FALSE)); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = 0; + if (nm_active_connection_is_modified (NM_ACTIVE_CONNECTION (self))) { + _LOGE ("Failed to request VPN secrets #%d: the connection was modified since requesting secrets", + priv->secrets_idx + 1); + _set_vpn_state (self, STATE_FAILED, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, FALSE); + g_error_free (local); + return; + } + if (error && priv->secrets_idx >= SECRETS_REQ_NEW) { _LOGE ("Failed to request VPN secrets #%d: (%d) %s", priv->secrets_idx + 1, error->code, error->message); @@ -2076,7 +2081,7 @@ get_secrets_cb (NMSettingsConnection *connection, priv->username = g_strdup (agent_username); } - dict = _hash_with_username (nm_vpn_connection_get_applied_connection (self), priv->username); + dict = _hash_with_username (_get_applied_connection (self), priv->username); if (priv->secrets_idx == SECRETS_REQ_INTERACTIVE) { _LOGD ("sending secrets to the plugin"); @@ -2106,6 +2111,18 @@ get_secrets_cb (NMSettingsConnection *connection, } static void +cancel_get_secrets (NMVpnConnection *self) +{ + NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + + if (priv->secrets_id) { + nm_settings_connection_cancel_secrets (_get_settings_connection (self, FALSE), + priv->secrets_id); + priv->secrets_id = 0; + } +} + +static void get_secrets (NMVpnConnection *self, SecretsReq secrets_idx, const char **hints) @@ -2113,10 +2130,13 @@ get_secrets (NMVpnConnection *self, NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE; GError *error = NULL; + gboolean is_modified; g_return_if_fail (secrets_idx < SECRETS_REQ_LAST); priv->secrets_idx = secrets_idx; + cancel_get_secrets (self); + _LOGD ("requesting VPN secrets pass #%d", priv->secrets_idx + 1); @@ -2138,18 +2158,24 @@ get_secrets (NMVpnConnection *self, if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; - priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), - nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), - NM_SETTING_VPN_SETTING_NAME, - flags, - hints, - get_secrets_cb, - self, - &error); - if (!priv->secrets_id) { - if (error) { - _LOGE ("failed to request VPN secrets #%d: (%d) %s", - priv->secrets_idx + 1, error->code, error->message); + is_modified = nm_active_connection_is_modified (NM_ACTIVE_CONNECTION (self)); + if (!is_modified) { + priv->secrets_id = nm_settings_connection_get_secrets (_get_settings_connection (self, FALSE), + nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), + NM_SETTING_VPN_SETTING_NAME, + flags, + hints, + get_secrets_cb, + self, + &error); + } + if (is_modified || !priv->secrets_id) { + if (is_modified) { + _LOGW ("cannot request secrets because the connections was modified since activation: #%d", + priv->secrets_idx + 1); + } else { + _LOGE ("failed to request VPN secrets #%d: %s", + priv->secrets_idx + 1, error ? error->message : "(unknown reason)"); } _set_vpn_state (self, STATE_FAILED, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, FALSE); g_clear_error (&error); @@ -2233,19 +2259,9 @@ nm_vpn_connection_init (NMVpnConnection *self) } static void -constructed (GObject *object) -{ - NMConnection *connection; - - G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructed (object); - - connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (object)); - NM_VPN_CONNECTION_GET_PRIVATE (object)->connection = g_object_ref (connection); -} - -static void dispose (GObject *object) { + NMVpnConnection *self = NM_VPN_CONNECTION (object); NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); g_clear_pointer (&priv->connect_hash, g_variant_unref); @@ -2257,11 +2273,7 @@ dispose (GObject *object) dispatcher_cleanup (NM_VPN_CONNECTION (object)); - if (priv->secrets_id) { - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), - priv->secrets_id); - priv->secrets_id = 0; - } + cancel_get_secrets (self); if (priv->cancellable) { g_cancellable_cancel (priv->cancellable); @@ -2270,9 +2282,6 @@ dispose (GObject *object) g_clear_object (&priv->ip4_config); g_clear_object (&priv->ip6_config); g_clear_object (&priv->proxy); - g_clear_object (&priv->connection); - g_clear_object (&priv->default_route_manager); - g_clear_object (&priv->route_manager); fw_call_cleanup (NM_VPN_CONNECTION (object)); @@ -2339,7 +2348,6 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) /* virtual methods */ object_class->get_property = get_property; - object_class->constructed = constructed; object_class->dispose = dispose; object_class->finalize = finalize; active_class->device_state_changed = device_state_changed; diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index 996da42fc6..882ee828de 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -76,8 +76,6 @@ NMVpnConnection * nm_vpn_connection_new (NMConnection *connection, NMAuthSubject *subject); void nm_vpn_connection_activate (NMVpnConnection *self); -NMConnection * nm_vpn_connection_get_connection (NMVpnConnection *self); -const char* nm_vpn_connection_get_connection_id (NMVpnConnection *self); NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *self); const char * nm_vpn_connection_get_banner (NMVpnConnection *self); |