core: PolicyKit-protect sleep/wake

Default to 'not allowed', distros that need backwards compatibility
can flip this to 'yes' if they need to. At this point, only power
management scripts should call these functions.
This commit is contained in:
Dan Williams 2010-05-29 23:11:45 -07:00
parent 1e69294204
commit 65818d517e
4 changed files with 114 additions and 24 deletions

View file

@ -86,6 +86,7 @@
<method name="Sleep">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_sleep"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<tp:docstring>
Control the NetworkManager daemon's sleep state. When asleep, all
interfaces that it manages are deactivated. When awake, devices are
@ -303,6 +304,7 @@
DEPRECATED. Control the NetworkManager daemon's sleep state. When asleep, all interfaces that it manages are deactivated.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_legacy_sleep"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="wake">
@ -310,6 +312,7 @@
DEPRECATED. Control the NetworkManager daemon's sleep state. When awake, all known interfaces are available to be activated.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_manager_legacy_wake"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="state">

View file

@ -18,6 +18,15 @@
</defaults>
</action>
<action id="org.freedesktop.NetworkManager.sleep-wake">
<_description>Put NetworkManager to sleep or wake it up (should only be used by system power management)</_description>
<_message>System policy prevents putting NetworkManager to sleep or waking it up</_message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>no</allow_active>
</defaults>
</action>
<action id="org.freedesktop.NetworkManager.enable-disable-wifi">
<_description>Enable or disable WiFi devices</_description>
<_message>System policy prevents enabling or disabling WiFi devices</_message>

View file

@ -26,6 +26,7 @@
#include <dbus/dbus-glib.h>
#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network"
#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake"
#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi"
#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan"
#define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections"

View file

@ -71,7 +71,9 @@ static gboolean impl_manager_deactivate_connection (NMManager *manager,
const char *connection_path,
GError **error);
static gboolean impl_manager_sleep (NMManager *manager, gboolean sleep, GError **err);
static void impl_manager_sleep (NMManager *manager,
gboolean do_sleep,
DBusGMethodInvocation *context);
static void impl_manager_enable (NMManager *manager,
gboolean enable,
@ -87,8 +89,8 @@ static gboolean impl_manager_set_logging (NMManager *manager,
/* Legacy 0.6 compatibility interface */
static gboolean impl_manager_legacy_sleep (NMManager *manager, GError **err);
static gboolean impl_manager_legacy_wake (NMManager *manager, GError **err);
static void impl_manager_legacy_sleep (NMManager *manager, DBusGMethodInvocation *context);
static void impl_manager_legacy_wake (NMManager *manager, DBusGMethodInvocation *context);
static gboolean impl_manager_legacy_state (NMManager *manager, guint32 *state, GError **err);
#include "nm-manager-glue.h"
@ -2750,21 +2752,10 @@ return_permission_denied_error (PolkitAuthority *authority,
return TRUE;
}
static gboolean
impl_manager_sleep (NMManager *self, gboolean do_sleep, GError **error)
static void
_internal_sleep (NMManager *self, gboolean do_sleep)
{
NMManagerPrivate *priv;
g_return_val_if_fail (NM_IS_MANAGER (self), FALSE);
priv = NM_MANAGER_GET_PRIVATE (self);
if (priv->sleeping == do_sleep) {
g_set_error (error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
"Already %s", do_sleep ? "asleep" : "awake");
return FALSE;
}
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
nm_log_info (LOGD_SUSPEND, "%s requested (sleeping: %s enabled: %s)",
do_sleep ? "sleep" : "wake",
@ -2776,7 +2767,92 @@ impl_manager_sleep (NMManager *self, gboolean do_sleep, GError **error)
do_sleep_wake (self);
g_object_notify (G_OBJECT (self), NM_MANAGER_SLEEPING);
return TRUE;
}
static void
sleep_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;
NMAuthCallResult result;
gboolean do_sleep;
result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "result"));
do_sleep = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sleep"));
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
if (error) {
nm_log_dbg (LOGD_CORE, "Sleep/wake request failed: %s", error->message);
ret_error = g_error_new (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
"Sleep/wake request failed: %s",
error->message);
dbus_g_method_return_error (context, ret_error);
g_error_free (ret_error);
} else if (result != NM_AUTH_CALL_RESULT_YES) {
ret_error = g_error_new_literal (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_PERMISSION_DENIED,
"Not authorized to sleep/wake");
dbus_g_method_return_error (context, ret_error);
g_error_free (ret_error);
} else {
_internal_sleep (self, do_sleep);
dbus_g_method_return (context);
}
nm_auth_chain_unref (chain);
}
static void
sleep_auth_call_done_cb (NMAuthChain *chain,
const char *permission,
GError *error,
NMAuthCallResult result,
gpointer user_data)
{
if (!error)
nm_auth_chain_set_data (chain, "result", GUINT_TO_POINTER (result), NULL);
}
static void
impl_manager_sleep (NMManager *self,
gboolean do_sleep,
DBusGMethodInvocation *context)
{
NMManagerPrivate *priv;
NMAuthChain *chain;
GError *error;
g_return_if_fail (NM_IS_MANAGER (self));
priv = NM_MANAGER_GET_PRIVATE (self);
if (priv->sleeping == do_sleep) {
error = g_error_new (NM_MANAGER_ERROR,
NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE,
"Already %s", do_sleep ? "asleep" : "awake");
dbus_g_method_return_error (context, error);
g_error_free (error);
return;
}
if (!return_permission_denied_error (priv->authority, "Permission", context))
return;
chain = nm_auth_chain_new (priv->authority,
context,
sleep_auth_done_cb,
sleep_auth_call_done_cb,
self);
g_assert (chain);
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, TRUE);
}
static void
@ -2992,6 +3068,7 @@ impl_manager_get_permissions (NMManager *self,
nm_auth_chain_set_data (chain, "results", results, (GDestroyNotify) g_hash_table_destroy);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE);
@ -2999,16 +3076,16 @@ impl_manager_get_permissions (NMManager *self,
/* Legacy 0.6 compatibility interface */
static gboolean
impl_manager_legacy_sleep (NMManager *manager, GError **error)
static void
impl_manager_legacy_sleep (NMManager *manager, DBusGMethodInvocation *context)
{
return impl_manager_sleep (manager, TRUE, error);
return impl_manager_sleep (manager, TRUE, context);
}
static gboolean
impl_manager_legacy_wake (NMManager *manager, GError **error)
static void
impl_manager_legacy_wake (NMManager *manager, DBusGMethodInvocation *context)
{
return impl_manager_sleep (manager, FALSE, error);
return impl_manager_sleep (manager, FALSE, context);
}
static gboolean