mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-29 22:00:13 +01:00
core: use NMAuthSubject in D-Bus triggered activation paths
This commit is contained in:
parent
1126e22572
commit
bcef423174
1 changed files with 84 additions and 78 deletions
162
src/nm-manager.c
162
src/nm-manager.c
|
|
@ -192,8 +192,7 @@ struct PendingActivation {
|
|||
PendingActivationFunc callback;
|
||||
gpointer user_data;
|
||||
|
||||
char *dbus_sender;
|
||||
gulong sender_uid;
|
||||
NMAuthSubject *subject;
|
||||
NMAuthChain *chain;
|
||||
const char *wifi_shared_permission;
|
||||
|
||||
|
|
@ -851,19 +850,17 @@ nm_manager_get_state (NMManager *manager)
|
|||
|
||||
static PendingActivation *
|
||||
pending_activation_new (NMManager *manager,
|
||||
char *dbus_sender,
|
||||
gulong sender_uid,
|
||||
NMAuthSubject *subject,
|
||||
NMDevice *device,
|
||||
NMConnection *connection,
|
||||
const char *specific_object_path,
|
||||
PendingActivationFunc callback,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
gpointer user_data)
|
||||
{
|
||||
PendingActivation *pending;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (dbus_sender != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
|
@ -880,8 +877,7 @@ pending_activation_new (NMManager *manager,
|
|||
|
||||
pending->callback = callback;
|
||||
pending->user_data = user_data;
|
||||
pending->dbus_sender = dbus_sender;
|
||||
pending->sender_uid = sender_uid;
|
||||
pending->subject = g_object_ref (subject);
|
||||
|
||||
return pending;
|
||||
}
|
||||
|
|
@ -919,37 +915,38 @@ pending_auth_done (NMAuthChain *chain,
|
|||
g_clear_error (&tmp_error);
|
||||
}
|
||||
|
||||
static void
|
||||
pending_activation_check_authorized (PendingActivation *pending)
|
||||
static gboolean
|
||||
pending_activation_check_authorized (PendingActivation *pending, GError **error)
|
||||
{
|
||||
GError *error;
|
||||
const char *wifi_permission = NULL;
|
||||
|
||||
g_return_if_fail (pending != NULL);
|
||||
g_return_val_if_fail (pending != NULL, FALSE);
|
||||
|
||||
/* First check if the user is allowed to use networking at all, giving
|
||||
* the user a chance to authenticate to gain the permission.
|
||||
*/
|
||||
pending->chain = nm_auth_chain_new_dbus_sender (pending->dbus_sender,
|
||||
pending->sender_uid,
|
||||
pending_auth_done,
|
||||
pending);
|
||||
if (pending->chain) {
|
||||
nm_auth_chain_add_call (pending->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
||||
|
||||
/* Shared wifi connections require special permissions too */
|
||||
wifi_permission = nm_utils_get_shared_wifi_permission (pending->connection);
|
||||
if (wifi_permission) {
|
||||
pending->wifi_shared_permission = wifi_permission;
|
||||
nm_auth_chain_add_call (pending->chain, wifi_permission, TRUE);
|
||||
}
|
||||
} else {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
"Failed to authorize");
|
||||
pending->callback (pending, pending->user_data, error);
|
||||
g_error_free (error);
|
||||
pending->chain = nm_auth_chain_new_subject (pending->subject,
|
||||
NULL,
|
||||
pending_auth_done,
|
||||
pending);
|
||||
if (!pending->chain) {
|
||||
g_set_error_literal (error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
"Failed to authorize");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_auth_chain_add_call (pending->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
||||
|
||||
/* Shared wifi connections require special permissions too */
|
||||
wifi_permission = nm_utils_get_shared_wifi_permission (pending->connection);
|
||||
if (wifi_permission) {
|
||||
pending->wifi_shared_permission = wifi_permission;
|
||||
nm_auth_chain_add_call (pending->chain, wifi_permission, TRUE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -958,9 +955,9 @@ pending_activation_destroy (PendingActivation *pending)
|
|||
g_return_if_fail (pending != NULL);
|
||||
|
||||
g_free (pending->specific_object_path);
|
||||
g_free (pending->dbus_sender);
|
||||
g_clear_object (&pending->device);
|
||||
g_clear_object (&pending->connection);
|
||||
g_clear_object (&pending->subject);
|
||||
|
||||
if (pending->chain)
|
||||
nm_auth_chain_unref (pending->chain);
|
||||
|
|
@ -3129,7 +3126,7 @@ pending_activate (PendingActivation *pending,
|
|||
NM_CONNECTION (new_connection) : pending->connection,
|
||||
pending->specific_object_path,
|
||||
pending->device,
|
||||
pending->dbus_sender,
|
||||
nm_auth_subject_get_dbus_sender (pending->subject),
|
||||
&local);
|
||||
if (!ac) {
|
||||
nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s",
|
||||
|
|
@ -3141,28 +3138,29 @@ pending_activate (PendingActivation *pending,
|
|||
return ac;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static NMAuthSubject *
|
||||
validate_activation_request (NMManager *self,
|
||||
DBusGMethodInvocation *context,
|
||||
NMConnection *connection,
|
||||
const char *device_path,
|
||||
NMDevice **out_device,
|
||||
gboolean *out_vpn,
|
||||
gulong *out_sender_uid,
|
||||
GError **error)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMDevice *device = NULL;
|
||||
gboolean vpn = FALSE;
|
||||
NMAuthSubject *subject = NULL;
|
||||
|
||||
g_assert (connection);
|
||||
|
||||
/* Get caller's UID */
|
||||
if (!nm_dbus_manager_get_caller_info (priv->dbus_mgr, context, NULL, out_sender_uid, NULL)) {
|
||||
/* Validate the caller */
|
||||
subject = nm_auth_subject_new_from_context (context);
|
||||
if (!subject) {
|
||||
g_set_error_literal (error,
|
||||
NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
"Failed to get request UID.");
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check whether it's a VPN or not */
|
||||
|
|
@ -3188,14 +3186,15 @@ validate_activation_request (NMManager *self,
|
|||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
||||
"Device not found");
|
||||
return FALSE;
|
||||
g_object_unref (subject);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (out_device)
|
||||
*out_device = device;
|
||||
if (out_vpn)
|
||||
*out_vpn = vpn;
|
||||
return TRUE;
|
||||
return subject;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
@ -3232,10 +3231,10 @@ impl_manager_activate_connection (NMManager *self,
|
|||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
PendingActivation *pending;
|
||||
NMAuthSubject *subject = NULL;
|
||||
NMConnection *connection;
|
||||
NMDevice *device = NULL;
|
||||
GError *error = NULL;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
|
||||
connection = (NMConnection *) nm_settings_get_connection_by_path (priv->settings, connection_path);
|
||||
if (!connection) {
|
||||
|
|
@ -3245,35 +3244,39 @@ impl_manager_activate_connection (NMManager *self,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (!validate_activation_request (self,
|
||||
context,
|
||||
connection,
|
||||
device_path,
|
||||
&device,
|
||||
NULL,
|
||||
&sender_uid,
|
||||
&error))
|
||||
subject = validate_activation_request (self,
|
||||
context,
|
||||
connection,
|
||||
device_path,
|
||||
&device,
|
||||
NULL,
|
||||
&error);
|
||||
if (!subject)
|
||||
goto error;
|
||||
|
||||
/* Need to check the caller's permissions and stuff before we can
|
||||
* activate the connection.
|
||||
*/
|
||||
pending = pending_activation_new (self,
|
||||
dbus_g_method_get_sender (context),
|
||||
sender_uid,
|
||||
subject,
|
||||
device,
|
||||
connection,
|
||||
specific_object_path,
|
||||
activation_auth_done,
|
||||
context,
|
||||
&error);
|
||||
if (pending) {
|
||||
/* Success */
|
||||
pending_activation_check_authorized (pending);
|
||||
return;
|
||||
context);
|
||||
g_assert (pending);
|
||||
|
||||
if (!pending_activation_check_authorized (pending, &error)) {
|
||||
pending_activation_destroy (pending);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* success */
|
||||
g_object_unref (subject);
|
||||
return;
|
||||
|
||||
error:
|
||||
g_clear_object (&subject);
|
||||
g_assert (error);
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_error_free (error);
|
||||
|
|
@ -3344,10 +3347,10 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
|||
NMConnection *connection = NULL;
|
||||
GSList *all_connections = NULL;
|
||||
PendingActivation *pending;
|
||||
NMAuthSubject *subject = NULL;
|
||||
GError *error = NULL;
|
||||
NMDevice *device = NULL;
|
||||
gboolean vpn = FALSE;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
|
||||
if (!settings || !g_hash_table_size (settings)) {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
|
||||
|
|
@ -3359,14 +3362,14 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
|||
connection = nm_connection_new ();
|
||||
nm_connection_replace_settings (connection, settings, NULL);
|
||||
|
||||
if (!validate_activation_request (self,
|
||||
context,
|
||||
connection,
|
||||
device_path,
|
||||
&device,
|
||||
&vpn,
|
||||
&sender_uid,
|
||||
&error))
|
||||
subject = validate_activation_request (self,
|
||||
context,
|
||||
connection,
|
||||
device_path,
|
||||
&device,
|
||||
&vpn,
|
||||
&error);
|
||||
if (!subject)
|
||||
goto error;
|
||||
|
||||
all_connections = nm_settings_get_connections (priv->settings);
|
||||
|
|
@ -3401,24 +3404,27 @@ impl_manager_add_and_activate_connection (NMManager *self,
|
|||
* activate the connection.
|
||||
*/
|
||||
pending = pending_activation_new (self,
|
||||
dbus_g_method_get_sender (context),
|
||||
sender_uid,
|
||||
subject,
|
||||
device,
|
||||
connection,
|
||||
specific_object_path,
|
||||
add_and_activate_auth_done,
|
||||
context,
|
||||
&error);
|
||||
if (pending) {
|
||||
/* Success! */
|
||||
g_object_unref (connection);
|
||||
pending_activation_check_authorized (pending);
|
||||
return;
|
||||
context);
|
||||
g_assert (pending);
|
||||
|
||||
if (!pending_activation_check_authorized (pending, &error)) {
|
||||
pending_activation_destroy (pending);
|
||||
goto error;
|
||||
}
|
||||
|
||||
g_object_unref (connection);
|
||||
g_object_unref (subject);
|
||||
return; /* Success */
|
||||
|
||||
error:
|
||||
g_clear_object (&connection);
|
||||
g_slist_free (all_connections);
|
||||
g_object_unref (&subject);
|
||||
|
||||
g_assert (error);
|
||||
dbus_g_method_return_error (context, error);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue