diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index fa621a7b5..8d9d83271 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -264,3 +264,55 @@ nm_auth_chain_unref (NMAuthChain *self) g_free (self); } +/************ utils **************/ + +gboolean +nm_auth_is_caller_root (DBusGMethodInvocation *context, + NMDBusManager *dbus_mgr, + gboolean *out_is_root, + const char **out_error_desc) +{ + DBusConnection *connection; + char *sender = NULL; + gulong sender_uid = G_MAXULONG; + gboolean success = FALSE; + DBusError dbus_error; + + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (dbus_mgr != NULL, FALSE); + g_return_val_if_fail (out_is_root != NULL, FALSE); + + *out_is_root = FALSE; + + sender = dbus_g_method_get_sender (context); + if (!sender) { + if (out_error_desc) + *out_error_desc = "Could not determine D-Bus requestor"; + goto out; + } + + connection = nm_dbus_manager_get_dbus_connection (dbus_mgr); + if (!connection) { + if (out_error_desc) + *out_error_desc = "Could not get the D-Bus system bus"; + goto out; + } + + dbus_error_init (&dbus_error); + /* FIXME: do this async */ + sender_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error); + if (dbus_error_is_set (&dbus_error)) { + if (out_error_desc) + *out_error_desc = "Could not determine the Unix user ID of the requestor"; + dbus_error_free (&dbus_error); + goto out; + } + + success = TRUE; + if (0 == sender_uid) + *out_is_root = TRUE; + +out: + return success; +} + diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index faafbdbd2..433f10fea 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -25,6 +25,8 @@ #include #include +#include "nm-dbus-manager.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" @@ -71,5 +73,11 @@ gboolean nm_auth_chain_add_call (NMAuthChain *chain, void nm_auth_chain_unref (NMAuthChain *chain); +/* Utils */ +gboolean nm_auth_is_caller_root (DBusGMethodInvocation *context, + NMDBusManager *dbus_mgr, + gboolean *out_is_root, + const char **out_error_desc); + #endif /* NM_MANAGER_AUTH_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 9bf7f4a87..171ea2625 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2732,9 +2732,9 @@ do_sleep_wake (NMManager *self) } static gboolean -return_permission_denied_error (PolkitAuthority *authority, - const char *detail, - DBusGMethodInvocation *context) +return_no_pk_error (PolkitAuthority *authority, + const char *detail, + DBusGMethodInvocation *context) { GError *error; @@ -2825,7 +2825,9 @@ impl_manager_sleep (NMManager *self, { NMManagerPrivate *priv; NMAuthChain *chain; - GError *error; + GError *error = NULL; + gboolean is_root = FALSE; + const char *error_desc = NULL; g_return_if_fail (NM_IS_MANAGER (self)); @@ -2840,7 +2842,23 @@ impl_manager_sleep (NMManager *self, return; } - if (!return_permission_denied_error (priv->authority, "Permission", context)) + if (!nm_auth_is_caller_root (context, priv->dbus_mgr, &is_root, &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; + } + + /* Root doesn't need PK authentication */ + if (is_root) { + _internal_sleep (self, do_sleep); + dbus_g_method_return (context); + return; + } + + if (!return_no_pk_error (priv->authority, "Permission", context)) return; chain = nm_auth_chain_new (priv->authority, @@ -2943,7 +2961,9 @@ impl_manager_enable (NMManager *self, { NMManagerPrivate *priv; NMAuthChain *chain; - GError *error; + GError *error = NULL; + gboolean is_root = FALSE; + const char *error_desc = NULL; g_return_if_fail (NM_IS_MANAGER (self)); @@ -2958,7 +2978,23 @@ impl_manager_enable (NMManager *self, return; } - if (!return_permission_denied_error (priv->authority, "Permission", context)) + if (!nm_auth_is_caller_root (context, priv->dbus_mgr, &is_root, &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; + } + + /* Root doesn't need PK authentication */ + if (is_root) { + _internal_enable (self, enable); + dbus_g_method_return (context); + return; + } + + if (!return_no_pk_error (priv->authority, "Permission", context)) return; chain = nm_auth_chain_new (priv->authority,