diff --git a/src/nm-device.c b/src/nm-device.c index 5c8ac58a0..559651603 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -63,6 +63,7 @@ #include "nm-settings-connection.h" #include "nm-connection-provider.h" #include "nm-posix-signals.h" +#include "nm-manager-auth.h" static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); @@ -89,7 +90,6 @@ nm_device_error_quark (void) enum { STATE_CHANGED, - DISCONNECT_REQUEST, AUTOCONNECT_ALLOWED, AUTH_REQUEST, LAST_SIGNAL, @@ -3187,32 +3187,56 @@ nm_device_deactivate (NMDevice *self, NMDeviceStateReason reason) nm_device_set_ip6_config (self, NULL, &ignored); } -gboolean -nm_device_disconnect (NMDevice *device, GError **error) +static void +disconnect_cb (NMDevice *device, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) { - NMDevicePrivate *priv; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + GError *local = NULL; - g_return_val_if_fail (device != NULL, FALSE); - g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - - priv = NM_DEVICE_GET_PRIVATE (device); - if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, - "Cannot disconnect an inactive device."); - return FALSE; + if (error) + dbus_g_method_return_error (context, error); + else { + /* Authorized */ + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED) { + local = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not active"); + dbus_g_method_return_error (context, local); + g_error_free (local); + } else { + priv->autoconnect = FALSE; + nm_device_state_changed (device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); + dbus_g_method_return (context); + } } - - priv->autoconnect = FALSE; - nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); - return TRUE; } static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context) { - g_signal_emit (device, signals[DISCONNECT_REQUEST], 0, context); + GError *error = NULL; + + if (NM_DEVICE_GET_PRIVATE (device)->act_request == NULL) { + error = g_error_new_literal (NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "This device is not active"); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Ask the manager to authenticate this request for us */ + g_signal_emit (device, signals[AUTH_REQUEST], 0, + context, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + TRUE, + disconnect_cb, + NULL); } static gboolean @@ -4141,14 +4165,6 @@ nm_device_class_init (NMDeviceClass *klass) G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); - signals[DISCONNECT_REQUEST] = - g_signal_new (NM_DEVICE_DISCONNECT_REQUEST, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[AUTOCONNECT_ALLOWED] = g_signal_new ("autoconnect-allowed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/nm-device.h b/src/nm-device.h index a654d2b73..30b91260b 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -59,7 +59,6 @@ #define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ /* Internal signal */ -#define NM_DEVICE_DISCONNECT_REQUEST "disconnect-request" #define NM_DEVICE_AUTH_REQUEST "auth-request" @@ -269,8 +268,6 @@ gboolean nm_device_get_firmware_missing (NMDevice *self); gboolean nm_device_activate (NMDevice *device, NMActRequest *req, GError **error); -gboolean nm_device_disconnect (NMDevice *device, GError **error); - void nm_device_set_connection_provider (NMDevice *device, NMConnectionProvider *provider); G_END_DECLS diff --git a/src/nm-manager.c b/src/nm-manager.c index ce6e43fe1..ceb47050f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1532,114 +1532,6 @@ manager_modem_enabled_changed (NMModem *device, gpointer user_data) nm_manager_rfkill_update (NM_MANAGER (user_data), RFKILL_TYPE_WWAN); } -static GError * -deactivate_disconnect_check_error (GError *auth_error, - NMAuthCallResult result, - const char *detail) -{ - if (auth_error) { - nm_log_dbg (LOGD_CORE, "%s request failed: %s", detail, auth_error->message); - return g_error_new (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "%s request failed: %s", - detail, auth_error->message); - } else if (result != NM_AUTH_CALL_RESULT_YES) { - return g_error_new (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Not authorized to %s connections", - detail); - } - return NULL; -} - -static void -disconnect_net_auth_done_cb (NMAuthChain *chain, - GError *auth_error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *error = NULL; - NMAuthCallResult result; - NMDevice *device; - - priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - - result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); - error = deactivate_disconnect_check_error (auth_error, result, "Disconnect"); - if (!error) { - device = nm_auth_chain_get_data (chain, "device"); - if (!nm_device_disconnect (device, &error)) - g_assert (error); - } - - if (error) - dbus_g_method_return_error (context, error); - else - dbus_g_method_return (context); - - g_clear_error (&error); - nm_auth_chain_unref (chain); -} - -static void -manager_device_disconnect_request (NMDevice *device, - DBusGMethodInvocation *context, - NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMActRequest *req; - GError *error = NULL; - gulong sender_uid = G_MAXULONG; - char *error_desc = NULL; - - req = nm_device_get_act_request (device); - if (!req) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "This device is not active"); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - /* Need to check the caller's permissions and stuff before we can - * deactivate the connection. - */ - if (!nm_auth_get_caller_uid (context, - priv->dbus_mgr, - &sender_uid, - &error_desc)) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - error_desc); - dbus_g_method_return_error (context, error); - g_error_free (error); - g_free (error_desc); - return; - } - - /* Yay for root */ - if (0 == sender_uid) { - if (!nm_device_disconnect (device, &error)) { - dbus_g_method_return_error (context, error); - g_clear_error (&error); - } else - dbus_g_method_return (context); - } else { - NMAuthChain *chain; - - /* Otherwise validate the user request */ - chain = nm_auth_chain_new (context, NULL, disconnect_net_auth_done_cb, self); - g_assert (chain); - priv->auth_chains = g_slist_append (priv->auth_chains, chain); - - nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE); - } -} - static void device_auth_done_cb (NMAuthChain *chain, GError *auth_error, @@ -1772,10 +1664,6 @@ add_device (NMManager *self, NMDevice *device) G_CALLBACK (manager_device_state_changed), self); - g_signal_connect (device, NM_DEVICE_DISCONNECT_REQUEST, - G_CALLBACK (manager_device_disconnect_request), - self); - g_signal_connect (device, NM_DEVICE_AUTH_REQUEST, G_CALLBACK (device_auth_request_cb), self); @@ -3082,8 +2970,18 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, priv->auth_chains = g_slist_remove (priv->auth_chains, chain); result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); - error = deactivate_disconnect_check_error (auth_error, result, "Deactivate"); - if (!error) { + if (auth_error) { + nm_log_dbg (LOGD_CORE, "Disconnect request failed: %s", auth_error->message); + error = g_error_new (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Deactivate request failed: %s", + auth_error->message); + } else if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Not authorized to deactivate connections"); + } else { + /* success; deactivation allowed */ active_path = nm_auth_chain_get_data (chain, "path"); if (!nm_manager_deactivate_connection (self, active_path,