core: re-implement device disconnect using generic auth request signal

This commit is contained in:
Dan Williams
2012-06-01 16:53:23 -05:00
parent 0ab9c25646
commit 4692c00be2
3 changed files with 55 additions and 144 deletions

View 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;
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 (error)
dbus_g_method_return_error (context, error);
else {
/* Authorized */
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;
}
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);
return TRUE;
dbus_g_method_return (context);
}
}
}
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),

View 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

View 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,