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