manager: split device creation off from validate_activation_request()

Make validate_activation_request() only do the validation -- split the
determination of the device into find_device_for_activation().

The point of this is to be able complete the connection and actually
create a virtual device after the validation.

I believe this is also somewhat easier to follow now that the procedure
does what its name says.
This commit is contained in:
Lubomir Rintel
2025-01-07 08:33:29 +01:00
parent 25871f1971
commit 57e140d961

View File

@@ -6403,17 +6403,11 @@ nm_manager_activate_connection(NMManager *self,
* @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there
* is only a partial activation. * is only a partial activation.
* @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified) * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified)
* @device_path: the object path of the device to be activated, or NULL
* @out_device: on successful return, the #NMDevice to be activated with @connection
* The caller may pass in a device which shortcuts the lookup by path.
* In this case, the passed in device must have the matching @device_path
* already.
* @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection
* @error: location to store an error on failure * @error: location to store an error on failure
* *
* Performs basic validation on an activation request, including ensuring that * Performs basic permission validation on an activation request: Ensures that
* the requestor is a valid Unix process, is not disallowed in @connection * the requestor is a valid Unix process and is not disallowed in @connection
* permissions, and that a device exists that can activate @connection. * permissions.
* *
* Returns: on success, the #NMAuthSubject representing the requestor, or * Returns: on success, the #NMAuthSubject representing the requestor, or
* %NULL on error * %NULL on error
@@ -6423,13 +6417,8 @@ validate_activation_request(NMManager *self,
GDBusMethodInvocation *context, GDBusMethodInvocation *context,
NMSettingsConnection *sett_conn, NMSettingsConnection *sett_conn,
NMConnection *connection, NMConnection *connection,
const char *device_path,
NMDevice **out_device,
gboolean *out_is_vpn,
GError **error) GError **error)
{ {
NMDevice *device = NULL;
gboolean is_vpn = FALSE;
gs_unref_object NMAuthSubject *subject = NULL; gs_unref_object NMAuthSubject *subject = NULL;
nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn)); nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn));
@@ -6437,8 +6426,6 @@ validate_activation_request(NMManager *self,
nm_assert(sett_conn || connection); nm_assert(sett_conn || connection);
nm_assert(!connection || !sett_conn nm_assert(!connection || !sett_conn
|| connection == nm_settings_connection_get_connection(sett_conn)); || connection == nm_settings_connection_get_connection(sett_conn));
nm_assert(out_device);
nm_assert(out_is_vpn);
if (!connection) if (!connection)
connection = nm_settings_connection_get_connection(sett_conn); connection = nm_settings_connection_get_connection(sett_conn);
@@ -6459,6 +6446,51 @@ validate_activation_request(NMManager *self,
NM_MANAGER_ERROR_PERMISSION_DENIED, NM_MANAGER_ERROR_PERMISSION_DENIED,
error)) error))
return NULL; return NULL;
return g_steal_pointer(&subject);
}
/**
* find_device_for_activation:
* @self: the #NMManager
* @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there
* is only a partial activation.
* @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified)
* @device_path: the object path of the device to be activated, or NULL
* @out_device: on successful return, the #NMDevice to be activated with @connection
* The caller may pass in a device which shortcuts the lookup by path.
* In this case, the passed in device must have the matching @device_path
* already.
* @out_is_vpn: on successful return, %TRUE if @connection is a VPN connection
* @error: location to store an error on failure
*
* Looks up a device that can activate @connection, or indicates the
* connection is a VPN connection that does not require a device.
*
* Returns: %TRUE if the device could be find or connection doesn't
* need one, %FALSE otherwise
*/
static gboolean
find_device_for_activation(NMManager *self,
NMSettingsConnection *sett_conn,
NMConnection *connection,
const char *device_path,
NMDevice **out_device,
gboolean *out_is_vpn,
GError **error)
{
gboolean is_vpn = FALSE;
NMDevice *device = NULL;
nm_assert(!sett_conn || NM_IS_SETTINGS_CONNECTION(sett_conn));
nm_assert(!connection || NM_IS_CONNECTION(connection));
nm_assert(sett_conn || connection);
nm_assert(!connection || !sett_conn
|| connection == nm_settings_connection_get_connection(sett_conn));
nm_assert(out_device);
nm_assert(out_is_vpn);
if (!connection)
connection = nm_settings_connection_get_connection(sett_conn);
is_vpn = _connection_is_vpn(connection); is_vpn = _connection_is_vpn(connection);
@@ -6475,7 +6507,7 @@ validate_activation_request(NMManager *self,
NM_MANAGER_ERROR, NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_DEVICE, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Device not found"); "Device not found");
return NULL; return FALSE;
} }
} else if (!is_vpn) { } else if (!is_vpn) {
gs_free_error GError *local = NULL; gs_free_error GError *local = NULL;
@@ -6497,13 +6529,13 @@ validate_activation_request(NMManager *self,
NM_MANAGER_ERROR_UNKNOWN_DEVICE, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"No suitable device found for this connection (%s).", "No suitable device found for this connection (%s).",
local->message); local->message);
return NULL; return FALSE;
} }
/* Look for an existing device with the connection's interface name */ /* Look for an existing device with the connection's interface name */
iface = nm_manager_get_connection_iface(self, connection, NULL, NULL, error); iface = nm_manager_get_connection_iface(self, connection, NULL, NULL, error);
if (!iface) if (!iface)
return NULL; return FALSE;
device = find_device_by_iface(self, iface, connection, NULL, NULL); device = find_device_by_iface(self, iface, connection, NULL, NULL);
if (!device) { if (!device) {
@@ -6511,7 +6543,7 @@ validate_activation_request(NMManager *self,
NM_MANAGER_ERROR, NM_MANAGER_ERROR,
NM_MANAGER_ERROR_UNKNOWN_DEVICE, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
"Failed to find a compatible device for this connection"); "Failed to find a compatible device for this connection");
return NULL; return FALSE;
} }
} }
} }
@@ -6520,7 +6552,8 @@ validate_activation_request(NMManager *self,
*out_device = device; *out_device = device;
*out_is_vpn = is_vpn; *out_is_vpn = is_vpn;
return g_steal_pointer(&subject);
return TRUE;
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -6637,17 +6670,14 @@ impl_manager_activate_connection(NMDBusObject *obj,
goto error; goto error;
} }
subject = validate_activation_request(self, subject = validate_activation_request(self, invocation, sett_conn, NULL, &error);
invocation,
sett_conn,
NULL,
device_path,
&device,
&is_vpn,
&error);
if (!subject) if (!subject)
goto error; goto error;
if (!find_device_for_activation(self, sett_conn, NULL, device_path, &device, &is_vpn, &error)) {
goto error;
}
active = _new_active_connection(self, active = _new_active_connection(self,
is_vpn, is_vpn,
sett_conn, sett_conn,
@@ -6920,17 +6950,20 @@ impl_manager_add_and_activate_connection(NMDBusObject *obj,
NM_SETTING_PARSE_FLAGS_STRICT, NM_SETTING_PARSE_FLAGS_STRICT,
NULL); NULL);
subject = validate_activation_request(self, subject = validate_activation_request(self, invocation, NULL, incompl_conn, &error);
invocation,
NULL,
incompl_conn,
device_path,
&device,
&is_vpn,
&error);
if (!subject) if (!subject)
goto error; goto error;
if (!find_device_for_activation(self,
NULL,
incompl_conn,
device_path,
&device,
&is_vpn,
&error)) {
goto error;
}
if (is_vpn) { if (is_vpn) {
/* Try to fill the VPN's connection setting and name at least */ /* Try to fill the VPN's connection setting and name at least */
if (!nm_connection_get_setting_vpn(incompl_conn)) { if (!nm_connection_get_setting_vpn(incompl_conn)) {