mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-15 12:34:55 +00:00
core: PolicyKit protect Deactivate and Disconnect
This commit is contained in:
parent
25e758c770
commit
ae4b47ca99
|
@ -65,10 +65,11 @@
|
|||
</property>
|
||||
|
||||
<method name="Disconnect">
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_disconnect"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<tp:docstring>
|
||||
Disconnects a device and prevents the device from automatically activating further connections without user intervention.
|
||||
</tp:docstring>
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_disconnect"/>
|
||||
</method>
|
||||
|
||||
<signal name="StateChanged">
|
||||
|
|
|
@ -31,16 +31,19 @@ object. dbus-glib generates the same bound function names for D-Bus the methods
|
|||
|
||||
<method name="DeactivateConnection">
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_deactivate_connection"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="active_connection" type="o" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="Sleep">
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_sleep"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="sleep" type="b" direction="in"/>
|
||||
</method>
|
||||
|
||||
<method name="Enable">
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_enable"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="enable" type="b" direction="in"/>
|
||||
</method>
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
Deactivate an active connection.
|
||||
</tp:docstring>
|
||||
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_deactivate_connection"/>
|
||||
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
|
||||
<arg name="active_connection" type="o" direction="in">
|
||||
<tp:docstring>
|
||||
The currently active connection to deactivate.
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-device-interface.h"
|
||||
|
@ -26,8 +28,8 @@
|
|||
#include "nm-properties-changed-signal.h"
|
||||
#include "nm-rfkill.h"
|
||||
|
||||
static gboolean impl_device_disconnect (NMDeviceInterface *device,
|
||||
GError **error);
|
||||
static void impl_device_disconnect (NMDeviceInterface *device,
|
||||
DBusGMethodInvocation *context);
|
||||
|
||||
#include "nm-device-interface-glue.h"
|
||||
|
||||
|
@ -211,6 +213,13 @@ nm_device_interface_init (gpointer g_iface)
|
|||
G_TYPE_NONE, 3,
|
||||
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
|
||||
g_signal_new (NM_DEVICE_INTERFACE_DISCONNECT_REQUEST,
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
|
||||
dbus_g_object_type_install_info (iface_type,
|
||||
&dbus_glib_nm_device_interface_object_info);
|
||||
|
||||
|
@ -334,11 +343,11 @@ nm_device_interface_disconnect (NMDeviceInterface *device,
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
impl_device_disconnect (NMDeviceInterface *device,
|
||||
GError **error)
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
return nm_device_interface_disconnect (device, error);
|
||||
g_signal_emit_by_name (device, NM_DEVICE_INTERFACE_DISCONNECT_REQUEST, context);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -45,6 +45,8 @@ typedef enum
|
|||
#define NM_DEVICE_INTERFACE_ERROR (nm_device_interface_error_quark ())
|
||||
#define NM_TYPE_DEVICE_INTERFACE_ERROR (nm_device_interface_error_get_type ())
|
||||
|
||||
#define NM_DEVICE_INTERFACE_DISCONNECT_REQUEST "disconnect-request"
|
||||
|
||||
#define NM_DEVICE_INTERFACE_UDI "udi"
|
||||
#define NM_DEVICE_INTERFACE_IFACE "interface"
|
||||
#define NM_DEVICE_INTERFACE_DRIVER "driver"
|
||||
|
|
415
src/nm-manager.c
415
src/nm-manager.c
|
@ -67,9 +67,9 @@ static void impl_manager_activate_connection (NMManager *manager,
|
|||
const char *specific_object_path,
|
||||
DBusGMethodInvocation *context);
|
||||
|
||||
static gboolean impl_manager_deactivate_connection (NMManager *manager,
|
||||
static void impl_manager_deactivate_connection (NMManager *manager,
|
||||
const char *connection_path,
|
||||
GError **error);
|
||||
DBusGMethodInvocation *context);
|
||||
|
||||
static void impl_manager_sleep (NMManager *manager,
|
||||
gboolean do_sleep,
|
||||
|
@ -714,6 +714,41 @@ out:
|
|||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_user_authorized (NMDBusManager *dbus_mgr,
|
||||
DBusGProxy *user_proxy,
|
||||
DBusGMethodInvocation *context,
|
||||
NMConnectionScope scope,
|
||||
gulong *out_sender_uid,
|
||||
const char **out_error_desc)
|
||||
{
|
||||
g_return_val_if_fail (dbus_mgr != NULL, FALSE);
|
||||
g_return_val_if_fail (user_proxy != NULL, FALSE);
|
||||
g_return_val_if_fail (context != NULL, FALSE);
|
||||
g_return_val_if_fail (out_sender_uid != NULL, FALSE);
|
||||
g_return_val_if_fail (out_error_desc != NULL, FALSE);
|
||||
|
||||
*out_sender_uid = G_MAXULONG;
|
||||
|
||||
/* Get the UID */
|
||||
if (!nm_auth_get_caller_uid (context, dbus_mgr, out_sender_uid, out_error_desc))
|
||||
return FALSE;
|
||||
|
||||
/* root gets to do anything */
|
||||
if (0 == *out_sender_uid)
|
||||
return TRUE;
|
||||
|
||||
/* Check whether the UID is authorized for user connections */
|
||||
if ( scope == NM_CONNECTION_SCOPE_USER
|
||||
&& !nm_auth_uid_authorized (*out_sender_uid,
|
||||
dbus_mgr,
|
||||
user_proxy,
|
||||
out_error_desc))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
pending_activation_check_authorized (PendingActivation *pending,
|
||||
NMDBusManager *dbus_mgr,
|
||||
|
@ -727,27 +762,11 @@ pending_activation_check_authorized (PendingActivation *pending,
|
|||
g_return_if_fail (dbus_mgr != NULL);
|
||||
g_return_if_fail (user_proxy != NULL);
|
||||
|
||||
/* Get the UID */
|
||||
if (!nm_auth_get_caller_uid (pending->context, dbus_mgr, &sender_uid, &error_desc)) {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
error_desc);
|
||||
pending->callback (pending, error);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* root gets to do anything */
|
||||
if (0 == sender_uid) {
|
||||
pending->callback (pending, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check whether the UID is authorized for user connections */
|
||||
if ( pending->scope == NM_CONNECTION_SCOPE_USER
|
||||
&& !nm_auth_uid_authorized (sender_uid,
|
||||
dbus_mgr,
|
||||
if (!check_user_authorized (dbus_mgr,
|
||||
user_proxy,
|
||||
pending->context,
|
||||
pending->scope,
|
||||
&sender_uid,
|
||||
&error_desc)) {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
|
@ -757,6 +776,12 @@ pending_activation_check_authorized (PendingActivation *pending,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Yay for root */
|
||||
if (0 == sender_uid) {
|
||||
pending->callback (pending, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* First check if the user is allowed to use networking at all, giving
|
||||
* the user a chance to authenticate to gain the permission.
|
||||
*/
|
||||
|
@ -765,6 +790,7 @@ pending_activation_check_authorized (PendingActivation *pending,
|
|||
NULL,
|
||||
pending_auth_net_done,
|
||||
pending);
|
||||
g_assert (pending->chain);
|
||||
nm_auth_chain_add_call (pending->chain,
|
||||
NM_AUTH_PERMISSION_NETWORK_CONTROL,
|
||||
TRUE);
|
||||
|
@ -1805,6 +1831,175 @@ 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 user connections",
|
||||
detail);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_user_auth_done_cb (NMAuthChain *chain,
|
||||
GError *error,
|
||||
DBusGMethodInvocation *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *ret_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_USE_USER_CONNECTIONS));
|
||||
ret_error = deactivate_disconnect_check_error (error, result, "Disconnect");
|
||||
g_message ("%s: here! ret error %p", __func__, ret_error);
|
||||
if (!ret_error) {
|
||||
/* Everything authorized, deactivate the connection */
|
||||
device = nm_auth_chain_get_data (chain, "device");
|
||||
g_message ("%s: here! device %p", __func__, device);
|
||||
if (nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error))
|
||||
dbus_g_method_return (context);
|
||||
}
|
||||
|
||||
if (ret_error)
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_clear_error (&ret_error);
|
||||
|
||||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_net_auth_done_cb (NMAuthChain *chain,
|
||||
GError *error,
|
||||
DBusGMethodInvocation *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *ret_error = NULL;
|
||||
NMAuthCallResult result;
|
||||
NMConnectionScope scope;
|
||||
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));
|
||||
ret_error = deactivate_disconnect_check_error (error, result, "Disconnect");
|
||||
g_message ("%s: here! ret error %p", __func__, ret_error);
|
||||
if (ret_error) {
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_error_free (ret_error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If it's a system connection, we're done */
|
||||
device = nm_auth_chain_get_data (chain, "device");
|
||||
scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope"));
|
||||
if (scope == NM_CONNECTION_SCOPE_USER) {
|
||||
NMAuthChain *user_chain;
|
||||
|
||||
/* It's a user connection, so we need to ensure the caller is
|
||||
* authorized to manipulate user connections.
|
||||
*/
|
||||
user_chain = nm_auth_chain_new (priv->authority, context, NULL, disconnect_user_auth_done_cb, self);
|
||||
g_assert (user_chain);
|
||||
priv->auth_chains = g_slist_append (priv->auth_chains, user_chain);
|
||||
|
||||
nm_auth_chain_set_data (user_chain, "device", g_object_ref (device), g_object_unref);
|
||||
nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL);
|
||||
nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE);
|
||||
} else {
|
||||
if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) {
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_clear_error (&ret_error);
|
||||
} else
|
||||
dbus_g_method_return (context);
|
||||
}
|
||||
|
||||
done:
|
||||
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;
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
NMConnectionScope scope;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
const 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;
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
/* Need to check the caller's permissions and stuff before we can
|
||||
* deactivate the connection.
|
||||
*/
|
||||
scope = nm_connection_get_scope (connection);
|
||||
if (!check_user_authorized (priv->dbus_mgr,
|
||||
priv->user_proxy,
|
||||
context,
|
||||
scope,
|
||||
&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);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Yay for root */
|
||||
if (0 == sender_uid) {
|
||||
if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (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 (priv->authority, 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_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL);
|
||||
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_device (NMManager *self, NMDevice *device)
|
||||
{
|
||||
|
@ -1832,6 +2027,10 @@ add_device (NMManager *self, NMDevice *device)
|
|||
G_CALLBACK (manager_device_state_changed),
|
||||
self);
|
||||
|
||||
g_signal_connect (device, NM_DEVICE_INTERFACE_DISCONNECT_REQUEST,
|
||||
G_CALLBACK (manager_device_disconnect_request),
|
||||
self);
|
||||
|
||||
if (NM_IS_DEVICE_WIFI (device)) {
|
||||
/* Attach to the access-point-added signal so that the manager can fill
|
||||
* non-SSID-broadcasting APs with an SSID.
|
||||
|
@ -2895,15 +3094,173 @@ done:
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
impl_manager_deactivate_connection (NMManager *manager,
|
||||
const char *connection_path,
|
||||
GError **error)
|
||||
static void
|
||||
deactivate_user_auth_done_cb (NMAuthChain *chain,
|
||||
GError *error,
|
||||
DBusGMethodInvocation *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
return nm_manager_deactivate_connection (manager,
|
||||
connection_path,
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *ret_error = NULL;
|
||||
NMAuthCallResult result;
|
||||
|
||||
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
||||
|
||||
result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS));
|
||||
ret_error = deactivate_disconnect_check_error (error, result, "Deactivate");
|
||||
if (!ret_error) {
|
||||
/* Everything authorized, deactivate the connection */
|
||||
if (nm_manager_deactivate_connection (self,
|
||||
nm_auth_chain_get_data (chain, "path"),
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED,
|
||||
error);
|
||||
&ret_error))
|
||||
dbus_g_method_return (context);
|
||||
}
|
||||
|
||||
if (ret_error)
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_clear_error (&ret_error);
|
||||
|
||||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static void
|
||||
deactivate_net_auth_done_cb (NMAuthChain *chain,
|
||||
GError *error,
|
||||
DBusGMethodInvocation *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *ret_error = NULL;
|
||||
NMAuthCallResult result;
|
||||
const char *active_path;
|
||||
NMConnectionScope scope;
|
||||
|
||||
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));
|
||||
ret_error = deactivate_disconnect_check_error (error, result, "Deactivate");
|
||||
if (ret_error) {
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_error_free (ret_error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If it's a system connection, we're done */
|
||||
active_path = nm_auth_chain_get_data (chain, "path");
|
||||
scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope"));
|
||||
if (scope == NM_CONNECTION_SCOPE_USER) {
|
||||
NMAuthChain *user_chain;
|
||||
|
||||
/* It's a user connection, so we need to ensure the caller is
|
||||
* authorized to manipulate user connections.
|
||||
*/
|
||||
user_chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_user_auth_done_cb, self);
|
||||
g_assert (user_chain);
|
||||
priv->auth_chains = g_slist_append (priv->auth_chains, user_chain);
|
||||
|
||||
nm_auth_chain_set_data (user_chain, "path", g_strdup (active_path), g_free);
|
||||
nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL);
|
||||
nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE);
|
||||
} else {
|
||||
if (!nm_manager_deactivate_connection (self,
|
||||
active_path,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED,
|
||||
&ret_error)) {
|
||||
dbus_g_method_return_error (context, ret_error);
|
||||
g_clear_error (&ret_error);
|
||||
} else
|
||||
dbus_g_method_return (context);
|
||||
}
|
||||
|
||||
done:
|
||||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_manager_deactivate_connection (NMManager *self,
|
||||
const char *active_path,
|
||||
DBusGMethodInvocation *context)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
NMConnection *connection = NULL;
|
||||
GError *error = NULL;
|
||||
GSList *iter;
|
||||
NMAuthChain *chain;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
NMConnectionScope scope;
|
||||
const char *error_desc = NULL;
|
||||
|
||||
/* Check for device connections first */
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||
NMActRequest *req;
|
||||
const char *req_path = NULL;
|
||||
|
||||
req = nm_device_get_act_request (NM_DEVICE (iter->data));
|
||||
if (req)
|
||||
req_path = nm_act_request_get_active_connection_path (req);
|
||||
|
||||
if (req_path && !strcmp (active_path, req_path)) {
|
||||
connection = nm_act_request_get_connection (req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Maybe it's a VPN */
|
||||
if (!connection)
|
||||
connection = nm_vpn_manager_get_connection_for_active (priv->vpn_manager, active_path);
|
||||
|
||||
if (!connection) {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE,
|
||||
"The connection was 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.
|
||||
*/
|
||||
scope = nm_connection_get_scope (connection);
|
||||
if (!check_user_authorized (priv->dbus_mgr,
|
||||
priv->user_proxy,
|
||||
context,
|
||||
scope,
|
||||
&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);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Yay for root */
|
||||
if (0 == sender_uid) {
|
||||
if (!nm_manager_deactivate_connection (self,
|
||||
active_path,
|
||||
NM_DEVICE_STATE_REASON_USER_REQUESTED,
|
||||
&error)) {
|
||||
dbus_g_method_return_error (context, error);
|
||||
g_clear_error (&error);
|
||||
} else
|
||||
dbus_g_method_return (context);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise validate the user request */
|
||||
chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_net_auth_done_cb, self);
|
||||
g_assert (chain);
|
||||
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
||||
|
||||
nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free);
|
||||
nm_auth_chain_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL);
|
||||
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -304,6 +304,33 @@ nm_vpn_manager_get_active_connections (NMVPNManager *manager)
|
|||
return list;
|
||||
}
|
||||
|
||||
NMConnection *
|
||||
nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
|
||||
const char *active_path)
|
||||
{
|
||||
NMVPNManagerPrivate *priv;
|
||||
GSList *iter;
|
||||
|
||||
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
|
||||
|
||||
priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
|
||||
for (iter = priv->services; iter; iter = g_slist_next (iter)) {
|
||||
GSList *active, *elt;
|
||||
|
||||
active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data));
|
||||
for (elt = active; elt; elt = g_slist_next (elt)) {
|
||||
NMVPNConnection *candidate = NM_VPN_CONNECTION (elt->data);
|
||||
const char *ac_path;
|
||||
|
||||
ac_path = nm_vpn_connection_get_active_connection_path (candidate);
|
||||
if (ac_path && !strcmp (ac_path, active_path))
|
||||
return nm_vpn_connection_get_connection (candidate);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NMVPNManager *
|
||||
nm_vpn_manager_get (void)
|
||||
{
|
||||
|
|
|
@ -83,4 +83,7 @@ void nm_vpn_manager_add_active_connections (NMVPNManager *manager,
|
|||
|
||||
GSList *nm_vpn_manager_get_active_connections (NMVPNManager *manager);
|
||||
|
||||
NMConnection *nm_vpn_manager_get_connection_for_active (NMVPNManager *manager,
|
||||
const char *active_path);
|
||||
|
||||
#endif /* NM_VPN_VPN_MANAGER_H */
|
||||
|
|
Loading…
Reference in a new issue