diff options
author | Dan Williams <dcbw@redhat.com> | 2010-05-29 23:11:45 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-05-29 23:11:45 -0700 |
commit | 65818d517e386c03daca08db4be7b53aff94359a (patch) | |
tree | 83ab988f3c56d1e33e4dd6afa11b38d2a5e65bc7 | |
parent | 1e69294204e201ac284e9547d8f41e4a41fbd494 (diff) |
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.
-rw-r--r-- | introspection/nm-manager.xml | 3 | ||||
-rw-r--r-- | policy/org.freedesktop.NetworkManager.policy.in | 9 | ||||
-rw-r--r-- | src/nm-manager-auth.h | 1 | ||||
-rw-r--r-- | src/nm-manager.c | 125 |
4 files changed, 114 insertions, 24 deletions
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 370d98a59e..88686566d0 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -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"> diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index fb8654c249..a912872491 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -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> diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index f0f01c2839..faafbdbd2e 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -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" diff --git a/src/nm-manager.c b/src/nm-manager.c index 984db5fc94..9bf7f4a873 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -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 |