diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2015-07-14 16:53:24 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2015-09-18 17:32:11 +0200 |
commit | 06da3532428e3498c1e808ff8be1af48b540a6ff (patch) | |
tree | 80155896a11d61517bc7cb87df16b3f0ede16f25 /src | |
parent | c9b3617c35b3380428a1800e8aa6692ee68b4b74 (diff) | |
download | NetworkManager-06da3532428e3498c1e808ff8be1af48b540a6ff.tar.gz |
core: separate active and applied connection
Clone the connection upon activation. This makes it safe for the user
to modify the original connection while it is activated.
This involves several changes:
- NMActiveConnection gets @settings_connection and @applied_connection.
To support add-and-activate, we constructing a NMActiveConnection with
no connection set. Previously, we would set the "connection" field to
a temporary NMConnection. Now NMManager piggybacks this temporary
connection as object-data (TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE).
- get rid of the functions nm_active_connection_get_connection_type()
and nm_active_connection_get_connection_uuid(). From their names
it is unclear whether this returns the settings or applied connection.
The (few) callers should figure that out themselves.
- rename nm_active_connection_get_id() to
nm_active_connection_get_settings_connection_id(). This function
is only used internally for logging.
- dispatcher calls now get two connections as well. The
applied-connection is used for the connection data, while
the settings-connection is used for the connection path.
- needs special handling for properties that apply immediately
when changed (nm_device_reapply_settings_immediately()).
Co-Authored-By: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=724041
Diffstat (limited to 'src')
36 files changed, 1326 insertions, 843 deletions
diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 8dfd0c8541..019cccfa59 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -321,7 +321,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason) g_assert (out_reason); - s_adsl = nm_connection_get_setting_adsl (nm_device_get_connection (device)); + s_adsl = nm_connection_get_setting_adsl (nm_device_get_applied_connection (device)); g_assert (s_adsl); protocol = nm_setting_adsl_get_protocol (s_adsl); @@ -411,7 +411,7 @@ act_stage3_ip4_config_start (NMDevice *device, req = nm_device_get_act_request (device); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (req); s_adsl = nm_connection_get_setting_adsl (connection); diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 408315bca9..9fcb33bc81 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -821,7 +821,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMConnection *connection; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); priv->bt_type = get_connection_bt_type (connection); if (priv->bt_type == NM_BT_CAPABILITY_NONE) { diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index b47b199992..98e772adff 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -264,7 +264,7 @@ apply_bonding_config (NMDevice *device) * arp_interval doesn't require miimon to be 0 */ - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_bond = nm_connection_get_setting_bond (connection); g_assert (s_bond); @@ -377,7 +377,7 @@ ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) NMSettingWired *s_wired; guint32 mtu; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_wired = nm_connection_get_setting_wired (connection); diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 4dc180083f..db9f0c60e5 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -317,7 +317,7 @@ static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMActStageReturn ret; - NMConnection *connection = nm_device_get_connection (device); + NMConnection *connection = nm_device_get_applied_connection (device); g_assert (connection); diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 3de26b48c1..ff3994d127 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -271,7 +271,7 @@ clear_secrets_tries (NMDevice *device) req = nm_device_get_act_request (device); if (req) { - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); /* Clear wired secrets tries on success, failure, or when deactivating */ g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, NULL); } @@ -415,7 +415,7 @@ device_get_setting (NMDevice *device, GType setting_type) if (req) { NMConnection *connection; - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); if (connection) setting = nm_connection_get_setting (connection, setting_type); } @@ -481,7 +481,7 @@ supplicant_interface_release (NMDeviceEthernet *self) static void wired_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId call_id, - NMConnection *connection, + NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -492,7 +492,7 @@ wired_secrets_cb (NMActRequest *req, return; g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); - g_return_if_fail (nm_act_request_get_connection (req) == connection); + g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); if (error) { _LOGW (LOGD_ETHER, "%s", error->message); @@ -510,7 +510,7 @@ link_timeout_cb (gpointer user_data) NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self); NMDevice *dev = NM_DEVICE (self); NMActRequest *req; - NMConnection *connection; + NMConnection *applied_connection; const char *setting_name; priv->supplicant_timeout_id = 0; @@ -531,9 +531,10 @@ link_timeout_cb (gpointer user_data) if (nm_device_get_state (dev) != NM_DEVICE_STATE_CONFIG) goto time_out; - connection = nm_act_request_get_connection (req); - nm_connection_clear_secrets (connection); - setting_name = nm_connection_need_secrets (connection, NULL); + nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); + + applied_connection = nm_act_request_get_applied_connection (req); + setting_name = nm_connection_need_secrets (applied_connection, NULL); if (!setting_name) goto time_out; @@ -566,7 +567,7 @@ build_supplicant_config (NMDeviceEthernet *self) NMSetting8021x *security; NMConnection *connection; - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_assert (connection); con_uuid = nm_connection_get_uuid (connection); @@ -703,19 +704,19 @@ handle_auth_or_fail (NMDeviceEthernet *self, { const char *setting_name; guint32 tries; - NMConnection *connection; + NMConnection *applied_connection; - connection = nm_act_request_get_connection (req); - g_assert (connection); + applied_connection = nm_act_request_get_applied_connection (req); - tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), WIRED_SECRETS_TRIES)); + tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (applied_connection), WIRED_SECRETS_TRIES)); if (tries > 3) return NM_ACT_STAGE_RETURN_FAILURE; nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - nm_connection_clear_secrets (connection); - setting_name = nm_connection_need_secrets (connection, NULL); + nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (req)); + + setting_name = nm_connection_need_secrets (applied_connection, NULL); if (setting_name) { NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; @@ -723,7 +724,7 @@ handle_auth_or_fail (NMDeviceEthernet *self, flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); - g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); + g_object_set_data (G_OBJECT (applied_connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else _LOGI (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); @@ -753,7 +754,7 @@ supplicant_connection_timeout_cb (gpointer user_data) req = nm_device_get_act_request (device); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); /* Ask for new secrets only if we've never activated this connection @@ -875,7 +876,7 @@ nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason) const char *setting_name; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_assert (connection); security = nm_connection_get_setting_802_1x (connection); if (!security) { @@ -961,7 +962,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas req = nm_device_get_act_request (NM_DEVICE (self)); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (req); s_pppoe = nm_connection_get_setting_pppoe (connection); @@ -1275,7 +1276,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } /* PPPoE setup */ - if (nm_connection_is_type (nm_device_get_connection (device), + if (nm_connection_is_type (nm_device_get_applied_connection (device), NM_SETTING_PPPOE_SETTING_NAME)) { NMSettingPpp *s_ppp; @@ -1330,7 +1331,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) if (NM_DEVICE_ETHERNET_GET_PRIVATE (device)->ppp_manager) return; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_wired = nm_connection_get_setting_wired (connection); g_assert (s_wired); diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index df50cb6019..05bf0323af 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -85,7 +85,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) req = nm_device_get_act_request (dev); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); s_infiniband = nm_connection_get_setting_infiniband (connection); g_assert (s_infiniband); @@ -123,7 +123,7 @@ ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) NMSettingInfiniband *s_infiniband; guint32 mtu; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_infiniband = nm_connection_get_setting_infiniband (connection); g_assert (s_infiniband); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 59c2e47ce3..2d0a2ff794 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -310,7 +310,7 @@ match_parent (NMDeviceVlan *self, const char *parent) if (!parent_req) return FALSE; - parent_connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (parent_req)); + parent_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (parent_req)); if (!parent_connection) return FALSE; @@ -495,7 +495,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) req = nm_device_get_act_request (dev); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); s_wired = nm_connection_get_setting_wired (connection); @@ -534,7 +534,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) NMSettingWired *s_wired; guint32 mtu; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_wired = nm_connection_get_setting_wired (connection); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4226725059..e20f285858 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -768,7 +768,7 @@ _get_ipx_route_metric (NMDevice *self, g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (connection) { s_ip = is_v4 ? nm_connection_get_setting_ip4_config (connection) @@ -896,12 +896,31 @@ nm_device_get_act_request (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->act_request; } +NMSettingsConnection * +nm_device_get_settings_connection (NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + return priv->act_request ? nm_act_request_get_settings_connection (priv->act_request) : NULL; +} + NMConnection * -nm_device_get_connection (NMDevice *self) +nm_device_get_applied_connection (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - return priv->act_request ? nm_act_request_get_connection (priv->act_request) : NULL; + return priv->act_request ? nm_act_request_get_applied_connection (priv->act_request) : NULL; +} + +gboolean +nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + if (!priv->act_request) + return FALSE; + + return nm_active_connection_has_unmodified_applied_connection ((NMActiveConnection *) priv->act_request, compare_flags); } RfKillType @@ -924,13 +943,13 @@ static gboolean nm_device_uses_generated_assumed_connection (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; + NMSettingsConnection *connection; if ( priv->act_request && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) { - connection = nm_act_request_get_connection (priv->act_request); + connection = nm_act_request_get_settings_connection (priv->act_request); if ( connection - && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + && nm_settings_connection_get_nm_generated_assumed (connection)) return TRUE; } return FALSE; @@ -1856,7 +1875,7 @@ slave_state_changed (NMDevice *slave, return; if (slave_new_state == NM_DEVICE_STATE_IP_CONFIG) - nm_device_enslave_slave (self, slave, nm_device_get_connection (slave)); + nm_device_enslave_slave (self, slave, nm_device_get_applied_connection (slave)); else if (slave_new_state > NM_DEVICE_STATE_ACTIVATED) release = TRUE; else if ( slave_new_state <= NM_DEVICE_STATE_DISCONNECTED @@ -2050,7 +2069,7 @@ static void nm_device_slave_notify_enslave (NMDevice *self, gboolean success) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection = nm_device_get_connection (self); + NMConnection *connection = nm_device_get_applied_connection (self); gboolean activating = (priv->state == NM_DEVICE_STATE_IP_CONFIG); g_assert (priv->master); @@ -2092,7 +2111,7 @@ static void nm_device_slave_notify_release (NMDevice *self, NMDeviceStateReason reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection = nm_device_get_connection (self); + NMConnection *connection = nm_device_get_applied_connection (self); NMDeviceState new_state; const char *master_status; @@ -2649,7 +2668,7 @@ nm_device_can_assume_active_connection (NMDevice *self) if (!nm_device_can_assume_connections (self)) return FALSE; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (!connection) return FALSE; @@ -2816,7 +2835,7 @@ get_ip_config_may_fail (NMDevice *self, int family) g_return_val_if_fail (self != NULL, TRUE); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); /* Fail the connection if the failed IP method is required to complete */ @@ -3010,7 +3029,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) NMDeviceState slave_state = nm_device_get_state (info->slave); if (slave_state == NM_DEVICE_STATE_IP_CONFIG) - nm_device_enslave_slave (self, info->slave, nm_device_get_connection (info->slave)); + nm_device_enslave_slave (self, info->slave, nm_device_get_applied_connection (info->slave)); else if ( nm_device_uses_generated_assumed_connection (self) && slave_state <= NM_DEVICE_STATE_DISCONNECTED) nm_device_queue_recheck_assume (info->slave); @@ -3155,7 +3174,7 @@ nm_device_handle_ipv4ll_event (sd_ipv4ll *ll, int event, void *data) if (priv->act_request == NULL) return; - connection = nm_act_request_get_connection (priv->act_request); + connection = nm_act_request_get_applied_connection (priv->act_request); g_assert (connection); /* Ignore if the connection isn't an AutoIP connection */ @@ -3350,7 +3369,7 @@ ensure_con_ip4_config (NMDevice *self) if (priv->con_ip4_config) return; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (!connection) return; @@ -3376,7 +3395,7 @@ ensure_con_ip6_config (NMDevice *self) if (priv->con_ip6_config) return; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (!connection) return; @@ -3449,7 +3468,7 @@ ip4_config_merge_and_apply (NMDevice *self, } /* Apply ignore-auto-routes and ignore-auto-dns settings */ - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (connection) { NMSettingIPConfig *s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -3488,7 +3507,6 @@ ip4_config_merge_and_apply (NMDevice *self, if (priv->con_ip4_config) nm_ip4_config_merge (composite, priv->con_ip4_config, NM_IP_CONFIG_MERGE_DEFAULT); - /* Add the default route. * * We keep track of the default route of a device in a private field. @@ -3613,7 +3631,8 @@ dhcp4_lease_change (NMDevice *self, NMIP4Config *config) } else { /* Notify dispatcher scripts of new DHCP4 config */ nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, - nm_device_get_connection (self), + nm_device_get_settings_connection (self), + nm_device_get_applied_connection (self), self, NULL, NULL, @@ -3633,7 +3652,7 @@ dhcp4_restart_cb (gpointer user_data) priv = NM_DEVICE_GET_PRIVATE (self); priv->dhcp4_restart_id = 0; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (dhcp4_start (self, connection, &reason) == NM_ACT_STAGE_RETURN_FAILURE) priv->dhcp4_restart_id = g_timeout_add_seconds (120, dhcp4_restart_cb, self); @@ -3803,7 +3822,7 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) /* Terminate old DHCP instance and release the old lease */ dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); /* Start DHCP again on the interface */ @@ -3998,7 +4017,7 @@ act_stage3_ip4_config_start (NMDevice *self, g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); if ( connection_ip4_method_requires_carrier (connection, NULL) @@ -4103,7 +4122,7 @@ ip6_config_merge_and_apply (NMDevice *self, gboolean ignore_auto_dns = FALSE; /* Apply ignore-auto-routes and ignore-auto-dns settings */ - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (connection) { NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -4267,7 +4286,7 @@ static void dhcp6_lease_change (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; + NMSettingsConnection *settings_connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; if (priv->dhcp6_ip6_config == NULL) { @@ -4278,8 +4297,8 @@ dhcp6_lease_change (NMDevice *self) g_assert (priv->dhcp6_client); /* sanity check */ - connection = nm_device_get_connection (self); - g_assert (connection); + settings_connection = nm_device_get_settings_connection (self); + g_assert (settings_connection); /* Apply the updated config */ if (ip6_config_merge_and_apply (self, TRUE, &reason) == FALSE) { @@ -4287,7 +4306,10 @@ dhcp6_lease_change (NMDevice *self) nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); } else { /* Notify dispatcher scripts of new DHCPv6 config */ - nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, connection, self, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, + settings_connection, + nm_device_get_applied_connection (self), + self, NULL, NULL, NULL); } } @@ -4500,7 +4522,7 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll, NMDeviceStateReason *reason) g_clear_object (&priv->dhcp6_ip6_config); g_clear_pointer (&priv->dhcp6_event_id, g_free); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); if (!nm_setting_ip_config_get_may_fail (s_ip6) || @@ -4604,7 +4626,7 @@ linklocal6_complete (NMDevice *self) linklocal6_cleanup (self); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -4686,7 +4708,7 @@ linklocal6_start (NMDevice *self) if (have_ip6_address (priv->ip6_config, TRUE)) return NM_ACT_STAGE_RETURN_FINISH; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -5016,7 +5038,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) NMActStageReturn ret; const char *ip_iface = nm_device_get_ip_iface (self); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); g_warn_if_fail (priv->ac_ip6_config == NULL); @@ -5185,7 +5207,7 @@ _ip6_privacy_get (NMDevice *self) /* 1.) First look at the per-connection setting. If it is not -1 (unknown), * use it. */ - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (connection) { NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -5254,7 +5276,7 @@ act_stage3_ip6_config_start (NMDevice *self, ip_iface = nm_device_get_ip_iface (self); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); if ( connection_ip6_method_requires_carrier (connection, NULL) @@ -5485,7 +5507,7 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) master_device = nm_active_connection_get_device (master); if (priv->ip4_state == IP_WAIT && priv->ip6_state == IP_WAIT) { _LOGI (LOGD_DEVICE, "Activation: connection '%s' waiting on master '%s'", - nm_connection_get_id (nm_device_get_connection (self)), + nm_connection_get_id (nm_device_get_applied_connection (self)), master_device ? nm_device_get_iface (master_device) : "(unknown)"); } goto out; @@ -5550,7 +5572,7 @@ nm_device_activate_schedule_stage3_ip_config_start (NMDevice *self) g_return_if_fail (!priv->fw_call); /* Add the interface to the specified firewall zone */ - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_con = nm_connection_get_setting_connection (connection); @@ -5828,7 +5850,7 @@ send_arps (NMDevice *self, const char *mode_arg) NMIPAddress *addr; GError *error = NULL; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (!connection) return; s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -5903,7 +5925,7 @@ arp_announce (NMDevice *self) /* We only care about manually-configured addresses; DHCP- and autoip-configured * ones should already have been seen on the network at this point. */ - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (!connection) return; s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -5935,7 +5957,7 @@ nm_device_activate_ip4_config_commit (gpointer user_data) req = nm_device_get_act_request (self); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); /* Interface must be IFF_UP before IP config can be applied */ @@ -5972,7 +5994,8 @@ nm_device_activate_ip4_config_commit (gpointer user_data) && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) { /* Notify dispatcher scripts of new DHCP4 config */ nm_dispatcher_call (DISPATCHER_ACTION_DHCP4_CHANGE, - nm_device_get_connection (self), + nm_device_get_settings_connection (self), + nm_device_get_applied_connection (self), self, NULL, NULL, @@ -6061,7 +6084,7 @@ nm_device_activate_ip6_config_commit (gpointer user_data) req = nm_device_get_act_request (self); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); /* Interface must be IFF_UP before IP config can be applied */ @@ -6081,7 +6104,8 @@ nm_device_activate_ip6_config_commit (gpointer user_data) && (nm_device_get_state (self) > NM_DEVICE_STATE_IP_CONFIG)) { /* Notify dispatcher scripts of new DHCP6 config */ nm_dispatcher_call (DISPATCHER_ACTION_DHCP6_CHANGE, - nm_device_get_connection (self), + nm_device_get_settings_connection (self), + nm_device_get_applied_connection (self), self, NULL, NULL, @@ -6341,7 +6365,7 @@ impl_device_disconnect (NMDevice *self, GDBusMethodInvocation *context) return; } - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); /* Ask the manager to authenticate this request for us */ @@ -6413,7 +6437,7 @@ _device_activate (NMDevice *self, NMActRequest *req) priv = NM_DEVICE_GET_PRIVATE (self); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); _LOGI (LOGD_DEVICE, "Activation: starting connection '%s' (%s)", @@ -6474,7 +6498,7 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) if (priv->carrier_wait_id == 0) return FALSE; - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) { /* We passed all @flags we have, and no @specific_object. @@ -6502,19 +6526,19 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) } void -nm_device_steal_connection (NMDevice *self, NMConnection *connection) +nm_device_steal_connection (NMDevice *self, NMSettingsConnection *connection) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); _LOGW (LOGD_DEVICE, "disconnecting connection '%s' for new activation request.", - nm_connection_get_id (connection)); + nm_settings_connection_get_id (connection)); if ( priv->queued_act_request - && 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 - && 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, @@ -6684,7 +6708,7 @@ nm_device_set_ip4_config (NMDevice *self, g_object_unref (old_config); if (nm_device_uses_generated_assumed_connection (self)) { - NMConnection *connection = nm_device_get_connection (self); + NMConnection *connection = nm_device_get_applied_connection (self); NMSetting *s_ip4; g_object_freeze_notify (G_OBJECT (connection)); @@ -6813,7 +6837,7 @@ nm_device_set_ip6_config (NMDevice *self, g_object_unref (old_config); if (nm_device_uses_generated_assumed_connection (self)) { - NMConnection *connection = nm_device_get_connection (self); + NMConnection *connection = nm_device_get_applied_connection (self); NMSetting *s_ip6; g_object_freeze_notify (G_OBJECT (connection)); @@ -6927,7 +6951,8 @@ ip_check_pre_up (NMDevice *self) priv->dispatcher.post_state = NM_DEVICE_STATE_SECONDARIES; priv->dispatcher.post_state_reason = NM_DEVICE_STATE_REASON_NONE; if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_UP, - nm_device_get_connection (self), + nm_device_get_settings_connection (self), + nm_device_get_applied_connection (self), self, dispatcher_complete_proceed_state, self, @@ -7102,7 +7127,7 @@ nm_device_start_ip_check (NMDevice *self) g_assert (!priv->gw_ping.pid); g_assert (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_con = nm_connection_get_setting_connection (connection); @@ -7845,6 +7870,83 @@ nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) } void +nm_device_reapply_settings_immediately (NMDevice *self) +{ + NMConnection *applied_connection; + NMSettingsConnection *settings_connection; + NMDeviceState state; + NMSettingConnection *s_con_settings; + NMSettingConnection *s_con_applied; + const char *zone; + NMMetered metered; + + g_return_if_fail (NM_IS_DEVICE (self)); + + state = nm_device_get_state (self); + if ( state <= NM_DEVICE_STATE_DISCONNECTED + || state > NM_DEVICE_STATE_ACTIVATED) + return; + + applied_connection = nm_device_get_applied_connection (self); + settings_connection = nm_device_get_settings_connection (self); + + if (!nm_settings_connection_has_unmodified_applied_connection (settings_connection, + applied_connection, + NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)) + return; + + s_con_settings = nm_connection_get_setting_connection ((NMConnection *) settings_connection); + s_con_applied = nm_connection_get_setting_connection (applied_connection); + + if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)), + nm_setting_connection_get_zone (s_con_applied)) != 0) { + + _LOGD (LOGD_DEVICE, "reapply setting: zone = %s%s%s", NM_PRINT_FMT_QUOTE_STRING (zone)); + + g_object_set (G_OBJECT (s_con_applied), + NM_SETTING_CONNECTION_ZONE, zone, + NULL); + + nm_device_update_firewall_zone (self); + } + + if ((metered = nm_setting_connection_get_metered (s_con_settings)) != nm_setting_connection_get_metered (s_con_applied)) { + + _LOGD (LOGD_DEVICE, "reapply setting: metered = %d", (int) metered); + + g_object_set (G_OBJECT (s_con_applied), + NM_SETTING_CONNECTION_METERED, metered, + NULL); + + nm_device_update_metered (self); + } +} + +void +nm_device_update_firewall_zone (NMDevice *self) +{ + NMConnection *applied_connection; + NMSettingConnection *s_con; + + g_return_if_fail (NM_IS_DEVICE (self)); + + applied_connection = nm_device_get_applied_connection (self); + if (!applied_connection) + return; + + s_con = nm_connection_get_setting_connection (applied_connection); + if ( nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED + && !nm_device_uses_assumed_connection (self)) { + nm_firewall_manager_add_or_change_zone (nm_firewall_manager_get (), + nm_device_get_ip_iface (self), + nm_setting_connection_get_zone (s_con), + FALSE, /* change zone */ + NULL, + NULL); + } +} + +void nm_device_update_metered (NMDevice *self) { #define NM_METERED_INVALID ((NMMetered) -1) @@ -7862,7 +7964,7 @@ nm_device_update_metered (NMDevice *self) value = NM_METERED_UNKNOWN; if (value == NM_METERED_INVALID) { - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if (connection) { setting = nm_connection_get_setting_connection (connection); if (setting) { @@ -8233,7 +8335,7 @@ _cleanup_generic_pre (NMDevice *self, CleanupType cleanup_type) _cancel_activation (self); - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE && connection && !nm_device_uses_assumed_connection (self)) { @@ -8415,7 +8517,7 @@ nm_device_spawn_iface_helper (NMDevice *self) if (!nm_device_can_assume_connections (self)) return; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); argv = g_ptr_array_sized_new (10); @@ -8636,7 +8738,7 @@ _set_state_full (NMDevice *self, NMDeviceState old_state; NMActRequest *req; gboolean no_firmware = FALSE; - NMConnection *connection; + NMSettingsConnection *connection; /* Track re-entry */ g_warn_if_fail (priv->in_state_changed == FALSE); @@ -8801,13 +8903,15 @@ _set_state_full (NMDevice *self, if (quitting) { nm_dispatcher_call_sync (DISPATCHER_ACTION_PRE_DOWN, - nm_act_request_get_connection (req), + nm_act_request_get_settings_connection (req), + nm_act_request_get_applied_connection (req), self); } else { priv->dispatcher.post_state = NM_DEVICE_STATE_DISCONNECTED; priv->dispatcher.post_state_reason = reason; if (!nm_dispatcher_call (DISPATCHER_ACTION_PRE_DOWN, - nm_act_request_get_connection (req), + nm_act_request_get_settings_connection (req), + nm_act_request_get_applied_connection (req), self, deactivate_dispatcher_complete, self, @@ -8838,7 +8942,10 @@ _set_state_full (NMDevice *self, case NM_DEVICE_STATE_ACTIVATED: _LOGI (LOGD_DEVICE, "Activation: successful, device activated."); nm_device_update_metered (self); - nm_dispatcher_call (DISPATCHER_ACTION_UP, nm_act_request_get_connection (req), self, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_UP, + nm_act_request_get_settings_connection (req), + nm_act_request_get_applied_connection (req), + self, NULL, NULL, NULL); break; case NM_DEVICE_STATE_FAILED: if (nm_device_uses_assumed_connection (self)) { @@ -8849,10 +8956,10 @@ _set_state_full (NMDevice *self, break; } - connection = nm_device_get_connection (self); + connection = nm_device_get_settings_connection (self); _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: failed for connection '%s'", - connection ? nm_connection_get_id (connection) : "<unknown>"); + connection ? nm_settings_connection_get_id (connection) : "<unknown>"); /* Notify any slaves of the unexpected failure */ nm_device_master_release_slaves (self); @@ -8862,11 +8969,8 @@ _set_state_full (NMDevice *self, * failed (zero timestamp), connections that succeeded (non-zero timestamp), * and those we haven't tried yet (no timestamp). */ - if (connection && !nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), NULL)) { - nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (connection), - (guint64) 0, - TRUE); - } + if (connection && !nm_settings_connection_get_timestamp (connection, NULL)) + nm_settings_connection_update_timestamp (connection, (guint64) 0, TRUE); /* Schedule the transition to DISCONNECTED. The device can't transition * immediately because we can't change states again from the state @@ -8895,10 +8999,17 @@ _set_state_full (NMDevice *self, if ( (old_state == NM_DEVICE_STATE_ACTIVATED || old_state == NM_DEVICE_STATE_DEACTIVATING) && (state != NM_DEVICE_STATE_DEACTIVATING)) { - if (quitting) - nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self); - else - nm_dispatcher_call (DISPATCHER_ACTION_DOWN, nm_act_request_get_connection (req), self, NULL, NULL, NULL); + if (quitting) { + nm_dispatcher_call_sync (DISPATCHER_ACTION_DOWN, + nm_act_request_get_settings_connection (req), + nm_act_request_get_applied_connection (req), + self); + } else { + nm_dispatcher_call (DISPATCHER_ACTION_DOWN, + nm_act_request_get_settings_connection (req), + nm_act_request_get_applied_connection (req), + self, NULL, NULL, NULL); + } } /* IP-related properties are only valid when the device has IP configuration. diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index f70dca2049..441ae06b73 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -357,8 +357,11 @@ GSList * nm_device_master_get_slaves (NMDevice *dev); /* Slave */ NMDevice * nm_device_get_master (NMDevice *dev); -NMActRequest * nm_device_get_act_request (NMDevice *dev); -NMConnection * nm_device_get_connection (NMDevice *dev); +NMActRequest * nm_device_get_act_request (NMDevice *dev); +NMSettingsConnection * nm_device_get_settings_connection (NMDevice *dev); +NMConnection * nm_device_get_applied_connection (NMDevice *dev); +gboolean nm_device_has_unmodified_applied_connection (NMDevice *self, + NMSettingCompareFlags compare_flags); void nm_device_removed (NMDevice *dev); @@ -470,7 +473,7 @@ gboolean nm_device_get_nm_plugin_missing (NMDevice *self); void nm_device_set_nm_plugin_missing (NMDevice *self, gboolean missing); -void nm_device_steal_connection (NMDevice *device, NMConnection *connection); +void nm_device_steal_connection (NMDevice *device, NMSettingsConnection *connection); void nm_device_queue_activation (NMDevice *device, NMActRequest *req); @@ -498,6 +501,10 @@ const NMPlatformIP4Route *nm_device_get_ip4_default_route (NMDevice *self, gbool const NMPlatformIP6Route *nm_device_get_ip6_default_route (NMDevice *self, gboolean *out_is_assumed); void nm_device_spawn_iface_helper (NMDevice *self); + +void nm_device_reapply_settings_immediately (NMDevice *self); + +void nm_device_update_firewall_zone (NMDevice *self); void nm_device_update_metered (NMDevice *self); G_END_DECLS diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index bd41b33bf2..f20d0922f8 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -383,7 +383,7 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection, /* Attempt to respawn teamd */ if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) { - NMConnection *connection = nm_device_get_connection (device); + NMConnection *connection = nm_device_get_applied_connection (device); g_assert (connection); if (!teamd_start (device, nm_connection_get_setting_team (connection))) @@ -526,7 +526,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) if (ret != NM_ACT_STAGE_RETURN_SUCCESS) return ret; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_team = nm_connection_get_setting_team (connection); g_assert (s_team); @@ -567,7 +567,7 @@ ip4_config_pre_commit (NMDevice *self, NMIP4Config *config) NMSettingWired *s_wired; guint32 mtu; - connection = nm_device_get_connection (self); + connection = nm_device_get_applied_connection (self); g_assert (connection); s_wired = nm_connection_get_setting_wired (connection); diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index c3699da3a4..f656e4efb3 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -208,7 +208,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) GBytes *ssid; const char *anycast_addr; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_mesh = nm_connection_get_setting_olpc_mesh (connection); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index c668e1c70f..754834d872 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -318,8 +318,6 @@ get_ap_by_supplicant_path (NMDeviceWifi *self, const char *path) static void update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap) { - NMConnection *connection; - g_return_if_fail (NM_IS_DEVICE_WIFI (self)); if (ap == NULL) @@ -329,12 +327,10 @@ update_seen_bssids_cache (NMDeviceWifi *self, NMAccessPoint *ap) if (nm_ap_get_mode (ap) != NM_802_11_MODE_INFRA) return; - if (nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED) { - connection = nm_device_get_connection (NM_DEVICE (self)); - if (connection) { - nm_settings_connection_add_seen_bssid (NM_SETTINGS_CONNECTION (connection), - nm_ap_get_address (ap)); - } + if ( nm_device_get_state (NM_DEVICE (self)) == NM_DEVICE_STATE_ACTIVATED + && nm_device_has_unmodified_applied_connection (NM_DEVICE (self), NM_SETTING_COMPARE_FLAG_NONE)) { + nm_settings_connection_add_seen_bssid (nm_device_get_settings_connection (NM_DEVICE (self)), + nm_ap_get_address (ap)); } } @@ -484,15 +480,8 @@ deactivate (NMDevice *device) NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); int ifindex = nm_device_get_ifindex (device); - NMConnection *connection; NM80211Mode old_mode = priv->mode; - connection = nm_device_get_connection (device); - if (connection) { - /* Clear wireless secrets tries when deactivating */ - g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); - } - if (priv->periodic_source_id) { g_source_remove (priv->periodic_source_id); priv->periodic_source_id = 0; @@ -1164,7 +1153,7 @@ scanning_allowed (NMDeviceWifi *self) || nm_supplicant_interface_get_scanning (priv->sup_iface)) return FALSE; - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); if (connection) { NMSettingWireless *s_wifi; const char *ip4_method = NULL; @@ -1675,7 +1664,7 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) static void wifi_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId call_id, - NMConnection *connection, + NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -1686,7 +1675,7 @@ wifi_secrets_cb (NMActRequest *req, return; g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); - g_return_if_fail (nm_act_request_get_connection (req) == connection); + g_return_if_fail (nm_act_request_get_settings_connection (req) == connection); if (error) { _LOGW (LOGD_WIFI, "%s", error->message); @@ -1748,7 +1737,7 @@ need_new_8021x_secrets (NMDeviceWifi *self, g_assert (setting_name != NULL); - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_return_val_if_fail (connection != NULL, FALSE); /* 802.1x stuff only happens in the supplicant's ASSOCIATED state when it's @@ -1801,7 +1790,7 @@ need_new_wpa_psk (NMDeviceWifi *self, g_assert (setting_name != NULL); - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_return_val_if_fail (connection != NULL, FALSE); /* A bad PSK will cause the supplicant to disconnect during the 4-way handshake */ @@ -1829,7 +1818,6 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, { NMDevice *device = NM_DEVICE (self); NMActRequest *req; - NMConnection *connection; const char *setting_name = NULL; gboolean handled = FALSE; @@ -1838,13 +1826,10 @@ handle_8021x_or_psk_auth_fail (NMDeviceWifi *self, req = nm_device_get_act_request (NM_DEVICE (self)); g_return_val_if_fail (req != NULL, FALSE); - connection = nm_act_request_get_connection (req); - g_assert (connection); - if ( need_new_8021x_secrets (self, old_state, &setting_name) || need_new_wpa_psk (self, old_state, &setting_name)) { - nm_connection_clear_secrets (connection); + nm_act_request_clear_secrets (req); _LOGI (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) disconnected during association, asking for new key"); @@ -1914,7 +1899,7 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, NMSettingWireless *s_wifi; GBytes *ssid; - connection = nm_device_get_connection (NM_DEVICE (self)); + connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_return_if_fail (connection); s_wifi = nm_connection_get_setting_wireless (connection); @@ -2090,7 +2075,7 @@ handle_auth_or_fail (NMDeviceWifi *self, { const char *setting_name; guint32 tries; - NMConnection *connection; + NMConnection *applied_connection; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -2100,17 +2085,16 @@ handle_auth_or_fail (NMDeviceWifi *self, g_assert (req); } - connection = nm_act_request_get_connection (req); - g_assert (connection); + applied_connection = nm_act_request_get_applied_connection (req); - tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES)); + tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES)); if (tries > 3) return NM_ACT_STAGE_RETURN_FAILURE; nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - nm_connection_clear_secrets (connection); - setting_name = nm_connection_need_secrets (connection, NULL); + nm_act_request_clear_secrets (req); + setting_name = nm_connection_need_secrets (applied_connection, NULL); if (setting_name) { NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; @@ -2118,7 +2102,7 @@ handle_auth_or_fail (NMDeviceWifi *self, flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); - g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); + g_object_set_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); ret = NM_ACT_STAGE_RETURN_POSTPONE; } else _LOGW (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); @@ -2155,7 +2139,7 @@ supplicant_connection_timeout_cb (gpointer user_data) req = nm_device_get_act_request (device); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); if ( priv->mode == NM_802_11_MODE_ADHOC @@ -2292,7 +2276,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) req = nm_device_get_act_request (NM_DEVICE (self)); g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); s_wireless = nm_connection_get_setting_wireless (connection); @@ -2420,7 +2404,7 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) goto out; } - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); s_wireless = nm_connection_get_setting_wireless (connection); @@ -2518,7 +2502,7 @@ act_stage3_ip4_config_start (NMDevice *device, NMSettingIPConfig *s_ip4; const char *method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); if (s_ip4) @@ -2540,7 +2524,7 @@ act_stage3_ip6_config_start (NMDevice *device, NMSettingIPConfig *s_ip6; const char *method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) @@ -2561,7 +2545,7 @@ ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) NMSettingWireless *s_wifi; guint32 mtu; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); @@ -2648,7 +2632,7 @@ act_stage4_ip4_config_timeout (NMDevice *device, NMDeviceStateReason *reason) gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -2669,7 +2653,7 @@ act_stage4_ip6_config_timeout (NMDevice *device, NMDeviceStateReason *reason) gboolean may_fail = FALSE, chain_up = FALSE; NMActStageReturn ret; - connection = nm_device_get_connection (device); + connection = nm_device_get_applied_connection (device); g_assert (connection); s_ip6 = nm_connection_get_setting_ip6_config (connection); @@ -2689,19 +2673,18 @@ activation_success_handler (NMDevice *device) NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); int ifindex = nm_device_get_ifindex (device); NMActRequest *req; - NMConnection *connection; + NMConnection *applied_connection; req = nm_device_get_act_request (device); g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); + applied_connection = nm_act_request_get_applied_connection (req); /* Clear any critical protocol notification in the wifi stack */ nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, ifindex, FALSE); /* Clear wireless secrets tries on success */ - g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); + g_object_set_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES, NULL); /* There should always be a current AP, either a fake one because we haven't * seen a scan result for the activated AP yet, or a real one from the @@ -2744,13 +2727,13 @@ activation_success_handler (NMDevice *device) static void activation_failure_handler (NMDevice *device) { - NMConnection *connection; + NMConnection *applied_connection; - connection = nm_device_get_connection (device); - g_assert (connection); + applied_connection = nm_device_get_applied_connection (device); + g_assert (applied_connection); /* Clear wireless secrets tries on failure */ - g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, NULL); + g_object_set_data (G_OBJECT (applied_connection), WIRELESS_SECRETS_TRIES, NULL); /* Clear any critical protocol notification in the wifi stack */ nm_platform_wifi_indicate_addressing_running (NM_PLATFORM_GET, nm_device_get_ifindex (device), FALSE); diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index b875080b4b..3a85d58fa9 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -330,7 +330,7 @@ device_state_changed (NMDevice *device, { NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMConnection *connection = nm_device_get_connection (device); + NMConnection *connection = nm_device_get_applied_connection (device); g_assert (priv->modem); diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 71c2323983..7e70ba5608 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -30,6 +30,7 @@ #include "nm-device-private.h" #include "nm-modem-enum-types.h" #include "nm-route-manager.h" +#include "gsystem-local-alloc.h" G_DEFINE_TYPE (NMModem, nm_modem, G_TYPE_OBJECT) @@ -490,7 +491,7 @@ ppp_stage3_ip_config_start (NMModem *self, return NM_ACT_STAGE_RETURN_POSTPONE; if (NM_MODEM_GET_CLASS (self)->get_user_pass) { - NMConnection *connection = nm_act_request_get_connection (req); + NMConnection *connection = nm_act_request_get_applied_connection (req); g_assert (connection); if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &ppp_name, NULL)) @@ -560,7 +561,7 @@ nm_modem_stage3_ip4_config_start (NMModem *self, req = nm_device_get_act_request (device); g_assert (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); @@ -677,7 +678,7 @@ nm_modem_stage3_ip6_config_start (NMModem *self, g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -728,7 +729,7 @@ cancel_get_secrets (NMModem *self) static void modem_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId call_id, - NMConnection *connection, + NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -797,7 +798,7 @@ nm_modem_act_stage1_prepare (NMModem *self, g_object_unref (priv->act_request); priv->act_request = g_object_ref (req); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); setting_name = nm_connection_need_secrets (connection, &hints); diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 90590838c0..173dc19fd7 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -65,25 +65,52 @@ enum { /*******************************************************************/ +NMSettingsConnection * +nm_act_request_get_settings_connection (NMActRequest *req) +{ + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); + + return nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req)); +} + NMConnection * -nm_act_request_get_connection (NMActRequest *req) +nm_act_request_get_applied_connection (NMActRequest *req) { g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NULL); - return nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (req)); + return nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); } /*******************************************************************/ struct _NMActRequestGetSecretsCallId { NMActRequest *self; - NMSettingsConnectionCallId call_id_s; NMActRequestSecretsFunc callback; gpointer callback_data; + NMSettingsConnectionCallId call_id; }; typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo; +static GetSecretsInfo * +_get_secrets_info_new (NMActRequest *self, NMActRequestSecretsFunc callback, gpointer callback_data) +{ + GetSecretsInfo *info; + + info = g_slice_new0 (GetSecretsInfo); + info->self = self; + info->callback = callback; + info->callback_data = callback_data; + + return info; +} + +static void +_get_secrets_info_free (GetSecretsInfo *info) +{ + g_slice_free (GetSecretsInfo, info); +} + static void get_secrets_cb (NMSettingsConnection *connection, NMSettingsConnectionCallId call_id_s, @@ -93,16 +120,24 @@ get_secrets_cb (NMSettingsConnection *connection, gpointer user_data) { GetSecretsInfo *info = user_data; - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); + NMActRequestPrivate *priv; + + g_return_if_fail (info && info->call_id == call_id_s); + g_return_if_fail (NM_IS_ACT_REQUEST (info->self)); + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); - g_return_if_fail (info->call_id_s == call_id_s); g_return_if_fail (g_slist_find (priv->secrets_calls, info)); priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); if (info->callback) - info->callback (info->self, info, NM_CONNECTION (connection), error, info->callback_data); - g_free (info); + info->callback (info->self, info, connection, error, info->callback_data); + + _get_secrets_info_free (info); } /** @@ -135,57 +170,92 @@ nm_act_request_get_secrets (NMActRequest *self, NMActRequestPrivate *priv; GetSecretsInfo *info; NMSettingsConnectionCallId call_id_s; - NMConnection *connection; + NMSettingsConnection *settings_connection; + NMConnection *applied_connection; const char *hints[2] = { hint, NULL }; - g_return_val_if_fail (self, 0); g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); priv = NM_ACT_REQUEST_GET_PRIVATE (self); - info = g_malloc0 (sizeof (GetSecretsInfo)); - info->self = self; - info->callback = callback; - info->callback_data = callback_data; + settings_connection = nm_act_request_get_settings_connection (self); + applied_connection = nm_act_request_get_applied_connection (self); + + info = _get_secrets_info_new (self, callback, callback_data); + + priv->secrets_calls = g_slist_append (priv->secrets_calls, info); if (nm_active_connection_get_user_requested (NM_ACTIVE_CONNECTION (self))) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED; - connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self)); - call_id_s = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection), + call_id_s = nm_settings_connection_get_secrets (settings_connection, + applied_connection, nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)), setting_name, flags, hints, get_secrets_cb, - info, - NULL); - if (call_id_s) { - info->call_id_s = call_id_s; - priv->secrets_calls = g_slist_append (priv->secrets_calls, info); - } else - g_free (info); - + info); + info->call_id = call_id_s; + g_return_val_if_fail (call_id_s, NULL); return info; } +static void +_do_cancel_secrets (NMActRequest *self, GetSecretsInfo *info, gboolean is_disposing) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + nm_assert (info && info->self == self); + nm_assert (g_slist_find (priv->secrets_calls, info)); + + priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); + + nm_settings_connection_cancel_secrets (nm_act_request_get_settings_connection (self), info->call_id); + + if (info->callback) { + gs_free_error GError *error = NULL; + + if (is_disposing) { + /* Use a different error code. G_IO_ERROR_CANCELLED is only used synchronously + * when the user calls nm_act_request_cancel_secrets(). Disposing the instance + * with pending requests also cancels the requests, but with a different error + * code. */ + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Disposing NMActRequest instance"); + } else { + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Request cancelled"); + } + + info->callback (self, info, NULL, error, info->callback_data); + } + + _get_secrets_info_free (info); +} + void nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id) { NMActRequestPrivate *priv; - NMConnection *connection; - g_return_if_fail (self); g_return_if_fail (NM_IS_ACT_REQUEST (self)); g_return_if_fail (call_id); priv = NM_ACT_REQUEST_GET_PRIVATE (self); - if (g_slist_find (priv->secrets_calls, call_id)) + if (!g_slist_find (priv->secrets_calls, call_id)) g_return_if_reached (); - connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self)); - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), call_id->call_id_s); + _do_cancel_secrets (self, call_id, FALSE); +} + +void +nm_act_request_clear_secrets (NMActRequest *self) +{ + g_return_if_fail (NM_IS_ACT_REQUEST (self)); + + nm_active_connection_clear_secrets ((NMActiveConnection *) self); } /********************************************************************/ @@ -405,7 +475,7 @@ master_failed (NMActiveConnection *self) /** * nm_act_request_new: * - * @connection: the connection to activate @device with + * @settings_connection: (allow-none): the connection to activate @device with * @specific_object: the object path of the specific object (ie, WiFi access point, * etc) that will be used to activate @connection and @device * @subject: the #NMAuthSubject representing the requestor of the activation @@ -418,17 +488,17 @@ master_failed (NMActiveConnection *self) * Returns: the new activation request on success, %NULL on error. */ NMActRequest * -nm_act_request_new (NMConnection *connection, +nm_act_request_new (NMSettingsConnection *settings_connection, const char *specific_object, NMAuthSubject *subject, NMDevice *device) { - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); g_return_val_if_fail (!device || NM_IS_DEVICE (device), NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); return (NMActRequest *) g_object_new (NM_TYPE_ACT_REQUEST, - NM_ACTIVE_CONNECTION_INT_CONNECTION, connection, + NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, settings_connection, NM_ACTIVE_CONNECTION_INT_DEVICE, device, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, NM_ACTIVE_CONNECTION_INT_SUBJECT, subject, @@ -443,8 +513,12 @@ nm_act_request_init (NMActRequest *req) static void dispose (GObject *object) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - NMConnection *connection; + NMActRequest *self = NM_ACT_REQUEST (object); + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + /* Kill any in-progress secrets requests */ + while (priv->secrets_calls) + _do_cancel_secrets (self, priv->secrets_calls->data, TRUE); /* Clear any share rules */ if (priv->share_rules) { @@ -452,16 +526,6 @@ dispose (GObject *object) clear_share_rules (NM_ACT_REQUEST (object)); } - /* Kill any in-progress secrets requests */ - connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (object)); - while (priv->secrets_calls) { - GetSecretsInfo *info = priv->secrets_calls->data; - - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id_s); - - g_return_if_fail (!priv->secrets_calls || info != priv->secrets_calls->data); - } - G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 8c990d520f..929ce195f2 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -47,26 +47,28 @@ typedef struct { GType nm_act_request_get_type (void); -NMActRequest *nm_act_request_new (NMConnection *connection, +NMActRequest *nm_act_request_new (NMSettingsConnection *settings_connection, const char *specific_object, NMAuthSubject *subject, NMDevice *device); -NMConnection *nm_act_request_get_connection (NMActRequest *req); +NMSettingsConnection *nm_act_request_get_settings_connection (NMActRequest *req); -gboolean nm_act_request_get_shared (NMActRequest *req); +NMConnection *nm_act_request_get_applied_connection (NMActRequest *req); -void nm_act_request_set_shared (NMActRequest *req, gboolean shared); +gboolean nm_act_request_get_shared (NMActRequest *req); -void nm_act_request_add_share_rule (NMActRequest *req, - const char *table, - const char *rule); +void nm_act_request_set_shared (NMActRequest *req, gboolean shared); + +void nm_act_request_add_share_rule (NMActRequest *req, + const char *table, + const char *rule); /* Secrets handling */ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, NMActRequestGetSecretsCallId call_id, - NMConnection *connection, + NMSettingsConnection *connection, GError *error, gpointer user_data); @@ -78,6 +80,7 @@ NMActRequestGetSecretsCallId nm_act_request_get_secrets (NMActRequest *req, gpointer callback_data); void nm_act_request_cancel_secrets (NMActRequest *req, NMActRequestGetSecretsCallId call_id); +void nm_act_request_clear_secrets (NMActRequest *self); #endif /* __NETWORKMANAGER_ACTIVATION_REQUEST_H__ */ diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 4b147f750c..aa892cc711 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -25,9 +25,11 @@ #include "nm-dbus-interface.h" #include "nm-device.h" #include "nm-settings-connection.h" +#include "nm-simple-connection.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "NetworkManagerUtils.h" +#include "nm-core-internal.h" #include "nmdbus-active-connection.h" @@ -39,7 +41,8 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT NMActiveConnectionPrivate)) typedef struct { - NMConnection *connection; + NMSettingsConnection *settings_connection; + NMConnection *applied_connection; char *specific_object; NMDevice *device; @@ -82,7 +85,7 @@ enum { PROP_VPN, PROP_MASTER, - PROP_INT_CONNECTION, + PROP_INT_SETTINGS_CONNECTION, PROP_INT_DEVICE, PROP_INT_SUBJECT, PROP_INT_MASTER, @@ -173,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); } @@ -206,53 +209,120 @@ 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_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) +NMSettingsConnection * +_nm_active_connection_get_settings_connection (NMActiveConnection *self) { g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - return nm_connection_get_uuid (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection; } -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; + 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; } -const char * -nm_active_connection_get_connection_type (NMActiveConnection *self) +NMConnection * +nm_active_connection_get_applied_connection (NMActiveConnection *self) { - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMConnection *con; + + 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->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, - NMConnection *connection) +nm_active_connection_set_settings_connection (NMActiveConnection *self, + NMSettingsConnection *connection) { - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMActiveConnectionPrivate *priv; - /* Can't change connection after the ActiveConnection is exported over D-Bus */ + 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 (!priv->settings_connection); + g_return_if_fail (!priv->applied_connection); + + /* Can't change connection after the ActiveConnection is exported over D-Bus. + * + * 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)); + nm_connection_clear_secrets (priv->applied_connection); } +gboolean +nm_active_connection_has_unmodified_applied_connection (NMActiveConnection *self, NMSettingCompareFlags compare_flags) +{ + 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 (priv->settings_connection, FALSE); + + return nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection, + priv->applied_connection, + compare_flags); +} + +/*******************************************************************/ + +void +nm_active_connection_clear_secrets (NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv; + + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection, + priv->applied_connection, + NM_SETTING_COMPARE_FLAG_NONE)) + nm_connection_clear_secrets ((NMConnection *) priv->settings_connection); + nm_connection_clear_secrets (priv->applied_connection); +} + +/*******************************************************************/ + const char * nm_active_connection_get_specific_object (NMActiveConnection *self) { @@ -572,7 +642,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, @@ -667,6 +737,9 @@ done: /** * nm_active_connection_authorize: * @self: the #NMActiveConnection + * @initial_connection: (allow-none): for add-and-activate, there + * is no @settings_connection available when creating the active connection. + * Instead pass an alternative connection. * @result_func: function to be called on success or error * @user_data1: pointer passed to @result_func * @user_data2: additional pointer passed to @result_func @@ -677,16 +750,29 @@ done: */ void nm_active_connection_authorize (NMActiveConnection *self, + NMConnection *initial_connection, NMActiveConnectionAuthResultFunc result_func, gpointer user_data1, gpointer user_data2) { 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); + if (initial_connection) { + g_return_if_fail (NM_IS_CONNECTION (initial_connection)); + g_return_if_fail (!priv->settings_connection); + g_return_if_fail (!priv->applied_connection); + con = initial_connection; + } else { + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection)); + g_return_if_fail (NM_IS_CONNECTION (priv->applied_connection)); + con = priv->applied_connection; + } + priv->chain = nm_auth_chain_new_subject (priv->subject, NULL, auth_done, self); g_assert (priv->chain); @@ -694,7 +780,7 @@ 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->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); @@ -717,24 +803,32 @@ static void constructed (GObject *object) { NMActiveConnection *self = (NMActiveConnection *) object; + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); - g_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (object)->subject); _LOGD ("constructed (%s)", G_OBJECT_TYPE_NAME (self)); + + g_return_if_fail (priv->subject); } 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; + NMSettingsConnection *con; switch (prop_id) { - case PROP_INT_CONNECTION: - g_warn_if_fail (priv->connection == NULL); - priv->connection = g_value_dup_object (value); + case PROP_INT_SETTINGS_CONNECTION: + /* construct-only */ + con = g_value_get_object (value); + if (con) { + priv->settings_connection = g_object_ref (con); + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (con)); + nm_connection_clear_secrets (priv->applied_connection); + } break; case PROP_INT_DEVICE: nm_active_connection_set_device (NM_ACTIVE_CONNECTION (object), g_value_get_object (value)); @@ -778,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 (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 (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 (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 (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 : "/"); @@ -883,7 +977,8 @@ dispose (GObject *object) g_free (priv->specific_object); priv->specific_object = NULL; - g_clear_object (&priv->connection); + g_clear_object (&priv->settings_connection); + g_clear_object (&priv->applied_connection); _device_cleanup (self); @@ -1024,10 +1119,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) /* Internal properties */ g_object_class_install_property - (object_class, PROP_INT_CONNECTION, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_CONNECTION, "", "", - NM_TYPE_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + (object_class, PROP_INT_SETTINGS_CONNECTION, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, "", "", + NM_TYPE_SETTINGS_CONNECTION, + 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 ccdc563f06..f57f2081f1 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -49,7 +49,7 @@ #define NM_ACTIVE_CONNECTION_MASTER "master" /* Internal non-exported properties */ -#define NM_ACTIVE_CONNECTION_INT_CONNECTION "int-connection" +#define NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION "int-settings-connection" #define NM_ACTIVE_CONNECTION_INT_DEVICE "int-device" #define NM_ACTIVE_CONNECTION_INT_SUBJECT "int-subject" #define NM_ACTIVE_CONNECTION_INT_MASTER "int-master" @@ -92,20 +92,23 @@ typedef void (*NMActiveConnectionAuthResultFunc) (NMActiveConnection *self, gpointer user_data2); void nm_active_connection_authorize (NMActiveConnection *self, + NMConnection *initial_connection, NMActiveConnectionAuthResultFunc result_func, gpointer user_data1, gpointer user_data2); -NMConnection *nm_active_connection_get_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, - NMConnection *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_has_unmodified_applied_connection (NMActiveConnection *self, + NMSettingCompareFlags compare_flags); -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); @@ -147,4 +150,6 @@ void nm_active_connection_set_assumed (NMActiveConnection *self, gboolean nm_active_connection_get_assumed (NMActiveConnection *self); +void nm_active_connection_clear_secrets (NMActiveConnection *self); + #endif /* __NETWORKMANAGER_ACTIVE_CONNECTION_H__ */ diff --git a/src/nm-audit-manager.c b/src/nm-audit-manager.c index 929800d96a..de4e56c254 100644 --- a/src/nm-audit-manager.c +++ b/src/nm-audit-manager.c @@ -33,6 +33,7 @@ #include "nm-config.h" #include "nm-logging.h" #include "nm-macros-internal.h" +#include "nm-settings-connection.h" #define AUDIT_LOG_LEVEL LOGL_INFO @@ -213,7 +214,7 @@ nm_audit_manager_audit_enabled (NMAuditManager *self) void _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line, - const char *func, const char *op, NMConnection *connection, + const char *func, const char *op, NMSettingsConnection *connection, gboolean result, NMAuthSubject *subject, const char *reason) { gs_unref_ptrarray GPtrArray *fields = NULL; @@ -224,11 +225,11 @@ _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, gui fields = g_ptr_array_new (); if (connection) { - _audit_field_init_string (&uuid_field, "uuid", nm_connection_get_uuid (connection), + _audit_field_init_string (&uuid_field, "uuid", nm_settings_connection_get_uuid (connection), FALSE, BACKEND_ALL); g_ptr_array_add (fields, &uuid_field); - _audit_field_init_string (&name_field, "name", nm_connection_get_id (connection), + _audit_field_init_string (&name_field, "name", nm_settings_connection_get_id (connection), TRUE, BACKEND_ALL); g_ptr_array_add (fields, &name_field); } diff --git a/src/nm-audit-manager.h b/src/nm-audit-manager.h index 0a74dc063c..78333c8bed 100644 --- a/src/nm-audit-manager.h +++ b/src/nm-audit-manager.h @@ -98,7 +98,7 @@ gboolean nm_audit_manager_audit_enabled (NMAuditManager *self); } G_STMT_END void _nm_audit_manager_log_connection_op (NMAuditManager *self, const char *file, guint line, - const char *func, const char *op, NMConnection *connection, + const char *func, const char *op, NMSettingsConnection *connection, gboolean result, NMAuthSubject *subject, const char *reason); void _nm_audit_manager_log_control_op (NMAuditManager *self, const char *file, guint line, diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index b06625311a..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 ? '+' : '-') @@ -757,7 +757,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, } else synced = default_route && !is_assumed; } else { - NMConnection *connection = nm_active_connection_get_connection ((NMActiveConnection *) vpn); + NMConnection *connection = nm_active_connection_get_applied_connection ((NMActiveConnection *) vpn); if ( connection && nm_vpn_connection_get_vpn_state (vpn) == NM_VPN_CONNECTION_STATE_ACTIVATED) { @@ -1026,7 +1026,7 @@ _ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager * || state >= NM_DEVICE_STATE_DEACTIVATING) continue; - if (!_ipx_connection_has_default_route (vtable, self, nm_device_get_connection (device), NULL)) + if (!_ipx_connection_has_default_route (vtable, self, nm_device_get_applied_connection (device), NULL)) continue; prio = nm_device_get_ip4_route_metric (device); diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index 0a39ed7995..af62192a01 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -437,7 +437,8 @@ dispatcher_idle_cb (gpointer user_data) static gboolean _dispatcher_call (DispatcherAction action, gboolean blocking, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *device, const char *vpn_iface, NMIP4Config *vpn_ip4_config, @@ -510,29 +511,33 @@ _dispatcher_call (DispatcherAction action, goto done; } - if (connection) { - const char *filename; + if (applied_connection) + connection_dict = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + else + connection_dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); - connection_dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT); + if (settings_connection) { + const char *connection_path; + const char *filename; - g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&connection_props, "{sv}", - NMD_CONNECTION_PROPS_PATH, - g_variant_new_object_path (nm_connection_get_path (connection))); - filename = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection)); + connection_path = nm_connection_get_path (NM_CONNECTION (settings_connection)); + if (connection_path) { + g_variant_builder_add (&connection_props, "{sv}", + NMD_CONNECTION_PROPS_PATH, + g_variant_new_object_path (connection_path)); + } + filename = nm_settings_connection_get_filename (settings_connection); if (filename) { g_variant_builder_add (&connection_props, "{sv}", NMD_CONNECTION_PROPS_FILENAME, g_variant_new_string (filename)); } - if (nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) { + if (nm_settings_connection_get_nm_generated_assumed (settings_connection)) { g_variant_builder_add (&connection_props, "{sv}", NMD_CONNECTION_PROPS_EXTERNAL, g_variant_new_boolean (TRUE)); } - } else { - connection_dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); - g_variant_builder_init (&connection_props, G_VARIANT_TYPE_VARDICT); } g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT); @@ -639,7 +644,8 @@ done: /** * nm_dispatcher_call: * @action: the %DispatcherAction - * @connection: the #NMConnection the action applies to + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @device: the #NMDevice the action applies to * @callback: a caller-supplied callback to execute when done * @user_data: caller-supplied pointer passed to @callback @@ -653,20 +659,22 @@ done: */ gboolean nm_dispatcher_call (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *device, DispatcherFunc callback, gpointer user_data, guint *out_call_id) { - return _dispatcher_call (action, FALSE, connection, device, NULL, NULL, + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device, NULL, NULL, NULL, callback, user_data, out_call_id); } /** * nm_dispatcher_call_sync(): * @action: the %DispatcherAction - * @connection: the #NMConnection the action applies to + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @device: the #NMDevice the action applies to * * This method always invokes the dispatcher action synchronously and it may @@ -676,17 +684,19 @@ nm_dispatcher_call (DispatcherAction action, */ gboolean nm_dispatcher_call_sync (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *device) { - return _dispatcher_call (action, TRUE, connection, device, NULL, NULL, + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device, NULL, NULL, NULL, NULL, NULL, NULL); } /** * nm_dispatcher_call_vpn(): * @action: the %DispatcherAction - * @connection: the #NMConnection the action applies to + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection * @vpn_iface: the IP interface of the VPN tunnel, if any * @vpn_ip4_config: the #NMIP4Config of the VPN connection @@ -703,7 +713,8 @@ nm_dispatcher_call_sync (DispatcherAction action, */ gboolean nm_dispatcher_call_vpn (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, NMIP4Config *vpn_ip4_config, @@ -712,14 +723,15 @@ nm_dispatcher_call_vpn (DispatcherAction action, gpointer user_data, guint *out_call_id) { - return _dispatcher_call (action, FALSE, connection, parent_device, vpn_iface, + return _dispatcher_call (action, FALSE, settings_connection, applied_connection, parent_device, vpn_iface, vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id); } /** * nm_dispatcher_call_vpn_sync(): * @action: the %DispatcherAction - * @connection: the #NMConnection the action applies to + * @settings_connection: the #NMSettingsConnection the action applies to + * @applied_connection: the currently applied connection * @parent_device: the parent #NMDevice of the VPN connection * @vpn_iface: the IP interface of the VPN tunnel, if any * @vpn_ip4_config: the #NMIP4Config of the VPN connection @@ -732,13 +744,14 @@ nm_dispatcher_call_vpn (DispatcherAction action, */ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, NMIP4Config *vpn_ip4_config, NMIP6Config *vpn_ip6_config) { - return _dispatcher_call (action, TRUE, connection, parent_device, vpn_iface, + return _dispatcher_call (action, TRUE, settings_connection, applied_connection, parent_device, vpn_iface, vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL); } diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h index 94f48ab168..42dcdc46e9 100644 --- a/src/nm-dispatcher.h +++ b/src/nm-dispatcher.h @@ -44,18 +44,21 @@ typedef enum { typedef void (*DispatcherFunc) (guint call_id, gpointer user_data); gboolean nm_dispatcher_call (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *device, DispatcherFunc callback, gpointer user_data, guint *out_call_id); gboolean nm_dispatcher_call_sync (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *device); gboolean nm_dispatcher_call_vpn (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, NMIP4Config *vpn_ip4_config, @@ -65,7 +68,8 @@ gboolean nm_dispatcher_call_vpn (DispatcherAction action, guint *out_call_id); gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action, - NMConnection *connection, + NMSettingsConnection *settings_connection, + NMConnection *applied_connection, NMDevice *parent_device, const char *vpn_iface, NMIP4Config *vpn_ip4_config, diff --git a/src/nm-manager.c b/src/nm-manager.c index aafa8d37bf..d19155e7c4 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -74,7 +74,7 @@ static void rfkill_change (const char *desc, RfKillType rtype, gboolean enabled) static gboolean find_master (NMManager *self, NMConnection *connection, NMDevice *device, - NMConnection **out_master_connection, + NMSettingsConnection **out_master_connection, NMDevice **out_master_device, NMActiveConnection **out_master_ac, GError **error); @@ -83,6 +83,7 @@ static void nm_manager_update_state (NMManager *manager); #define SSD_POKE_INTERVAL 120 #define ORIGDEV_TAG "originating-device" +#define TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE "act-con-add-and-activate" typedef struct { gboolean user_enabled; @@ -209,7 +210,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) /* FIXME: switch to a GList for faster removal */ found = g_slist_find (priv->active_connections, active); if (found) { - NMConnection *connection; + NMSettingsConnection *connection; priv->active_connections = g_slist_remove (priv->active_connections, active); g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active); @@ -217,8 +218,8 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self); if ( nm_active_connection_get_assumed (active) - && (connection = nm_active_connection_get_connection (active)) - && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + && (connection = nm_active_connection_get_settings_connection (active)) + && nm_settings_connection_get_nm_generated_assumed (connection)) g_object_ref (connection); else connection = NULL; @@ -228,7 +229,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) if ( connection && nm_settings_has_connection (priv->settings, connection)) { nm_log_dbg (LOGD_DEVICE, "Assumed connection disconnected. Deleting generated connection '%s' (%s)", - nm_connection_get_id (connection), nm_connection_get_uuid (connection)); + nm_settings_connection_get_id (connection), nm_settings_connection_get_uuid (connection)); nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); g_object_unref (connection); } @@ -340,19 +341,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; - if ( !strcmp (nm_connection_get_uuid (ac_connection), uuid) - && (ac_state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)) + con = nm_active_connection_get_settings_connection (ac); + + /* 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; } @@ -371,12 +383,12 @@ nm_manager_get_activatable_connections (NMManager *manager) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); GSList *all_connections = nm_settings_get_connections (priv->settings); GSList *connections = NULL, *iter; - NMConnection *connection; + NMSettingsConnection *connection; for (iter = all_connections; iter; iter = iter->next) { connection = iter->data; - if (!find_ac_for_connection (manager, connection)) + if (!find_ac_for_connection (manager, NM_CONNECTION (connection))) connections = g_slist_prepend (connections, connection); } @@ -821,7 +833,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMDeviceFactory *factory; const char *parent_name = NULL; - NMConnection *parent_connection; + NMSettingsConnection *parent_connection; NMDevice *parent, *first_compatible = NULL; GSList *iter; @@ -844,7 +856,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection) return parent; /* Maybe a connection UUID */ - parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, parent_name); + parent_connection = nm_settings_get_connection_by_uuid (priv->settings, parent_name); if (!parent_connection) return NULL; @@ -854,11 +866,11 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection) for (iter = priv->devices; iter; iter = iter->next) { NMDevice *candidate = iter->data; - if (nm_device_get_connection (candidate) == parent_connection) + if (nm_device_get_settings_connection (candidate) == parent_connection) return candidate; if ( !first_compatible - && nm_device_check_connection_compatible (candidate, parent_connection)) + && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection))) first_compatible = candidate; } @@ -1438,12 +1450,13 @@ match_connection_filter (NMConnection *connection, gpointer user_data) * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if * the device does not support assuming existing connections. */ -static NMConnection * +static NMSettingsConnection * get_existing_connection (NMManager *manager, NMDevice *device, gboolean *out_generated) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); gs_free_slist GSList *connections = nm_manager_get_activatable_connections (manager); - NMConnection *connection = NULL, *matched; + NMConnection *connection = NULL; + NMSettingsConnection *matched; NMSettingsConnection *added = NULL; GError *error = NULL; NMDevice *master = NULL; @@ -1492,15 +1505,15 @@ get_existing_connection (NMManager *manager, NMDevice *device, gboolean *out_gen * the generated connection instead. */ connections = g_slist_reverse (g_slist_sort (connections, nm_settings_sort_connections)); - matched = nm_utils_match_connection (connections, - connection, - nm_device_has_carrier (device), - match_connection_filter, - device); + matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, + connection, + nm_device_has_carrier (device), + match_connection_filter, + device)); if (matched) { nm_log_info (LOGD_DEVICE, "(%s): found matching connection '%s'", nm_device_get_iface (device), - nm_connection_get_id (matched)); + nm_settings_connection_get_id (matched)); g_object_unref (connection); return matched; } @@ -1526,11 +1539,11 @@ get_existing_connection (NMManager *manager, NMDevice *device, gboolean *out_gen } g_object_unref (connection); - return added ? NM_CONNECTION (added) : NULL; + return added ? added : NULL; } static gboolean -assume_connection (NMManager *self, NMDevice *device, NMConnection *connection) +assume_connection (NMManager *self, NMDevice *device, NMSettingsConnection *connection) { NMActiveConnection *active, *master_ac; NMAuthSubject *subject; @@ -1548,12 +1561,12 @@ assume_connection (NMManager *self, NMDevice *device, NMConnection *connection) g_return_val_if_fail (nm_device_get_state (device) >= NM_DEVICE_STATE_DISCONNECTED, FALSE); subject = nm_auth_subject_new_internal (); - active = _new_active_connection (self, connection, NULL, device, subject, &error); + active = _new_active_connection (self, NM_CONNECTION (connection), NULL, device, subject, &error); g_object_unref (subject); if (!active) { nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s", - nm_connection_get_path (connection), + nm_connection_get_path (NM_CONNECTION (connection)), error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_error_free (error); @@ -1562,7 +1575,7 @@ assume_connection (NMManager *self, NMDevice *device, NMConnection *connection) /* If the device is a slave or VLAN, find the master ActiveConnection */ master_ac = NULL; - if (find_master (self, connection, device, NULL, NULL, &master_ac, NULL) && master_ac) + if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac) nm_active_connection_set_master (active, master_ac); nm_active_connection_set_assumed (active, TRUE); @@ -1578,7 +1591,7 @@ static gboolean recheck_assume_connection (NMDevice *device, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); - NMConnection *connection; + NMSettingsConnection *connection; gboolean was_unmanaged = FALSE, success, generated; NMDeviceState state; @@ -1624,7 +1637,7 @@ recheck_assume_connection (NMDevice *device, gpointer user_data) nm_log_dbg (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection", nm_device_get_iface (device)); - nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); + nm_settings_connection_delete (connection, NULL, NULL); } } @@ -2141,7 +2154,7 @@ static gboolean find_master (NMManager *self, NMConnection *connection, NMDevice *device, - NMConnection **out_master_connection, + NMSettingsConnection **out_master_connection, NMDevice **out_master_device, NMActiveConnection **out_master_ac, GError **error) @@ -2150,7 +2163,7 @@ find_master (NMManager *self, NMSettingConnection *s_con; const char *master; NMDevice *master_device = NULL; - NMConnection *master_connection = NULL; + NMSettingsConnection *master_connection = NULL; GSList *iter, *connections = NULL; s_con = nm_connection_get_setting_connection (connection); @@ -2169,8 +2182,8 @@ find_master (NMManager *self, return FALSE; } - master_connection = nm_device_get_connection (master_device); - if (master_connection && !is_compatible_with_slave (master_connection, connection)) { + master_connection = nm_device_get_settings_connection (master_device); + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection on %s is not a valid master for '%s'", nm_device_get_iface (master_device), @@ -2179,7 +2192,7 @@ find_master (NMManager *self, } } else { /* Try master as a connection UUID */ - master_connection = (NMConnection *) nm_settings_get_connection_by_uuid (priv->settings, master); + master_connection = nm_settings_get_connection_by_uuid (priv->settings, master); if (master_connection) { /* Check if the master connection is activated on some device already */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { @@ -2188,7 +2201,7 @@ find_master (NMManager *self, if (candidate == device) continue; - if (nm_device_get_connection (candidate) == master_connection) { + if (nm_device_get_settings_connection (candidate) == master_connection) { master_device = candidate; break; } @@ -2201,11 +2214,11 @@ find_master (NMManager *self, */ connections = nm_manager_get_activatable_connections (self); for (iter = connections; iter && !master_connection; iter = g_slist_next (iter)) { - NMConnection *candidate = iter->data; + NMSettingsConnection *candidate = iter->data; char *vname; - vname = get_virtual_iface_name (self, candidate, NULL, NULL); - if (g_strcmp0 (master, vname) == 0 && is_compatible_with_slave (candidate, connection)) + vname = get_virtual_iface_name (self, NM_CONNECTION (candidate), NULL, NULL); + if (g_strcmp0 (master, vname) == 0 && is_compatible_with_slave (NM_CONNECTION (candidate), connection)) master_connection = candidate; g_free (vname); } @@ -2218,7 +2231,7 @@ find_master (NMManager *self, if (out_master_device) *out_master_device = master_device; if (out_master_ac && master_connection) - *out_master_ac = find_ac_for_connection (self, master_connection); + *out_master_ac = find_ac_for_connection (self, NM_CONNECTION (master_connection)); if (master_device || master_connection) return TRUE; @@ -2262,7 +2275,7 @@ ensure_master_active_connection (NMManager *self, NMAuthSubject *subject, NMConnection *connection, NMDevice *device, - NMConnection *master_connection, + NMSettingsConnection *master_connection, NMDevice *master_device, GError **error) { @@ -2278,13 +2291,13 @@ ensure_master_active_connection (NMManager *self, * compatible connection. If it's already activating we can just proceed. */ if (master_device) { - NMConnection *device_connection = nm_device_get_connection (master_device); + NMSettingsConnection *device_connection = nm_device_get_settings_connection (master_device); /* If we're passed a connection and a device, we require that connection * be already activated on the device, eg returned from find_master(). */ g_assert (!master_connection || master_connection == device_connection); - if (device_connection && !is_compatible_with_slave (device_connection, connection)) { + if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection on %s is not a valid master for '%s'", nm_device_get_iface (master_device), @@ -2311,15 +2324,15 @@ ensure_master_active_connection (NMManager *self, /* Find a compatible connection and activate this device using it */ connections = nm_manager_get_activatable_connections (self); for (iter = connections; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = NM_CONNECTION (iter->data); + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (iter->data); /* Ensure eg bond/team slave and the candidate master is a * bond/team master */ - if (!is_compatible_with_slave (candidate, connection)) + if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection)) continue; - if (nm_device_check_connection_available (master_device, candidate, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { + if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { master_ac = nm_manager_activate_connection (self, candidate, NULL, @@ -2360,7 +2373,7 @@ ensure_master_active_connection (NMManager *self, continue; } - if (!nm_device_check_connection_available (candidate, master_connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) + if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) continue; found_device = TRUE; @@ -2382,7 +2395,7 @@ ensure_master_active_connection (NMManager *self, /* Device described by master_connection may be a virtual one that's * not created yet. */ - if (!found_device && nm_connection_is_virtual (master_connection)) { + if (!found_device && nm_connection_is_virtual (NM_CONNECTION (master_connection))) { master_ac = nm_manager_activate_connection (self, master_connection, NULL, @@ -2398,7 +2411,7 @@ ensure_master_active_connection (NMManager *self, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "No compatible disconnected device found for master connection %s.", - nm_connection_get_uuid (master_connection)); + nm_settings_connection_get_uuid (master_connection)); } else g_assert_not_reached (); @@ -2408,17 +2421,17 @@ ensure_master_active_connection (NMManager *self, /** * find_slaves: * @manager: #NMManager object - * @connection: the master #NMConnection to find slave connections for + * @connection: the master #NMSettingsConnection to find slave connections for * @device: the master #NMDevice for the @connection * - * Given an #NMConnection, attempts to find its slaves. If @connection is not + * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not * master, or has not any slaves, this will return %NULL. * * Returns: list of slave connections for given master @connection, or %NULL **/ static GSList * find_slaves (NMManager *manager, - NMConnection *connection, + NMSettingsConnection *connection, NMDevice *device) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); @@ -2427,7 +2440,7 @@ find_slaves (NMManager *manager, NMSettingConnection *s_con; const char *master; - s_con = nm_connection_get_setting_connection (connection); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_assert (s_con); master = nm_setting_connection_get_master (s_con); @@ -2440,7 +2453,7 @@ find_slaves (NMManager *manager, */ all_connections = nm_settings_get_connections (priv->settings); for (iter = all_connections; iter; iter = iter->next) { - NMConnection *master_connection = NULL; + NMSettingsConnection *master_connection = NULL; NMDevice *master_device = NULL; NMConnection *candidate = iter->data; @@ -2486,34 +2499,34 @@ out: static gboolean autoconnect_slaves (NMManager *manager, - NMConnection *master_connection, + NMSettingsConnection *master_connection, NMDevice *master_device, NMAuthSubject *subject) { GError *local_err = NULL; gboolean ret = FALSE; - if (should_connect_slaves (master_connection, master_device)) { + if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { GSList *slaves, *iter; iter = slaves = find_slaves (manager, master_connection, master_device); ret = slaves != NULL; while (iter) { - NMConnection *slave_connection = iter->data; + NMSettingsConnection *slave_connection = iter->data; iter = iter->next; nm_log_dbg (LOGD_CORE, "will activate slave connection '%s' (%s) as a dependency for master '%s' (%s)", - nm_connection_get_id (slave_connection), - nm_connection_get_uuid (slave_connection), - nm_connection_get_id (master_connection), - nm_connection_get_uuid (master_connection)); + nm_settings_connection_get_id (slave_connection), + nm_settings_connection_get_uuid (slave_connection), + nm_settings_connection_get_id (master_connection), + nm_settings_connection_get_uuid (master_connection)); /* Schedule slave activation */ nm_manager_activate_connection (manager, slave_connection, NULL, - nm_manager_get_best_device_for_connection (manager, slave_connection), + nm_manager_get_best_device_for_connection (manager, NM_CONNECTION (slave_connection)), subject, &local_err); if (local_err) { @@ -2547,8 +2560,9 @@ static gboolean _internal_activate_device (NMManager *self, NMActiveConnection *active, GError **error) { NMDevice *device, *existing, *master_device = NULL; - NMConnection *connection; - NMConnection *master_connection = NULL; + NMConnection *applied; + NMSettingsConnection *connection; + NMSettingsConnection *master_connection = NULL; NMActiveConnection *master_ac = NULL; GError *local_err = NULL; @@ -2558,13 +2572,15 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * g_assert (NM_IS_VPN_CONNECTION (active) == FALSE); - connection = nm_active_connection_get_connection (active); + connection = nm_active_connection_get_settings_connection (active); g_assert (connection); + applied = nm_active_connection_get_applied_connection (active); + device = nm_active_connection_get_device (active); if (!device) { - if (!nm_connection_is_virtual (connection)) { - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + if (!nm_connection_is_virtual (applied)) { + NMSettingConnection *s_con = nm_connection_get_setting_connection (applied); g_assert (s_con); g_set_error (error, @@ -2575,7 +2591,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * return FALSE; } - device = system_create_virtual_device (self, connection, &local_err); + device = system_create_virtual_device (self, applied, &local_err); if (!device) { g_set_error (error, NM_MANAGER_ERROR, @@ -2614,27 +2630,27 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * * should not be allowed to implicitly deactivate private connections * by activating a connection of their own. */ - existing_connection = nm_device_get_connection (device); + existing_connection = nm_device_get_applied_connection (device); subject = nm_active_connection_get_subject (active); if (existing_connection && !nm_auth_is_subject_in_acl (existing_connection, 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; } } /* Final connection must be available on device */ - if (!nm_device_check_connection_available (device, connection, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { + if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "Connection '%s' is not available on the device %s at this time.", - nm_connection_get_id (connection), nm_device_get_iface (device)); + nm_settings_connection_get_id (connection), nm_device_get_iface (device)); return FALSE; } @@ -2650,7 +2666,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Try to find the master connection/device if the connection has a dependency */ - if (!find_master (self, connection, device, + if (!find_master (self, applied, device, &master_connection, &master_device, &master_ac, error)) return FALSE; @@ -2661,17 +2677,17 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (master_connection || master_device) { if (master_connection) { nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master connection '%s'", - nm_connection_get_id (connection), - nm_connection_get_id (master_connection)); + nm_settings_connection_get_id (connection), + nm_settings_connection_get_id (master_connection)); } if (master_device) { nm_log_dbg (LOGD_CORE, "Activation of '%s' requires master device '%s'", - nm_connection_get_id (connection), + nm_settings_connection_get_id (connection), nm_device_get_ip_iface (master_device)); } /* Ensure eg bond slave and the candidate master is a bond master */ - if (master_connection && !is_compatible_with_slave (master_connection, connection)) { + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) { g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The master connection was not compatible"); return FALSE; @@ -2680,7 +2696,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (!master_ac) { master_ac = ensure_master_active_connection (self, nm_active_connection_get_subject (active), - connection, + applied, device, master_connection, master_device, @@ -2694,7 +2710,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_active_connection_set_master (active, master_ac); nm_log_dbg (LOGD_CORE, "Activation of '%s' depends on active connection %p", - nm_connection_get_id (connection), + nm_settings_connection_get_id (connection), master_ac); } @@ -2702,7 +2718,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active)); /* Disconnect the connection if connected or queued on another device */ - existing = nm_manager_get_connection_device (self, connection); + existing = nm_manager_get_connection_device (self, NM_CONNECTION (connection)); if (existing) nm_device_steal_connection (existing, connection); @@ -2751,8 +2767,8 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError } static NMActiveConnection * -_new_vpn_active_connection (NMManager *self, - NMConnection *connection, +_new_vpn_active_connection (NMManager *self, + NMSettingsConnection *settings_connection, const char *specific_object, NMAuthSubject *subject, GError **error) @@ -2761,6 +2777,8 @@ _new_vpn_active_connection (NMManager *self, NMActiveConnection *parent = NULL; NMDevice *device = NULL; + g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); + if (specific_object) { /* Find the specific connection the client requested we use */ parent = active_connection_get_by_path (self, specific_object); @@ -2785,7 +2803,7 @@ _new_vpn_active_connection (NMManager *self, return NULL; } - return (NMActiveConnection *) nm_vpn_connection_new (connection, + return (NMActiveConnection *) nm_vpn_connection_new (settings_connection, device, nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)), subject); @@ -2799,7 +2817,9 @@ _new_active_connection (NMManager *self, NMAuthSubject *subject, GError **error) { + NMSettingsConnection *settings_connection = NULL; NMActiveConnection *existing_ac; + gboolean is_vpn; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); @@ -2817,15 +2837,20 @@ _new_active_connection (NMManager *self, if (specific_object && g_strcmp0 (specific_object, "/") == 0) specific_object = NULL; - if (nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) { + is_vpn = nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_VPN_SETTING_NAME); + + if (NM_IS_SETTINGS_CONNECTION (connection)) + settings_connection = (NMSettingsConnection *) connection; + + if (is_vpn) { return _new_vpn_active_connection (self, - connection, + settings_connection, specific_object, subject, error); } - return (NMActiveConnection *) nm_act_request_new (connection, + return (NMActiveConnection *) nm_act_request_new (settings_connection, specific_object, subject, device); @@ -2837,7 +2862,7 @@ _internal_activation_failed (NMManager *self, const char *error_desc) { nm_log_dbg (LOGD_CORE, "Failed to activate '%s': %s", - nm_connection_get_id (nm_active_connection_get_connection (active)), + nm_active_connection_get_settings_connection_id (active), error_desc); if (nm_active_connection_get_state (active) <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { @@ -2875,7 +2900,7 @@ _internal_activation_auth_done (NMActiveConnection *active, /** * nm_manager_activate_connection(): * @self: the #NMManager - * @connection: the #NMConnection to activate on @device + * @connection: the #NMSettingsConnection to activate on @device * @specific_object: the specific object path, if any, for the activation * @device: the #NMDevice to activate @connection on * @subject: the subject which requested activation @@ -2892,7 +2917,7 @@ _internal_activation_auth_done (NMActiveConnection *active, */ NMActiveConnection * nm_manager_activate_connection (NMManager *self, - NMConnection *connection, + NMSettingsConnection *connection, const char *specific_object, NMDevice *device, NMAuthSubject *subject, @@ -2909,7 +2934,7 @@ nm_manager_activate_connection (NMManager *self, g_return_val_if_fail (*error == NULL, NULL); /* Ensure the subject has permissions for this connection */ - if (!nm_auth_is_subject_in_acl (connection, + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), subject, &error_desc)) { g_set_error_literal (error, @@ -2928,7 +2953,7 @@ nm_manager_activate_connection (NMManager *self, for (iter = priv->authorizing_connections; iter; iter = g_slist_next (iter)) { active = iter->data; - if ( connection == nm_active_connection_get_connection (active) + if ( connection == nm_active_connection_get_settings_connection (active) && g_strcmp0 (nm_active_connection_get_specific_object (active), specific_object) == 0 && nm_active_connection_get_device (active) == device && nm_auth_subject_is_internal (nm_active_connection_get_subject (active)) @@ -2937,14 +2962,14 @@ nm_manager_activate_connection (NMManager *self, } active = _new_active_connection (self, - connection, + NM_CONNECTION (connection), specific_object, device, subject, error); if (active) { priv->authorizing_connections = g_slist_prepend (priv->authorizing_connections, active); - nm_active_connection_authorize (active, _internal_activation_auth_done, self, NULL); + nm_active_connection_authorize (active, NULL, _internal_activation_auth_done, self, NULL); } return active; } @@ -3070,10 +3095,10 @@ _activation_auth_done (NMActiveConnection *active, GDBusMethodInvocation *context = user_data2; GError *error = NULL; NMAuthSubject *subject; - NMConnection *connection; + NMSettingsConnection *connection; subject = nm_active_connection_get_subject (active); - connection = nm_active_connection_get_connection (active); + connection = nm_active_connection_get_settings_connection (active); if (success) { if (_internal_activate_generic (self, active, &error)) { @@ -3110,7 +3135,7 @@ impl_manager_activate_connection (NMManager *self, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *active = NULL; NMAuthSubject *subject = NULL; - NMConnection *connection = NULL; + NMSettingsConnection *connection = NULL; NMDevice *device = NULL; gboolean is_vpn = FALSE; GError *error = NULL; @@ -3170,7 +3195,7 @@ impl_manager_activate_connection (NMManager *self, } g_assert (connection_path); - connection = (NMConnection *) nm_settings_get_connection_by_path (priv->settings, connection_path); + connection = nm_settings_get_connection_by_path (priv->settings, connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -3180,7 +3205,7 @@ impl_manager_activate_connection (NMManager *self, subject = validate_activation_request (self, context, - connection, + NM_CONNECTION (connection), device_path, &device, &is_vpn, @@ -3189,7 +3214,7 @@ impl_manager_activate_connection (NMManager *self, goto error; active = _new_active_connection (self, - connection, + NM_CONNECTION (connection), specific_object_path, device, subject, @@ -3197,7 +3222,7 @@ impl_manager_activate_connection (NMManager *self, if (!active) goto error; - nm_active_connection_authorize (active, _activation_auth_done, self, context); + nm_active_connection_authorize (active, NULL, _activation_auth_done, self, context); g_clear_object (&subject); return; @@ -3221,7 +3246,7 @@ typedef struct { } AddAndActivateInfo; static void -activation_add_done (NMSettings *self, +activation_add_done (NMSettings *settings, NMSettingsConnection *new_connection, GError *error, GDBusMethodInvocation *context, @@ -3229,44 +3254,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, NM_CONNECTION (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_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 @@ -3283,17 +3310,23 @@ _add_and_activate_auth_done (NMActiveConnection *active, GError *error = NULL; if (success) { - info = g_malloc0 (sizeof (*info)); + NMConnection *connection; + + connection = g_object_steal_data (G_OBJECT (active), + TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE); + + 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_active_connection_get_connection (active), + connection, FALSE, context, activation_add_done, info); + g_object_unref (connection); } else { g_assert (error_desc); error = g_error_new_literal (NM_MANAGER_ERROR, @@ -3400,8 +3433,12 @@ impl_manager_add_and_activate_connection (NMManager *self, if (!active) goto error; - nm_active_connection_authorize (active, _add_and_activate_auth_done, self, context); - g_object_unref (connection); + g_object_set_data_full (G_OBJECT (active), + TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE, + connection, + g_object_unref); + + nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context); g_object_unref (subject); return; @@ -3501,7 +3538,7 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, if (active) { nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, - nm_active_connection_get_connection (active), + nm_active_connection_get_settings_connection (active), !error, nm_auth_chain_get_subject (chain), error ? error->message : NULL); @@ -3522,7 +3559,7 @@ impl_manager_deactivate_connection (NMManager *self, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; - NMConnection *connection = NULL; + NMSettingsConnection *connection = NULL; GError *error = NULL; NMAuthSubject *subject = NULL; NMAuthChain *chain; @@ -3531,7 +3568,7 @@ impl_manager_deactivate_connection (NMManager *self, /* Find the connection by its object path */ ac = active_connection_get_by_path (self, active_path); if (ac) - connection = nm_active_connection_get_connection (ac); + connection = nm_active_connection_get_settings_connection (ac); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -3550,7 +3587,7 @@ impl_manager_deactivate_connection (NMManager *self, } /* Ensure the subject has permissions for this connection */ - if (!nm_auth_is_subject_in_acl (connection, + if (!nm_auth_is_subject_in_acl (NM_CONNECTION (connection), subject, &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -4341,7 +4378,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); @@ -4376,7 +4413,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); } } @@ -4788,7 +4825,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); } } @@ -5035,7 +5072,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-manager.h b/src/nm-manager.h index 632cd0d0b4..39123f8b41 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -23,7 +23,7 @@ #define __NETWORKMANAGER_MANAGER_H__ #include "nm-exported-object.h" -#include "nm-connection.h" +#include "nm-settings-connection.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -98,7 +98,7 @@ NMDevice * nm_manager_get_device_by_ifindex (NMManager *manager, int ifindex); NMActiveConnection *nm_manager_activate_connection (NMManager *manager, - NMConnection *connection, + NMSettingsConnection *connection, const char *specific_object, NMDevice *device, NMAuthSubject *subject, diff --git a/src/nm-policy.c b/src/nm-policy.c index a35361f17e..e186320d2e 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -195,7 +195,7 @@ _set_hostname (NMPolicy *policy, nm_dns_manager_set_hostname (priv->dns_manager, priv->cur_hostname); if (set_system_hostname (priv->cur_hostname, msg)) - nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL); } static void @@ -466,7 +466,7 @@ update_ip4_routing (NMPolicy *policy, gboolean force_update) return; priv->default_device4 = default_device; - connection = nm_active_connection_get_connection (best_ac); + connection = nm_active_connection_get_applied_connection (best_ac); nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv4 routing and DNS.", nm_connection_get_id (connection), ip_iface); g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP4_DEVICE); @@ -561,7 +561,7 @@ update_ip6_routing (NMPolicy *policy, gboolean force_update) return; priv->default_device6 = default_device6; - connection = nm_active_connection_get_connection (best_ac); + connection = nm_active_connection_get_applied_connection (best_ac); nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv6 routing and DNS.", nm_connection_get_id (connection), ip_iface); g_object_notify (G_OBJECT (policy), NM_POLICY_DEFAULT_IP6_DEVICE); @@ -636,7 +636,7 @@ auto_activate_device (gpointer user_data) ActivateData *data = (ActivateData *) user_data; NMPolicy *policy; NMPolicyPrivate *priv; - NMConnection *best_connection; + NMSettingsConnection *best_connection; char *specific_object = NULL; GPtrArray *connections; GSList *connection_list; @@ -674,7 +674,7 @@ auto_activate_device (gpointer user_data) if (!nm_settings_connection_can_autoconnect (candidate)) continue; if (nm_device_can_auto_connect (data->device, (NMConnection *) candidate, &specific_object)) { - best_connection = (NMConnection *) candidate; + best_connection = candidate; break; } } @@ -685,7 +685,7 @@ auto_activate_device (gpointer user_data) NMAuthSubject *subject; nm_log_info (LOGD_DEVICE, "Auto-activating connection '%s'.", - nm_connection_get_id (best_connection)); + nm_settings_connection_get_id (best_connection)); subject = nm_auth_subject_new_internal (); if (!nm_manager_activate_connection (priv->manager, best_connection, @@ -694,7 +694,7 @@ auto_activate_device (gpointer user_data) subject, &error)) { nm_log_info (LOGD_DEVICE, "Connection '%s' auto-activation failed: (%d) %s", - nm_connection_get_id (best_connection), + nm_settings_connection_get_id (best_connection), error ? error->code : -1, error ? error->message : "(none)"); g_error_free (error); @@ -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)); } @@ -1049,7 +1062,7 @@ activate_secondary_connections (NMPolicy *policy, } if (!nm_connection_is_type (NM_CONNECTION (settings_con), NM_SETTING_VPN_SETTING_NAME)) { nm_log_warn (LOGD_DEVICE, "Secondary connection '%s (%s)' auto-activation failed: The connection is not a VPN.", - nm_connection_get_id (NM_CONNECTION (settings_con)), sec_uuid); + nm_settings_connection_get_id (settings_con), sec_uuid); success = FALSE; break; } @@ -1058,10 +1071,10 @@ activate_secondary_connections (NMPolicy *policy, g_assert (req); nm_log_dbg (LOGD_DEVICE, "Activating secondary connection '%s (%s)' for base connection '%s (%s)'", - nm_connection_get_id (NM_CONNECTION (settings_con)), sec_uuid, + nm_settings_connection_get_id (settings_con), sec_uuid, nm_connection_get_id (connection), nm_connection_get_uuid (connection)); ac = nm_manager_activate_connection (priv->manager, - NM_CONNECTION (settings_con), + settings_con, nm_exported_object_get_path (NM_EXPORTED_OBJECT (req)), device, nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)), @@ -1070,7 +1083,7 @@ activate_secondary_connections (NMPolicy *policy, secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac)); else { nm_log_warn (LOGD_DEVICE, "Secondary connection '%s (%s)' auto-activation failed: (%d) %s", - nm_connection_get_id (NM_CONNECTION (settings_con)), sec_uuid, + nm_settings_connection_get_id (settings_con), sec_uuid, error ? error->code : 0, (error && error->message) ? error->message : "unknown"); g_clear_error (&error); @@ -1097,7 +1110,9 @@ device_state_changed (NMDevice *device, { NMPolicy *policy = (NMPolicy *) user_data; NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - NMSettingsConnection *connection = NM_SETTINGS_CONNECTION (nm_device_get_connection (device)); + + NMSettingsConnection *connection = nm_device_get_settings_connection (device); + const char *ip_iface = nm_device_get_ip_iface (device); NMIP4Config *ip4_config; NMIP6Config *ip6_config; @@ -1115,18 +1130,18 @@ device_state_changed (NMDevice *device, if (reason == NM_DEVICE_STATE_REASON_NO_SECRETS) { nm_log_dbg (LOGD_DEVICE, "Connection '%s' now blocked from autoconnect due to no secrets", - nm_connection_get_id (NM_CONNECTION (connection))); + nm_settings_connection_get_id (connection)); nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_NO_SECRETS); } else if (tries > 0) { nm_log_dbg (LOGD_DEVICE, "Connection '%s' failed to autoconnect; %d tries left", - nm_connection_get_id (NM_CONNECTION (connection)), tries); + nm_settings_connection_get_id (connection), tries); nm_settings_connection_set_autoconnect_retries (connection, tries - 1); } if (nm_settings_connection_get_autoconnect_retries (connection) == 0) { nm_log_info (LOGD_DEVICE, "Disabling autoconnect for connection '%s'.", - nm_connection_get_id (NM_CONNECTION (connection))); + nm_settings_connection_get_id (connection)); /* Schedule a handler to reset retries count */ if (!priv->reset_retries_id) { gint32 retry_time = nm_settings_connection_get_autoconnect_retry_time (connection); @@ -1146,6 +1161,7 @@ device_state_changed (NMDevice *device, /* And clear secrets so they will always be requested from the * settings service when the next connection is made. */ + nm_connection_clear_secrets (NM_CONNECTION (connection)); } @@ -1178,7 +1194,7 @@ device_state_changed (NMDevice *device, if (connection) { /* The connection was deactivated, so block just this connection */ nm_log_dbg (LOGD_DEVICE, "Blocking autoconnect of connection '%s' by user request", - nm_connection_get_id (NM_CONNECTION (connection))); + nm_settings_connection_get_id (connection)); nm_settings_connection_set_autoconnect_blocked_reason (connection, NM_DEVICE_STATE_REASON_USER_REQUESTED); } @@ -1459,7 +1475,7 @@ vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *policy) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); NMActiveConnection *ac = NM_ACTIVE_CONNECTION (vpn); - NMConnection *connection = nm_active_connection_get_connection (ac); + NMSettingsConnection *connection = nm_active_connection_get_settings_connection (ac); GError *error = NULL; /* Attempt to reconnect VPN connections that failed after being connected */ @@ -1470,7 +1486,7 @@ vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *policy) nm_active_connection_get_subject (ac), &error)) { nm_log_warn (LOGD_DEVICE, "VPN '%s' reconnect failed: %s", - nm_connection_get_id (connection), + nm_settings_connection_get_id (connection), error->message ? error->message : "unknown"); g_clear_error (&error); } @@ -1551,63 +1567,16 @@ connection_added (NMSettings *settings, } static void -add_or_change_zone_cb (GError *error, gpointer user_data) -{ - NMDevice *device = NM_DEVICE (user_data); - - if (error) { - /* FIXME: what do we do here? */ - } - - g_object_unref (device); -} - -static void -firewall_update_zone (NMPolicy *policy, NMConnection *connection, NMDevice *device) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); - - if ( nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED - && !nm_device_uses_assumed_connection (device)) { - nm_firewall_manager_add_or_change_zone (priv->firewall_manager, - nm_device_get_ip_iface (device), - nm_setting_connection_get_zone (s_con), - FALSE, /* change zone */ - add_or_change_zone_cb, - g_object_ref (device)); - } -} - -static void firewall_started (NMFirewallManager *manager, gpointer user_data) { NMPolicy *policy = (NMPolicy *) user_data; NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (policy); - NMConnection *connection; - NMSettingConnection *s_con; const GSList *iter; /* add interface of each device to correct zone */ - for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) { - NMDevice *dev = NM_DEVICE (iter->data); - - connection = nm_device_get_connection (dev); - if (!connection) - continue; - - s_con = nm_connection_get_setting_connection (connection); - if ( nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED - && !nm_device_uses_assumed_connection (dev)) { - nm_firewall_manager_add_or_change_zone (priv->firewall_manager, - nm_device_get_ip_iface (dev), - nm_setting_connection_get_zone (s_con), - FALSE, /* still change zone */ - add_or_change_zone_cb, - g_object_ref (dev)); - } - } + for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) + nm_device_update_firewall_zone (iter->data); } static void @@ -1665,22 +1634,21 @@ connection_updated_by_user (NMSettings *settings, for (iter = nm_manager_get_devices (priv->manager); iter; iter = g_slist_next (iter)) { NMDevice *dev = NM_DEVICE (iter->data); - if (nm_device_get_connection (dev) == NM_CONNECTION (connection)) { + if (nm_device_get_settings_connection (dev) == connection) { device = dev; break; } } - if (device) { - firewall_update_zone (policy, NM_CONNECTION (connection), device); - nm_device_update_metered (device); - } + if (device) + nm_device_reapply_settings_immediately (device); + /* Reset auto retries back to default since connection was updated */ nm_settings_connection_reset_autoconnect_retries (connection); } static void -_deactivate_if_active (NMManager *manager, NMConnection *connection) +_deactivate_if_active (NMManager *manager, NMSettingsConnection *connection) { const GSList *active, *iter; @@ -1690,14 +1658,14 @@ _deactivate_if_active (NMManager *manager, NMConnection *connection) NMActiveConnectionState state = nm_active_connection_get_state (ac); GError *error = NULL; - if (nm_active_connection_get_connection (ac) == connection && + if (nm_active_connection_get_settings_connection (ac) == connection && (state <= NM_ACTIVE_CONNECTION_STATE_ACTIVATED)) { if (!nm_manager_deactivate_connection (manager, nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac)), NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, &error)) { nm_log_warn (LOGD_DEVICE, "Connection '%s' disappeared, but error deactivating it: (%d) %s", - nm_connection_get_id (connection), + nm_settings_connection_get_id (connection), error ? error->code : -1, error ? error->message : "(unknown)"); g_clear_error (&error); @@ -1708,7 +1676,7 @@ _deactivate_if_active (NMManager *manager, NMConnection *connection) static void connection_removed (NMSettings *settings, - NMConnection *connection, + NMSettingsConnection *connection, gpointer user_data) { NMPolicy *policy = user_data; @@ -1728,7 +1696,7 @@ connection_visibility_changed (NMSettings *settings, if (nm_settings_connection_is_visible (connection)) schedule_activate_all (policy); else - _deactivate_if_active (priv->manager, NM_CONNECTION (connection)); + _deactivate_if_active (priv->manager, connection); } static void diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index b5bb22c11d..802a7264a3 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -309,7 +309,7 @@ extract_details_from_connection (NMConnection *connection, static void ppp_secrets_cb (NMActRequest *req, NMActRequestGetSecretsCallId call_id, - NMConnection *connection, + NMSettingsConnection *settings_connection, /* unused (we pass NULL here) */ GError *error, gpointer user_data) { @@ -318,6 +318,7 @@ ppp_secrets_cb (NMActRequest *req, const char *username = NULL; const char *password = NULL; GError *local = NULL; + NMConnection *applied_connection; g_return_if_fail (priv->pending_secrets_context != NULL); g_return_if_fail (req == priv->act_req); @@ -332,7 +333,9 @@ ppp_secrets_cb (NMActRequest *req, goto out; } - if (!extract_details_from_connection (connection, priv->secrets_setting_name, &username, &password, &local)) { + applied_connection = nm_act_request_get_applied_connection (req); + + if (!extract_details_from_connection (applied_connection, priv->secrets_setting_name, &username, &password, &local)) { nm_log_warn (LOGD_PPP, "%s", local->message); g_dbus_method_invocation_take_error (priv->pending_secrets_context, local); goto out; @@ -359,7 +362,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, GDBusMethodInvocation *context) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); - NMConnection *connection; + NMConnection *applied_connection; const char *username = NULL; const char *password = NULL; guint32 tries; @@ -367,16 +370,17 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, GError *error = NULL; NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; - connection = nm_act_request_get_connection (priv->act_req); + nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (priv->act_req)); + + applied_connection = nm_act_request_get_applied_connection (priv->act_req); - nm_connection_clear_secrets (connection); - priv->secrets_setting_name = nm_connection_need_secrets (connection, &hints); + priv->secrets_setting_name = nm_connection_need_secrets (applied_connection, &hints); if (!priv->secrets_setting_name) { /* Use existing secrets from the connection */ - if (extract_details_from_connection (connection, NULL, &username, &password, &error)) { + if (extract_details_from_connection (applied_connection, NULL, &username, &password, &error)) { /* Send existing secrets to the PPP plugin */ priv->pending_secrets_context = context; - ppp_secrets_cb (priv->act_req, priv->secrets_id, connection, NULL, manager); + ppp_secrets_cb (priv->act_req, priv->secrets_id, NULL, NULL, manager); } else { nm_log_warn (LOGD_PPP, "%s", error->message); g_dbus_method_invocation_take_error (priv->pending_secrets_context, error); @@ -388,7 +392,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, * appear to ask a few times when they actually don't even care what you * pass back. */ - tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); + tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (applied_connection), PPP_MANAGER_SECRET_TRIES)); if (tries > 1) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; @@ -398,7 +402,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, hints ? g_ptr_array_index (hints, 0) : NULL, ppp_secrets_cb, manager); - g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); + g_object_set_data (G_OBJECT (applied_connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); priv->pending_secrets_context = context; if (hints) @@ -422,7 +426,7 @@ set_ip_config_common (NMPPPManager *self, guint32 *out_mtu) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - NMConnection *connection; + NMConnection *applied_connection; NMSettingPpp *s_ppp; const char *iface; @@ -434,12 +438,11 @@ set_ip_config_common (NMPPPManager *self, priv->ip_iface = g_strdup (iface); /* Got successful IP config; obviously the secrets worked */ - connection = nm_act_request_get_connection (priv->act_req); - g_assert (connection); - g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); + applied_connection = nm_act_request_get_applied_connection (priv->act_req); + g_object_set_data (G_OBJECT (applied_connection), PPP_MANAGER_SECRET_TRIES, NULL); /* Get any custom MTU */ - s_ppp = nm_connection_get_setting_ppp (connection); + s_ppp = nm_connection_get_setting_ppp (applied_connection); if (s_ppp && out_mtu) *out_mtu = nm_setting_ppp_get_mtu (s_ppp); @@ -1047,7 +1050,7 @@ nm_ppp_manager_start (NMPPPManager *manager, if (stat ("/dev/ppp", &st) || !S_ISCHR (st.st_mode)) nm_utils_modprobe (NULL, FALSE, "ppp_generic", NULL); - connection = nm_act_request_get_connection (req); + connection = nm_act_request_get_applied_connection (req); g_assert (connection); s_ppp = nm_connection_get_setting_ppp (connection); diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 2bdb41baee..c3abaac25c 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -474,8 +474,6 @@ struct _NMAgentManagerCallId { NMAgentSecretsResultFunc callback; gpointer callback_data; - gpointer other_data2; - gpointer other_data3; } get; }; } con; @@ -564,9 +562,7 @@ req_complete_release (Request *req, req->con.get.flags, error ? NULL : secrets, error, - req->con.get.callback_data, - req->con.get.other_data2, - req->con.get.other_data3); + req->con.get.callback_data); break; case REQUEST_TYPE_CON_SAVE: @@ -1167,8 +1163,6 @@ _con_get_try_complete_early (Request *req) * @hints: * @callback: * @callback_data: - * @other_data2: - * @other_data3: * * Requests secrets for a connection. * @@ -1190,17 +1184,15 @@ nm_agent_manager_get_secrets (NMAgentManager *self, NMSecretAgentGetSecretsFlags flags, const char **hints, NMAgentSecretsResultFunc callback, - gpointer callback_data, - gpointer other_data2, - gpointer other_data3) + gpointer callback_data) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); Request *req; - g_return_val_if_fail (self != NULL, 0); - g_return_val_if_fail (path && *path, 0); - g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); - g_return_val_if_fail (callback != NULL, 0); + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (path && *path, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (callback != NULL, NULL); nm_log_dbg (LOGD_SETTINGS, "Secrets requested for connection %s (%s/%s)", @@ -1227,8 +1219,6 @@ nm_agent_manager_get_secrets (NMAgentManager *self, req->con.get.flags = flags; req->con.get.callback = callback; req->con.get.callback_data = callback_data; - req->con.get.other_data2 = other_data2; - req->con.get.other_data3 = other_data3; if (!g_hash_table_add (priv->requests, req)) g_assert_not_reached (); diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index bfccabd081..2f50553724 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -61,9 +61,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, NMSecretAgentGetSecretsFlags flags, GVariant *secrets, GError *error, - gpointer user_data, - gpointer other_data2, - gpointer other_data3); + gpointer user_data); NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager, const char *path, @@ -74,9 +72,7 @@ NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager, NMSecretAgentGetSecretsFlags flags, const char **hints, NMAgentSecretsResultFunc callback, - gpointer callback_data, - gpointer other_data2, - gpointer other_data3); + gpointer callback_data); void nm_agent_manager_cancel_secrets (NMAgentManager *manager, NMAgentManagerCallId request_id); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index e0e9a25655..9ab0bc6b30 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -71,18 +71,6 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_E NM_TYPE_SETTINGS_CONNECTION, \ NMSettingsConnectionPrivate)) -static inline NMAgentManagerCallId -NM_AGENT_MANAGER_CALL_ID (NMSettingsConnectionCallId call_id) -{ - return (NMAgentManagerCallId) call_id; -} - -static inline NMSettingsConnectionCallId -NM_SETTINGS_CONNECTION_CALL_ID (NMAgentManagerCallId call_id_a) -{ - return (NMSettingsConnectionCallId) call_id_a; -} - enum { PROP_0 = 0, PROP_VISIBLE, @@ -115,13 +103,7 @@ typedef struct { GSList *pending_auths; /* List of pending authentication requests */ gboolean visible; /* Is this connection is visible by some session? */ - GSList *reqs_int; /* in-progress internal secrets requests */ - - GSList *reqs_ext; /* in-progress external secrets requests (D-Bus). Note that - this list contains NMSettingsConnectionCallId, vs. NMAgentManagerCallId. - So, we should for example cancel the reqs_ext with nm_settings_connection_cancel_secrets() - instead of nm_agent_manager_cancel_secrets(). - Actually, the difference doesn't matter, because both are indeed equivalent. */ + GSList *get_secret_requests; /* in-progress secrets requests */ /* Caches secrets from on-disk connections; were they not cached any * call to nm_connection_clear_secrets() wipes them out and we'd have @@ -150,6 +132,22 @@ typedef struct { } NMSettingsConnectionPrivate; +/*******************************************************************/ + +gboolean +nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, + NMConnection *applied_connection, + NMSettingCompareFlags compare_flags) +{ + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (applied_connection), FALSE); + + /* for convenience, we *always* ignore certain settings. */ + compare_flags |= NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP; + + return nm_connection_compare (NM_CONNECTION (self), applied_connection, compare_flags); +} + /**************************************************************/ /* Return TRUE to keep, FALSE to drop */ @@ -769,6 +767,86 @@ do_delete (NMSettingsConnection *self, /**************************************************************/ + +typedef enum { + GET_SECRETS_INFO_TYPE_REQ, + GET_SECRETS_INFO_TYPE_IDLE, +} GetSecretsInfoType; + +struct _NMSettingsConnectionCallId { + NMSettingsConnection *self; + gboolean had_applied_connection; + NMConnection *applied_connection; + NMSettingsConnectionSecretsFunc callback; + gpointer callback_data; + + GetSecretsInfoType type; + union { + struct { + NMAgentManagerCallId id; + } req; + struct { + guint32 id; + GError *error; + } idle; + } t; +}; + +typedef struct _NMSettingsConnectionCallId GetSecretsInfo; + +static GetSecretsInfo * +_get_secrets_info_new (NMSettingsConnection *self, + NMConnection *applied_connection, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data) +{ + GetSecretsInfo *info; + + info = g_slice_new0 (GetSecretsInfo); + + info->self = self; + if (applied_connection) { + info->had_applied_connection = TRUE; + info->applied_connection = applied_connection; + g_object_add_weak_pointer (G_OBJECT (applied_connection), (gpointer *) &info->applied_connection); + } + info->callback = callback; + info->callback_data = callback_data; + + return info; +} + +static void +_get_secrets_info_callback (GetSecretsInfo *info, + const char *agent_username, + const char *setting_name, + GError *error) +{ + if (info->callback) { + info->callback (info->self, + info, + agent_username, + setting_name, + error, + info->callback_data); + } +} + +static void +_get_secrets_info_free (GetSecretsInfo *info) +{ + g_return_if_fail (info && info->self); + + if (info->applied_connection) + g_object_remove_weak_pointer (G_OBJECT (info->applied_connection), (gpointer *) &info->applied_connection); + + if (info->type == GET_SECRETS_INFO_TYPE_IDLE) + g_clear_error (&info->t.idle.error); + + memset (info, 0, sizeof (*info)); + g_slice_free (GetSecretsInfo, info); +} + static gboolean supports_secrets (NMSettingsConnection *self, const char *setting_name) { @@ -813,69 +891,33 @@ new_secrets_commit_cb (NMSettingsConnection *self, } static void -_callback_nop (NMSettingsConnection *self, - NMSettingsConnectionCallId call_id, - const char *agent_username, - const char *setting_name, - GError *error, - gpointer user_data) +get_cmp_flags (NMSettingsConnection *self, /* only needed for logging */ + GetSecretsInfo *info, /* only needed for logging */ + NMConnection *connection, + const char *agent_dbus_owner, + gboolean agent_has_modify, + const char *setting_name, /* only needed for logging */ + NMSecretAgentGetSecretsFlags flags, + GVariant *secrets, + gboolean *agent_had_system, + ForEachSecretFlags *cmp_flags) { -} + gboolean is_self = (((NMConnection *) self) == connection); -static void -agent_secrets_done_cb (NMAgentManager *manager, - NMAgentManagerCallId call_id_a, - const char *agent_dbus_owner, - const char *agent_username, - gboolean agent_has_modify, - const char *setting_name, - NMSecretAgentGetSecretsFlags flags, - GVariant *secrets, - GError *error, - gpointer user_data, - gpointer other_data2, - gpointer other_data3) -{ - NMSettingsConnectionCallId call_id = NM_SETTINGS_CONNECTION_CALL_ID (call_id_a); - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMSettingsConnectionSecretsFunc callback = other_data2; - gpointer callback_data = other_data3; - GError *local = NULL; - GVariant *dict; - gboolean agent_had_system = FALSE; - ForEachSecretFlags cmp_flags = { NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE }; - - if (!callback) - callback = _callback_nop; - - g_return_if_fail (g_slist_find (priv->reqs_int, call_id)); + g_return_if_fail (secrets); - priv->reqs_int = g_slist_remove (priv->reqs_int, call_id); + cmp_flags->required = NM_SETTING_SECRET_FLAG_NONE; + cmp_flags->forbidden = NM_SETTING_SECRET_FLAG_NONE; - if (error) { - _LOGD ("(%s:%p) secrets request error: %s", - setting_name, call_id, error->message); - - callback (self, call_id, NULL, setting_name, error, callback_data); - return; - } + *agent_had_system = FALSE; - if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { - local = g_error_new (NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - "%s.%d - Connection didn't have requested setting '%s'.", - __FILE__, __LINE__, setting_name); - callback (self, call_id, NULL, setting_name, local, callback_data); - g_clear_error (&local); - return; - } - - g_assert (secrets); if (agent_dbus_owner) { - _LOGD ("(%s:%p) secrets returned from agent %s", - setting_name, - call_id, - agent_dbus_owner); + if (is_self) { + _LOGD ("(%s:%p) secrets returned from agent %s", + setting_name, + info, + agent_dbus_owner); + } /* If the agent returned any system-owned secrets (initial connect and no * secrets given when the connection was created, or something like that) @@ -883,50 +925,134 @@ agent_secrets_done_cb (NMAgentManager *manager, * save those system-owned secrets. If not, discard them and use the * existing secrets, or fail the connection. */ - agent_had_system = find_secret (NM_CONNECTION (self), secrets, secret_is_system_owned, NULL); - if (agent_had_system) { + *agent_had_system = find_secret (connection, secrets, secret_is_system_owned, NULL); + if (*agent_had_system) { if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { /* No user interaction was allowed when requesting secrets; the * agent is being bad. Remove system-owned secrets. */ - _LOGD ("(%s:%p) interaction forbidden but agent %s returned system secrets", - setting_name, - call_id, - agent_dbus_owner); + if (is_self) { + _LOGD ("(%s:%p) interaction forbidden but agent %s returned system secrets", + setting_name, + info, + agent_dbus_owner); + } - cmp_flags.required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; } else if (agent_has_modify == FALSE) { /* Agent didn't successfully authenticate; clear system-owned secrets * from the secrets the agent returned. */ - _LOGD ("(%s:%p) agent failed to authenticate but provided system secrets", - setting_name, - call_id); + if (is_self) { + _LOGD ("(%s:%p) agent failed to authenticate but provided system secrets", + setting_name, + info); + } - cmp_flags.required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + cmp_flags->required |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; } } } else { - _LOGD ("(%s:%p) existing secrets returned", - setting_name, - call_id); + if (is_self) { + _LOGD ("(%s:%p) existing secrets returned", + setting_name, + info); + } } - _LOGD ("(%s:%p) secrets request completed", - setting_name, - call_id); - /* If no user interaction was allowed, make sure that no "unsaved" secrets * came back. Unsaved secrets by definition require user interaction. */ if (flags == NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE) { - cmp_flags.forbidden |= ( NM_SETTING_SECRET_FLAG_NOT_SAVED - | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); + cmp_flags->forbidden |= ( NM_SETTING_SECRET_FLAG_NOT_SAVED + | NM_SETTING_SECRET_FLAG_NOT_REQUIRED); + } +} + +static void +get_secrets_done_cb (NMAgentManager *manager, + NMAgentManagerCallId call_id_a, + const char *agent_dbus_owner, + const char *agent_username, + gboolean agent_has_modify, + const char *setting_name, + NMSecretAgentGetSecretsFlags flags, + GVariant *secrets, + GError *error, + gpointer user_data) +{ + GetSecretsInfo *info = user_data; + NMSettingsConnection *self; + NMSettingsConnectionPrivate *priv; + NMConnection *applied_connection; + gs_free_error GError *local = NULL; + GVariant *dict; + gboolean agent_had_system = FALSE; + ForEachSecretFlags cmp_flags = { NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE }; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = info->self; + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (g_slist_find (priv->get_secret_requests, info)); + + priv->get_secret_requests = g_slist_remove (priv->get_secret_requests, info); + + if (error) { + _LOGD ("(%s:%p) secrets request error: %s", + setting_name, info, error->message); + + _get_secrets_info_callback (info, NULL, setting_name, error); + goto out; } + if ( info->had_applied_connection + && !info->applied_connection) { + g_set_error_literal (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Applied connection deleted since requesting secrets"); + _get_secrets_info_callback (info, NULL, setting_name, local); + goto out; + } + + if ( info->had_applied_connection + && !nm_settings_connection_has_unmodified_applied_connection (self, info->applied_connection, NM_SETTING_COMPARE_FLAG_NONE)) { + g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); + _get_secrets_info_callback (info, NULL, setting_name, local); + goto out; + } + + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { + g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Connection didn't have requested setting '%s'.", + setting_name); + _get_secrets_info_callback (info, NULL, setting_name, local); + goto out; + } + + get_cmp_flags (self, + info, + NM_CONNECTION (self), + agent_dbus_owner, + agent_has_modify, + setting_name, + flags, + secrets, + &agent_had_system, + &cmp_flags); + + _LOGD ("(%s:%p) secrets request completed", + setting_name, + info); + + dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); - dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) { GVariant *filtered_secrets; @@ -937,7 +1063,7 @@ agent_secrets_done_cb (NMAgentManager *manager, */ filtered_secrets = for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags); if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, filtered_secrets, &local)) { - /* Now that all secrets are updated, copy and cache new secrets, + /* Now that all secrets are updated, copy and cache new secrets, * then save them to backing storage. */ update_system_secrets_cache (self); @@ -951,19 +1077,19 @@ agent_secrets_done_cb (NMAgentManager *manager, if (agent_had_system) { _LOGD ("(%s:%p) saving new secrets to backing storage", setting_name, - call_id); + info); nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, new_secrets_commit_cb, NULL); } else { _LOGD ("(%s:%p) new agent secrets processed", setting_name, - call_id); + info); } } else { _LOGD ("(%s:%p) failed to update with agent secrets: (%d) %s", setting_name, - call_id, + info, local ? local->code : -1, (local && local->message) ? local->message : "(unknown)"); } @@ -971,20 +1097,69 @@ agent_secrets_done_cb (NMAgentManager *manager, } else { _LOGD ("(%s:%p) failed to update with existing secrets: (%d) %s", setting_name, - call_id, + info, local ? local->code : -1, (local && local->message) ? local->message : "(unknown)"); } - callback (self, call_id, agent_username, setting_name, local, callback_data); + applied_connection = info->applied_connection; + if (applied_connection) { + get_cmp_flags (self, + info, + applied_connection, + agent_dbus_owner, + agent_has_modify, + setting_name, + flags, + secrets, + &agent_had_system, + &cmp_flags); + + nm_connection_clear_secrets (applied_connection); + + if (!dict || nm_connection_update_secrets (applied_connection, setting_name, dict, NULL)) { + GVariant *filtered_secrets; + + filtered_secrets = for_each_secret (applied_connection, secrets, TRUE, validate_secret_flags, &cmp_flags); + nm_connection_update_secrets (applied_connection, setting_name, filtered_secrets, NULL); + g_variant_unref (filtered_secrets); + } + } + + _get_secrets_info_callback (info, agent_username, setting_name, local); g_clear_error (&local); if (dict) g_variant_unref (dict); + +out: + _get_secrets_info_free (info); +} + +static gboolean +get_secrets_idle_cb (GetSecretsInfo *info) +{ + NMSettingsConnectionPrivate *priv; + + g_return_val_if_fail (info && NM_IS_SETTINGS_CONNECTION (info->self), G_SOURCE_REMOVE); + + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (info->self); + + g_return_val_if_fail (g_slist_find (priv->get_secret_requests, info), G_SOURCE_REMOVE); + + priv->get_secret_requests = g_slist_remove (priv->get_secret_requests, info); + + _get_secrets_info_callback (info, NULL, NULL, info->t.idle.error); + + _get_secrets_info_free (info); + return G_SOURCE_REMOVE; } /** * nm_settings_connection_get_secrets: * @self: the #NMSettingsConnection + * @applied_connection: (allow-none): if provided, only request secrets + * if @self equals to @applied_connection. Also, update the secrets + * in the @applied_connection. * @subject: the #NMAuthSubject originating the request * @setting_name: the setting to return secrets for * @flags: flags to modify the secrets request @@ -1006,35 +1181,55 @@ agent_secrets_done_cb (NMAgentManager *manager, **/ NMSettingsConnectionCallId nm_settings_connection_get_secrets (NMSettingsConnection *self, + NMConnection *applied_connection, NMAuthSubject *subject, const char *setting_name, NMSecretAgentGetSecretsFlags flags, const char **hints, NMSettingsConnectionSecretsFunc callback, - gpointer callback_data, - GError **error) + gpointer callback_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GVariant *existing_secrets; NMAgentManagerCallId call_id_a; gs_free char *joined_hints = NULL; + GetSecretsInfo *info; + GError *local = NULL; + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); + g_return_val_if_fail ( !applied_connection + || ( NM_IS_CONNECTION (applied_connection) + && (((NMConnection *) self) != applied_connection)), NULL); + + info = _get_secrets_info_new (self, + applied_connection, + callback, + callback_data); + + priv->get_secret_requests = g_slist_append (priv->get_secret_requests, info); /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. */ if (!priv->system_secrets) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "%s.%d - Internal error; secrets cache invalid.", - __FILE__, __LINE__); - return NULL; + g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "secrets cache invalid"); + goto schedule_dummy; } /* Make sure the request actually requests something we can return */ if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { - g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, - "%s.%d - Connection didn't have requested setting '%s'.", - __FILE__, __LINE__, setting_name); - return NULL; + g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, + "Connection didn't have requested setting '%s'.", + setting_name); + goto schedule_dummy; + } + + if ( applied_connection + && !nm_settings_connection_has_unmodified_applied_connection (self, applied_connection, NM_SETTING_COMPARE_FLAG_NONE)) { + g_set_error_literal (&local, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, + "The connection was modified since activation"); + goto schedule_dummy; } existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); @@ -1048,10 +1243,9 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, setting_name, flags, hints, - agent_secrets_done_cb, - self, - callback, - callback_data); + get_secrets_done_cb, + info); + g_assert (call_id_a); if (existing_secrets) g_variant_unref (existing_secrets); @@ -1061,23 +1255,61 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, flags, (hints && hints[0]) ? (joined_hints = g_strjoinv (",", (char **) hints)) : "(none)"); - priv->reqs_int = g_slist_append (priv->reqs_int, call_id_a); - - return NM_SETTINGS_CONNECTION_CALL_ID (call_id_a); + if (call_id_a) { + info->type = GET_SECRETS_INFO_TYPE_REQ; + info->t.req.id = call_id_a; + } else { +schedule_dummy: + info->type = GET_SECRETS_INFO_TYPE_IDLE; + g_propagate_error (&info->t.idle.error, local); + info->t.idle.id = g_idle_add ((GSourceFunc) get_secrets_idle_cb, info); + } + return info; } -void -nm_settings_connection_cancel_secrets (NMSettingsConnection *self, - NMSettingsConnectionCallId call_id) +static void +_get_secrets_cancel (NMSettingsConnection *self, + GetSecretsInfo *info, + gboolean shutdown) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - if (!g_slist_find (priv->reqs_int, call_id)) + gs_free_error GError *error = NULL; + + if (!g_slist_find (priv->get_secret_requests, info)) g_return_if_reached (); + priv->get_secret_requests = g_slist_remove (priv->get_secret_requests, info); + + if (info->type == GET_SECRETS_INFO_TYPE_REQ) + nm_agent_manager_cancel_secrets (priv->agent_mgr, info->t.req.id); + else + g_source_remove (info->t.idle.id); + + if (shutdown) { + /* Use a different error code. G_IO_ERROR_CANCELLED is only used synchronously + * when the user calls nm_act_request_cancel_secrets(). Disposing the instance + * with pending requests also cancels the requests, but with a different error + * code. */ + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Disposing NMActRequest instance"); + } else { + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_CANCELLED, + "Request cancelled"); + } + + _get_secrets_info_callback (info, NULL, NULL, error); + + _get_secrets_info_free (info); +} + +void +nm_settings_connection_cancel_secrets (NMSettingsConnection *self, + NMSettingsConnectionCallId call_id) +{ _LOGD ("(%p) secrets canceled", call_id); - nm_agent_manager_cancel_secrets (priv->agent_mgr, NM_AGENT_MANAGER_CALL_ID (call_id)); + _get_secrets_cancel (self, call_id, FALSE); } /**** User authorization **************************************/ @@ -1389,7 +1621,7 @@ update_complete (NMSettingsConnection *self, else g_dbus_method_invocation_return_value (info->context, NULL); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, NM_CONNECTION (self), !error, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, !error, info->subject, error ? error->message : NULL); g_clear_object (&info->subject); @@ -1555,7 +1787,7 @@ impl_settings_connection_update_helper (NMSettingsConnection *self, return; error: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, NM_CONNECTION (self), FALSE, subject, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, self, FALSE, subject, error->message); g_clear_object (&tmp); @@ -1603,7 +1835,7 @@ con_delete_cb (NMSettingsConnection *self, else g_dbus_method_invocation_return_value (info->context, NULL); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, !error, info->subject, error ? error->message : NULL); g_free (info); } @@ -1618,7 +1850,7 @@ delete_auth_cb (NMSettingsConnection *self, CallbackInfo *info; if (error) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject, error->message); g_dbus_method_invocation_return_gerror (context, error); return; @@ -1667,7 +1899,7 @@ impl_settings_connection_delete (NMSettingsConnection *self, return; out_err: - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, error->message); + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, subject, error->message); g_dbus_method_invocation_take_error (context, error); } @@ -1681,14 +1913,9 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, GError *error, gpointer user_data) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GDBusMethodInvocation *context = user_data; GVariant *dict; - g_return_if_fail (g_slist_find (priv->reqs_ext, call_id)); - - priv->reqs_ext = g_slist_remove (priv->reqs_ext, call_id); - if (error) g_dbus_method_invocation_return_gerror (context, error); else { @@ -1711,31 +1938,22 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self, GError *error, gpointer user_data) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *setting_name = user_data; - NMSettingsConnectionCallId call_id; - GError *local = NULL; if (!error) { - call_id = nm_settings_connection_get_secrets (self, - subject, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED - | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, - NULL, - dbus_get_agent_secrets_cb, - context, - &local); - if (call_id) { - /* track the request and wait for the callback */ - priv->reqs_ext = g_slist_append (priv->reqs_ext, call_id); - } + nm_settings_connection_get_secrets (self, + NULL, + subject, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED + | NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS, + NULL, + dbus_get_agent_secrets_cb, + context); } - if (error || local) { - g_dbus_method_invocation_return_gerror (context, error ? error : local); - g_clear_error (&local); - } + if (error) + g_dbus_method_invocation_return_gerror (context, error); g_free (setting_name); } @@ -1773,7 +1991,7 @@ clear_secrets_cb (NMSettingsConnection *self, else g_dbus_method_invocation_return_value (info->context, NULL); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, !error, info->subject, error ? error->message : NULL); g_free (info); } @@ -1790,7 +2008,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, if (error) { g_dbus_method_invocation_return_gerror (context, error); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, FALSE, subject, error->message); } else { /* Clear secrets in connection and caches */ @@ -1830,7 +2048,7 @@ impl_settings_connection_clear_secrets (NMSettingsConnection *self, NULL); g_object_unref (subject); } else { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, FALSE, NULL, error->message); g_dbus_method_invocation_take_error (context, error); } @@ -2399,20 +2617,6 @@ constructed (GObject *object) } static void -_cancel_all (NMAgentManager *agent_mgr, GSList **preqs) -{ - while (*preqs) { - NMAgentManagerCallId call_id_a = (*preqs)->data; - - /* Cancel will invoke the complete callback, which in - * turn deletes the current call-id from the list. */ - nm_agent_manager_cancel_secrets (agent_mgr, call_id_a); - - g_return_if_fail (!*preqs || (call_id_a != (*preqs)->data)); - } -} - -static void dispose (GObject *object) { NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); @@ -2422,11 +2626,12 @@ dispose (GObject *object) /* Cancel in-progress secrets requests */ if (priv->agent_mgr) { - /* although @reqs_ext theoretically contains NMSettingsConnectionCallId, - * we still cancel it with nm_agent_manager_cancel_secrets() -- it is - * actually correct. */ - _cancel_all (priv->agent_mgr, &priv->reqs_ext); - _cancel_all (priv->agent_mgr, &priv->reqs_int); + while (priv->get_secret_requests) { + GetSecretsInfo *info = priv->get_secret_requests->data; + + _get_secrets_cancel (self, info, TRUE); + g_return_if_fail (!priv->get_secret_requests || (info != priv->get_secret_requests->data)); + } } if (priv->updated_idle_id) { diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index d7ffbecd4e..5c12a8aca7 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -126,6 +126,10 @@ struct _NMSettingsConnectionClass { GType nm_settings_connection_get_type (void); +gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, + NMConnection *applied_connection, + NMSettingCompareFlags compare_flage); + void nm_settings_connection_commit_changes (NMSettingsConnection *self, NMSettingsConnectionCommitReason commit_reason, NMSettingsConnectionCommitFunc callback, @@ -154,13 +158,13 @@ typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self, gpointer user_data); NMSettingsConnectionCallId nm_settings_connection_get_secrets (NMSettingsConnection *self, + NMConnection *applied_connection, NMAuthSubject *subject, const char *setting_name, NMSecretAgentGetSecretsFlags flags, const char **hints, NMSettingsConnectionSecretsFunc callback, - gpointer callback_data, - GError **error); + gpointer callback_data); void nm_settings_connection_cancel_secrets (NMSettingsConnection *self, NMSettingsConnectionCallId call_id); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 71bcf67494..951f417646 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -430,7 +430,7 @@ nm_settings_get_connection_by_path (NMSettings *self, const char *path) } gboolean -nm_settings_has_connection (NMSettings *self, NMConnection *connection) +nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; @@ -1174,7 +1174,7 @@ send_agent_owned_secrets (NMSettings *self, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_connection_get_path (NM_CONNECTION (for_agent)), + nm_connection_get_path (NM_CONNECTION (connection)), for_agent, subject); g_object_unref (for_agent); @@ -1230,7 +1230,7 @@ pk_add_cb (NMAuthChain *chain, callback (self, added, error, context, subject, callback_data); /* Send agent-owned secrets to the agents */ - if (!error && added && nm_settings_has_connection (self, (NMConnection *) added)) + if (!error && added && nm_settings_has_connection (self, added)) send_agent_owned_secrets (self, added, subject); g_clear_error (&error); @@ -1388,9 +1388,9 @@ impl_settings_add_connection_add_cb (NMSettings *self, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message); } else { g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NM_CONNECTION (connection), TRUE, + context, + g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, subject, NULL); } } @@ -2046,7 +2046,7 @@ hostnamed_properties_changed (GDBusProxy *proxy, g_free (priv->hostname.value); priv->hostname.value = g_strdup (hostname); g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME); - nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL); + nm_dispatcher_call (DISPATCHER_ACTION_HOSTNAME, NULL, NULL, NULL, NULL, NULL, NULL); } g_variant_unref (v_hostname); diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 0801054d66..923b164b04 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -113,7 +113,7 @@ NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings, NMSettingsConnection *nm_settings_get_connection_by_uuid (NMSettings *settings, const char *uuid); -gboolean nm_settings_has_connection (NMSettings *self, NMConnection *connection); +gboolean nm_settings_has_connection (NMSettings *self, NMSettingsConnection *connection); const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 2bf19d4992..881751b77a 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -76,7 +76,6 @@ typedef enum { } VpnState; typedef struct { - NMConnection *connection; gboolean service_can_persist; gboolean connection_can_persist; @@ -136,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); @@ -168,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, @@ -212,7 +214,7 @@ cancel_get_secrets (NMVpnConnection *self) NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); if (priv->secrets_id) { - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), + nm_settings_connection_cancel_secrets (_get_settings_connection (self, FALSE), priv->secrets_id); g_warn_if_fail (!priv->secrets_id); priv->secrets_id = NULL; @@ -278,6 +280,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) { @@ -332,9 +359,7 @@ 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); - + nm_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self)); } static void @@ -433,7 +458,8 @@ _set_vpn_state (NMVpnConnection *self, break; case STATE_PRE_UP: if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_UP, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, priv->ip4_config, @@ -447,11 +473,12 @@ _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_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self)); /* Let dispatcher scripts know we're up and running */ nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_UP, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, priv->ip4_config, @@ -463,14 +490,16 @@ _set_vpn_state (NMVpnConnection *self, case STATE_DEACTIVATING: if (quitting) { nm_dispatcher_call_vpn_sync (DISPATCHER_ACTION_VPN_PRE_DOWN, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, priv->ip4_config, priv->ip6_config); } else { if (!nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_PRE_DOWN, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, priv->ip4_config, @@ -490,14 +519,16 @@ _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, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, NULL, NULL); } else { nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_DOWN, - priv->connection, + _get_settings_connection (self, FALSE), + _get_applied_connection (self), parent_dev, priv->ip_iface, NULL, @@ -674,16 +705,16 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, } NMVpnConnection * -nm_vpn_connection_new (NMConnection *connection, +nm_vpn_connection_new (NMSettingsConnection *settings_connection, NMDevice *parent_device, const char *specific_object, NMAuthSubject *subject) { - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); return (NMVpnConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, - NM_ACTIVE_CONNECTION_INT_CONNECTION, connection, + NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, settings_connection, NM_ACTIVE_CONNECTION_INT_DEVICE, parent_device, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, specific_object, NM_ACTIVE_CONNECTION_INT_SUBJECT, subject, @@ -694,10 +725,9 @@ nm_vpn_connection_new (NMConnection *connection, static const char * nm_vpn_connection_get_service (NMVpnConnection *self) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); NMSettingVpn *s_vpn; - s_vpn = nm_connection_get_setting_vpn (priv->connection); + s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self)); return nm_setting_vpn_get_service_type (s_vpn); } @@ -827,7 +857,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_active_connection_clear_secrets (NM_ACTIVE_CONNECTION (self)); if ((priv->vpn_state >= STATE_WAITING) && (priv->vpn_state <= STATE_ACTIVATED)) { VpnState old_state = priv->vpn_state; @@ -1109,8 +1139,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); @@ -1260,31 +1289,25 @@ nm_vpn_connection_config_get (NMVpnConnection *self, GVariant *dict) guint32 nm_vpn_connection_get_ip4_route_metric (NMVpnConnection *self) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - - if (priv->connection) { - gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip4_config (priv->connection)); + 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) { - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - - if (priv->connection) { - gint64 route_metric = nm_setting_ip_config_get_route_metric (nm_connection_get_setting_ip6_config (priv->connection)); + 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_ip6_config (applied)); - return NM_VPN_ROUTE_METRIC_DEFAULT; + return (route_metric >= 0) ? route_metric : NM_VPN_ROUTE_METRIC_DEFAULT; } static void @@ -1415,7 +1438,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 (priv->connection), + nm_connection_get_setting_ip4_config (_get_applied_connection (self)), route_metric); g_clear_object (&priv->ip4_config); @@ -1550,7 +1573,7 @@ next: /* Merge in user overrides from the NMConnection's IPv6 setting */ nm_ip6_config_merge_setting (config, - nm_connection_get_setting_ip6_config (priv->connection), + nm_connection_get_setting_ip6_config (_get_applied_connection (self)), route_metric); g_clear_object (&priv->ip6_config); @@ -1684,7 +1707,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 (priv->connection, 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 @@ -1851,7 +1874,7 @@ nm_vpn_connection_activate (NMVpnConnection *self) priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - s_vpn = nm_connection_get_setting_vpn (priv->connection); + 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); @@ -1869,25 +1892,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 (c) : NULL; -} - NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *self) { @@ -2059,10 +2063,14 @@ get_secrets_cb (NMSettingsConnection *connection, gpointer user_data) { NMVpnConnection *self = NM_VPN_CONNECTION (user_data); - NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVpnConnectionPrivate *priv; GVariant *dict; - g_return_if_fail (NM_CONNECTION (connection) == priv->connection); + g_return_if_fail (NM_IS_VPN_CONNECTION (self)); + + priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (connection && connection == _get_settings_connection (self, FALSE)); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = NULL; @@ -2083,7 +2091,7 @@ get_secrets_cb (NMSettingsConnection *connection, priv->username = g_strdup (agent_username); } - dict = _hash_with_username (priv->connection, 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"); @@ -2119,7 +2127,6 @@ get_secrets (NMVpnConnection *self, { NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE; - GError *error = NULL; g_return_if_fail (secrets_idx < SECRETS_REQ_LAST); priv->secrets_idx = secrets_idx; @@ -2147,22 +2154,15 @@ 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), + priv->secrets_id = nm_settings_connection_get_secrets (_get_settings_connection (self, FALSE), + _get_applied_connection (self), 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); - } - _set_vpn_state (self, STATE_FAILED, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS, FALSE); - g_clear_error (&error); - } + self); + g_return_if_fail (priv->secrets_id); } static void @@ -2242,17 +2242,6 @@ 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); @@ -2276,13 +2265,13 @@ 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 (self); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); + + g_clear_object (&priv->default_route_manager); + g_clear_object (&priv->route_manager); } static void @@ -2345,7 +2334,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..28a4b04d18 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -70,14 +70,12 @@ typedef struct { GType nm_vpn_connection_get_type (void); -NMVpnConnection * nm_vpn_connection_new (NMConnection *connection, +NMVpnConnection * nm_vpn_connection_new (NMSettingsConnection *settings_connection, NMDevice *parent_device, const char *specific_object, 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); diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index d7947b4621..343997a250 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -64,7 +64,7 @@ nm_vpn_manager_activate_connection (NMVpnManager *manager, NMVpnConnection *vpn, GError **error) { - NMConnection *connection; + NMConnection *applied_connection; NMSettingVpn *s_vpn; NMVpnService *service; NMVpnPluginInfo *plugin_info; @@ -85,9 +85,8 @@ nm_vpn_manager_activate_connection (NMVpnManager *manager, return FALSE; } - connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (vpn)); - g_assert (connection); - s_vpn = nm_connection_get_setting_vpn (connection); + applied_connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (vpn)); + s_vpn = nm_connection_get_setting_vpn (applied_connection); g_assert (s_vpn); service_name = nm_setting_vpn_get_service_type (s_vpn); |