core: improve and fix keeping connection active based on "connection.permissions"

By setting "connection.permissions", a profile is restricted to a
particular user.
That means for example, that another user cannot see, modify, delete,
activate or deactivate the profile. It also means, that the profile
will only autoconnect when the user is logged in (has a session).

Note that root is always able to activate the profile. Likewise, the
user is also allowed to manually activate the own profile, even if no
session currently exists (which can easily happen with `sudo`).

When the user logs out (the session goes away), we want do disconnect
the profile, however there are conflicting goals here:

1) if the profile was activate by root user, then logging out the user
   should not disconnect the profile. The patch fixes that by not
   binding the activation to the connection, if the activation is done
   by the root user.

2) if the profile was activated by the owner when it had no session,
   then it should stay alive until the user logs in (once) and logs
   out again. This is already handled by the previous commit.

   Yes, this point is odd. If you first do

      $ sudo -u $OTHER_USER nmcli connection up $PROFILE

   the profile activates despite not having a session. If you then

      $ ssh guest@localhost nmcli device

   you'll still see the profile active. However, the moment the SSH session
   ends, a session closes and the profile disconnects. It's unclear, how to
   solve that any better. I think, a user who cares about this, should not
   activate the profile without having a session in the first place.

There are quite some special cases, in particular with internal
activations. In those cases we need to decide whether to bind the
activation to the profile's visibility.

Also, expose the "bind" setting in the D-Bus API. Note, that in the future
this flag may be modified via D-Bus API. Like we may also add related API
that allows to tweak the lifetime of the activation.

Also, I think we broke handling of connection visiblity with 37e8c53eee
"core: Introduce helper class to track connection keep alive". This
should be fixed now too, with improved behavior.

Fixes: 37e8c53eee

https://bugzilla.redhat.com/show_bug.cgi?id=1530977
This commit is contained in:
Thomas Haller
2018-11-21 13:30:16 +01:00
parent b4d3334853
commit b635b4d419
13 changed files with 181 additions and 29 deletions

View File

@@ -960,20 +960,25 @@ typedef enum { /*< flags >*/
* @NM_ACTIVATION_STATE_FLAG_IP6_READY: IPv6 setting is completed.
* @NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES: The master has any slave devices attached.
* This only makes sense if the device is a master.
* @NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY: the lifetime
* of the activation is bound to the visilibity of the connection profile,
* which in turn depends on "connection.permissions" and whether a session
* for the user exists. Since: 1.16
*
* Flags describing the current activation state.
*
* Since: 1.10
**/
typedef enum { /*< flags >*/
NM_ACTIVATION_STATE_FLAG_NONE = 0,
NM_ACTIVATION_STATE_FLAG_NONE = 0,
NM_ACTIVATION_STATE_FLAG_IS_MASTER = (1LL << 0),
NM_ACTIVATION_STATE_FLAG_IS_SLAVE = (1LL << 1),
NM_ACTIVATION_STATE_FLAG_LAYER2_READY = (1LL << 2),
NM_ACTIVATION_STATE_FLAG_IP4_READY = (1LL << 3),
NM_ACTIVATION_STATE_FLAG_IP6_READY = (1LL << 4),
NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
NM_ACTIVATION_STATE_FLAG_IS_MASTER = (1LL << 0),
NM_ACTIVATION_STATE_FLAG_IS_SLAVE = (1LL << 1),
NM_ACTIVATION_STATE_FLAG_LAYER2_READY = (1LL << 2),
NM_ACTIVATION_STATE_FLAG_IP4_READY = (1LL << 3),
NM_ACTIVATION_STATE_FLAG_IP6_READY = (1LL << 4),
NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY = (1LL << 6),
} NMActivationStateFlags;
/**

View File

@@ -2384,10 +2384,27 @@ nm_device_get_act_request (NMDevice *self)
return NM_DEVICE_GET_PRIVATE (self)->act_request.obj;
}
NMActivationStateFlags
nm_device_get_activation_state_flags (NMDevice *self)
{
NMActRequest *ac;
g_return_val_if_fail (NM_IS_DEVICE (self), NM_ACTIVATION_STATE_FLAG_NONE);
ac = NM_DEVICE_GET_PRIVATE (self)->act_request.obj;
if (!ac)
return NM_ACTIVATION_STATE_FLAG_NONE;
return nm_active_connection_get_state_flags (NM_ACTIVE_CONNECTION (ac));
}
NMSettingsConnection *
nm_device_get_settings_connection (NMDevice *self)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
NMDevicePrivate *priv;
g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
priv = NM_DEVICE_GET_PRIVATE (self);
return priv->act_request.obj ? nm_act_request_get_settings_connection (priv->act_request.obj) : NULL;
}

View File

@@ -543,6 +543,7 @@ NMConnection * nm_device_get_settings_connection_get_connection (NMDevice *self
NMConnection * nm_device_get_applied_connection (NMDevice *dev);
gboolean nm_device_has_unmodified_applied_connection (NMDevice *self,
NMSettingCompareFlags compare_flags);
NMActivationStateFlags nm_device_get_activation_state_flags (NMDevice *self);
gpointer /* (NMSetting *) */ nm_device_get_applied_setting (NMDevice *dev,
GType setting_type);

View File

@@ -539,6 +539,7 @@ nm_act_request_init (NMActRequest *req)
* @subject: the #NMAuthSubject representing the requestor of the activation
* @activation_type: the #NMActivationType
* @activation_reason: the reason for activation
* @initial_state_flags: the initial state flags.
* @device: the device/interface to configure according to @connection
*
* Creates a new device-based activation request. If an applied connection is
@@ -553,6 +554,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
NMDevice *device)
{
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
@@ -567,6 +569,7 @@ nm_act_request_new (NMSettingsConnection *settings_connection,
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
NM_ACTIVE_CONNECTION_INT_ACTIVATION_TYPE, (int) activation_type,
NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON, (int) activation_reason,
NM_ACTIVE_CONNECTION_STATE_FLAGS, (guint) initial_state_flags,
NULL);
}

View File

@@ -42,6 +42,7 @@ NMActRequest *nm_act_request_new (NMSettingsConnection *settings_connec
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
NMDevice *device);
NMSettingsConnection *nm_act_request_get_settings_connection (NMActRequest *req);

View File

@@ -163,14 +163,18 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, NMActiveConnectionState,
);
#define state_to_string(state) NM_UTILS_LOOKUP_STR (_state_to_string, state)
/* the maximum required buffer size for _state_flags_to_string(). */
#define _NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE (255)
NM_UTILS_FLAGS2STR_DEFINE_STATIC (_state_flags_to_string, NMActivationStateFlags,
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_NONE, "none"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_MASTER, "is-master"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_SLAVE, "is-slave"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LAYER2_READY, "layer2-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP4_READY, "ip4-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP6_READY, "ip6-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES, "master-has-slaves"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_NONE, "none"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_MASTER, "is-master"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_SLAVE, "is-slave"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LAYER2_READY, "layer2-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP4_READY, "ip4-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP6_READY, "ip6-ready"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES, "master-has-slaves"),
NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY, "lifetime-bound-to-profile-visibility"),
);
/*****************************************************************************/
@@ -361,14 +365,20 @@ nm_active_connection_set_state_flags_full (NMActiveConnection *self,
f = (priv->state_flags & ~mask) | (state_flags & mask);
if (f != priv->state_flags) {
char buf1[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
char buf2[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
char buf1[_NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE];
char buf2[_NM_ACTIVATION_STATE_FLAG_TO_STRING_BUFSIZE];
_LOGD ("set state-flags %s (was %s)",
_state_flags_to_string (f, buf1, sizeof (buf1)),
_state_flags_to_string (priv->state_flags, buf2, sizeof (buf2)));
priv->state_flags = f;
_notify (self, PROP_STATE_FLAGS);
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive,
NM_FLAGS_HAS (priv->state_flags,
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY)
? priv->settings_connection.obj
: NULL);
}
}
@@ -1384,6 +1394,12 @@ set_property (GObject *object, guint prop_id,
g_return_if_reached ();
_set_activation_type (self, (NMActivationType) i);
break;
case PROP_STATE_FLAGS:
/* construct-only */
priv->state_flags = g_value_get_uint (value);
nm_assert ((guint) priv->state_flags == g_value_get_uint (value));
nm_assert (!NM_FLAGS_ANY (priv->state_flags, ~NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY));
break;
case PROP_INT_ACTIVATION_REASON:
/* construct-only */
i = g_value_get_int (value);
@@ -1467,13 +1483,12 @@ constructed (GObject *object)
g_steal_pointer (&priv->applied_connection));
}
if (NM_FLAGS_HAS (priv->state_flags,
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY))
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive, priv->settings_connection.obj);
g_return_if_fail (priv->subject);
g_return_if_fail (priv->activation_reason != NM_ACTIVATION_REASON_UNSET);
if (NM_IN_SET ((NMActivationReason) priv->activation_reason,
NM_ACTIVATION_REASON_AUTOCONNECT,
NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES))
nm_keep_alive_set_settings_connection_watch_visible (priv->keep_alive, priv->settings_connection.obj);
}
static void
@@ -1625,7 +1640,7 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
obj_properties[PROP_STATE_FLAGS] =
g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE_FLAGS, "", "",
0, G_MAXUINT32, NM_ACTIVATION_STATE_FLAG_NONE,
G_PARAM_READABLE |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_properties[PROP_DEFAULT] =

View File

@@ -163,6 +163,13 @@ nm_active_connection_set_state_flags (NMActiveConnection *self,
nm_active_connection_set_state_flags_full (self, state_flags, state_flags);
}
static inline void
nm_active_connection_set_state_flags_clear (NMActiveConnection *self,
NMActivationStateFlags state_flags)
{
nm_active_connection_set_state_flags_full (self, NM_ACTIVATION_STATE_FLAG_NONE, state_flags);
}
NMDevice * nm_active_connection_get_device (NMActiveConnection *self);
gboolean nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device);

View File

@@ -46,6 +46,7 @@ typedef struct {
guint64 ac_version_id;
NMDeviceState state;
bool realized:1;
bool activation_lifetime_bound_to_profile_visiblity:1;
NMUnmanFlagOp unmanaged_explicit;
NMActivationReason activation_reason;
} DeviceCheckpoint;
@@ -335,6 +336,9 @@ activate:
subject,
NM_ACTIVATION_TYPE_MANAGED,
dev_checkpoint->activation_reason,
dev_checkpoint->activation_lifetime_bound_to_profile_visiblity
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
: NM_ACTIVATION_STATE_FLAG_NONE,
&local_error)) {
_LOGW ("rollback: reactivation of connection %s/%s failed: %s",
nm_settings_connection_get_id (connection),
@@ -439,6 +443,8 @@ device_checkpoint_create (NMDevice *device)
dev_checkpoint->settings_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection));
dev_checkpoint->ac_version_id = nm_active_connection_version_id_get (NM_ACTIVE_CONNECTION (act_request));
dev_checkpoint->activation_reason = nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (act_request));
dev_checkpoint->activation_lifetime_bound_to_profile_visiblity = NM_FLAGS_HAS (nm_active_connection_get_state_flags (NM_ACTIVE_CONNECTION (act_request)),
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
}
return dev_checkpoint;

View File

@@ -320,6 +320,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self,
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
GError **error);
static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
@@ -2698,6 +2699,18 @@ recheck_assume_connection (NMManager *self,
GError *error = NULL;
subject = nm_auth_subject_new_internal ();
/* Note: the lifetime of the activation connection is always bound to the profiles visiblity
* via NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY.
*
* This only makes a difference, if the profile actually has "connection.permissions"
* set to limit visibility (which is not the case for externally managed, generated profiles).
*
* If we assume a previously active connection whose lifetime was unbound, we now bind it
* after restart. That is not correct, and can mean that the profile becomes subject to
* deactivation after restart (if the user logs out).
*
* This should be improved, but it's unclear how. */
active = _new_active_connection (self,
FALSE,
sett_conn,
@@ -2708,6 +2721,7 @@ recheck_assume_connection (NMManager *self,
subject,
generated ? NM_ACTIVATION_TYPE_EXTERNAL : NM_ACTIVATION_TYPE_ASSUME,
generated ? NM_ACTIVATION_REASON_EXTERNAL : NM_ACTIVATION_REASON_ASSUME,
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
&error);
if (!active) {
@@ -3892,11 +3906,16 @@ ensure_master_active_connection (NMManager *self,
GError **error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
NMActiveConnection *ac;
NMActiveConnection *master_ac = NULL;
NMDeviceState master_state;
gboolean bind_lifetime_to_profile_visibility;
g_assert (connection);
g_assert (master_connection || master_device);
g_return_val_if_fail (connection, NULL);
g_return_val_if_fail (master_connection || master_device, FALSE);
bind_lifetime_to_profile_visibility = NM_FLAGS_HAS (nm_device_get_activation_state_flags (device),
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
/* If the master device isn't activated then we need to activate it using
* compatible connection. If it's already activating we can just proceed.
@@ -3921,8 +3940,16 @@ ensure_master_active_connection (NMManager *self,
if ( (master_state == NM_DEVICE_STATE_ACTIVATED)
|| nm_device_is_activating (master_device)) {
/* Device already using master_connection */
g_assert (device_connection);
return NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (master_device));
g_return_val_if_fail (device_connection, ac);
if (!bind_lifetime_to_profile_visibility) {
/* unbind the lifetime. */
nm_active_connection_set_state_flags_clear (ac,
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
}
return ac;
}
/* If the device is disconnected, find a compatible connection and
@@ -3959,6 +3986,9 @@ ensure_master_active_connection (NMManager *self,
subject,
NM_ACTIVATION_TYPE_MANAGED,
activation_reason,
bind_lifetime_to_profile_visibility
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
: NM_ACTIVATION_STATE_FLAG_NONE,
error);
return master_ac;
}
@@ -4007,6 +4037,9 @@ ensure_master_active_connection (NMManager *self,
subject,
NM_ACTIVATION_TYPE_MANAGED,
activation_reason,
bind_lifetime_to_profile_visibility
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
: NM_ACTIVATION_STATE_FLAG_NONE,
error);
return master_ac;
}
@@ -4168,6 +4201,7 @@ autoconnect_slaves (NMManager *self,
master_device)) {
gs_free SlaveConnectionInfo *slaves = NULL;
guint i, n_slaves = 0;
gboolean bind_lifetime_to_profile_visibility;
slaves = find_slaves (self, master_connection, master_device, &n_slaves);
if (n_slaves > 1) {
@@ -4182,6 +4216,10 @@ autoconnect_slaves (NMManager *self,
GINT_TO_POINTER (!nm_streq0 (value, "index")));
}
bind_lifetime_to_profile_visibility = n_slaves > 0
&& NM_FLAGS_HAS (nm_device_get_activation_state_flags (master_device),
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY);
for (i = 0; i < n_slaves; i++) {
SlaveConnectionInfo *slave = &slaves[i];
const char *uuid;
@@ -4236,6 +4274,9 @@ autoconnect_slaves (NMManager *self,
subject,
NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES,
bind_lifetime_to_profile_visibility
? NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY
: NM_ACTIVATION_STATE_FLAG_NONE,
&local_err);
if (local_err) {
_LOGW (LOGD_CORE, "Slave connection activation failed: %s", local_err->message);
@@ -4296,6 +4337,40 @@ unmanaged_to_disconnected (NMDevice *device)
}
}
static NMActivationStateFlags
_activation_bind_lifetime_to_profile_visibility (NMAuthSubject *subject)
{
if ( nm_auth_subject_is_internal (subject)
|| nm_auth_subject_get_unix_process_uid (subject) == 0) {
/* internal requests and requests from root are always unbound. */
return NM_ACTIVATION_STATE_FLAG_NONE;
}
/* if the activation was not done by internal decision nor root, there
* are the following cases:
*
* - the connection has "connection.permissions" unset and the profile
* is not restricted to a user and commonly always visible. It does
* not hurt to bind the lifetime, because we expect the profile to be
* visible at the moment. If the profile changes (while still being active),
* we want to pick-up changes to the visibility and possibly disconnect.
*
* - the connection has "connection.permissions" set, and the current user
* is the owner:
*
* - Usually, we would expect that the profile is visible at the moment,
* and of course we want to bind the lifetime. The moment the user
* logs out, the connection becomes invisible and disconnects.
*
* - the profile at this time could already be invisible (e.g. if the
* user didn't ceate a proper session (sudo) and manually activates
* an invisible profile. In this case, we still want to bind the
* lifetime, and it will disconnect after the user logs in and logs
* out again. NMKeepAlive takes care of that.
*/
return NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY;
}
/* The parent connection is ready; we can proceed realizing the device and
* progressing the device to disconencted state.
*/
@@ -4425,6 +4500,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError *
subject,
NM_ACTIVATION_TYPE_MANAGED,
nm_active_connection_get_activation_reason (active),
nm_active_connection_get_state_flags (active)
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
error);
if (!parent_ac) {
g_prefix_error (error, "%s failed to activate parent: ", nm_device_get_iface (device));
@@ -4625,6 +4702,7 @@ _new_active_connection (NMManager *self,
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
GError **error)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
@@ -4696,6 +4774,7 @@ _new_active_connection (NMManager *self,
parent_device,
nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)),
activation_reason,
initial_state_flags,
subject);
}
@@ -4705,6 +4784,7 @@ _new_active_connection (NMManager *self,
subject,
activation_type,
activation_reason,
initial_state_flags,
device);
}
@@ -4768,6 +4848,7 @@ fail:
* @activation_type: whether to assume the connection. That is, take over gracefully,
* non-destructible.
* @activation_reason: the reason for activation
* @initial_state_flags: the inital state flags for the activation.
* @error: return location for an error
*
* Begins a new internally-initiated activation of @sett_conn on @device.
@@ -4789,6 +4870,7 @@ nm_manager_activate_connection (NMManager *self,
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
GError **error)
{
NMManagerPrivate *priv;
@@ -4842,6 +4924,7 @@ nm_manager_activate_connection (NMManager *self,
subject,
activation_type,
activation_reason,
initial_state_flags,
error);
if (!active)
return NULL;
@@ -5101,6 +5184,7 @@ impl_manager_activate_connection (NMDBusObject *obj,
subject,
NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_REASON_USER_REQUEST,
_activation_bind_lifetime_to_profile_visibility (subject),
&error);
if (!active)
goto error;
@@ -5375,6 +5459,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj,
subject,
NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_REASON_USER_REQUEST,
_activation_bind_lifetime_to_profile_visibility (subject),
&error);
if (!active)
goto error;

View File

@@ -175,6 +175,7 @@ NMActiveConnection *nm_manager_activate_connection (NMManager *manager,
NMAuthSubject *subject,
NMActivationType activation_type,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
GError **error);
gboolean nm_manager_deactivate_connection (NMManager *manager,

View File

@@ -1284,6 +1284,7 @@ auto_activate_device (NMPolicy *self,
subject,
NM_ACTIVATION_TYPE_MANAGED,
NM_ACTIVATION_REASON_AUTOCONNECT,
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY,
&error);
if (!ac) {
_LOGI (LOGD_DEVICE, "connection '%s' auto-activation failed: %s",
@@ -1674,9 +1675,14 @@ activate_secondary_connections (NMPolicy *self,
GError *error = NULL;
guint32 i;
gboolean success = TRUE;
NMActivationStateFlags initial_state_flags;
s_con = nm_connection_get_setting_connection (connection);
nm_assert (s_con);
nm_assert (NM_IS_SETTING_CONNECTION (s_con));
/* we propagate the activation's state flags. */
initial_state_flags = nm_device_get_activation_state_flags (device)
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY;
for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) {
NMSettingsConnection *sett_conn;
@@ -1700,7 +1706,6 @@ activate_secondary_connections (NMPolicy *self,
}
req = nm_device_get_act_request (device);
g_assert (req);
_LOGD (LOGD_DEVICE, "activating secondary connection '%s (%s)' for base connection '%s (%s)'",
nm_settings_connection_get_id (sett_conn), sec_uuid,
@@ -1713,6 +1718,7 @@ activate_secondary_connections (NMPolicy *self,
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)),
NM_ACTIVATION_TYPE_MANAGED,
nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (req)),
initial_state_flags,
&error);
if (ac)
secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac));
@@ -2162,6 +2168,8 @@ vpn_connection_retry_after_failure (NMVpnConnection *vpn, NMPolicy *self)
nm_active_connection_get_subject (ac),
NM_ACTIVATION_TYPE_MANAGED,
nm_active_connection_get_activation_reason (ac),
( nm_active_connection_get_state_flags (ac)
& NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY),
&error)) {
_LOGW (LOGD_DEVICE, "VPN '%s' reconnect failed: %s",
nm_settings_connection_get_id (connection),

View File

@@ -851,6 +851,7 @@ nm_vpn_connection_new (NMSettingsConnection *settings_connection,
NMDevice *parent_device,
const char *specific_object,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
NMAuthSubject *subject)
{
g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL);
@@ -864,6 +865,7 @@ nm_vpn_connection_new (NMSettingsConnection *settings_connection,
NM_ACTIVE_CONNECTION_INT_SUBJECT, subject,
NM_ACTIVE_CONNECTION_INT_ACTIVATION_REASON, activation_reason,
NM_ACTIVE_CONNECTION_VPN, TRUE,
NM_ACTIVE_CONNECTION_STATE_FLAGS, (guint) initial_state_flags,
NULL);
}

View File

@@ -53,6 +53,7 @@ NMVpnConnection * nm_vpn_connection_new (NMSettingsConnection *settings_connecti
NMDevice *parent_device,
const char *specific_object,
NMActivationReason activation_reason,
NMActivationStateFlags initial_state_flags,
NMAuthSubject *subject);
void nm_vpn_connection_activate (NMVpnConnection *self,