core: re-implement device disconnect using generic auth request signal
authorDan Williams <dcbw@redhat.com>
Fri, 1 Jun 2012 21:53:23 +0000 (16:53 -0500)
committerDan Williams <dcbw@redhat.com>
Fri, 1 Jun 2012 22:05:00 +0000 (17:05 -0500)
src/nm-device.c
src/nm-device.h
src/nm-manager.c

index 5c8ac58..5596516 100644 (file)
@@ -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;
-
-       g_return_val_if_fail (device != NULL, FALSE);
-       g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
+       NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
+       GError *local = NULL;
 
-       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),
index a654d2b..30b9126 100644 (file)
@@ -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
index ce6e43f..ceb4705 100644 (file)
@@ -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,