diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2016-08-01 17:57:13 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2016-08-17 14:55:34 +0200 |
commit | a52d4654ec4d3afbbb0ef70ada55f4a5ddac92db (patch) | |
tree | c43141210a2b7a1f4de1c5d1cf069afa92c11b9e | |
parent | 3e09aed2a09fab11f66b8228e48dc8f732c65cce (diff) | |
download | NetworkManager-a52d4654ec4d3afbbb0ef70ada55f4a5ddac92db.tar.gz |
checkpoint: use polkit to check permission
-rw-r--r-- | policy/org.freedesktop.NetworkManager.policy.in.in | 10 | ||||
-rw-r--r-- | shared/nm-common-macros.h | 1 | ||||
-rw-r--r-- | src/nm-manager.c | 141 |
3 files changed, 108 insertions, 44 deletions
diff --git a/policy/org.freedesktop.NetworkManager.policy.in.in b/policy/org.freedesktop.NetworkManager.policy.in.in index 94d5cb8201..e0a147a107 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in.in +++ b/policy/org.freedesktop.NetworkManager.policy.in.in @@ -132,5 +132,15 @@ </defaults> </action> + <action id="org.freedesktop.NetworkManager.checkpoint-rollback"> + <_description>Perform a checkpoint or rollback of interfaces configuration</_description> + <_message>System policy prevents the the creation of a checkpoint or its rollback</_message> + <defaults> + <allow_any>auth_admin_keep</allow_any> + <allow_inactive>auth_admin_keep</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + </policyconfig> diff --git a/shared/nm-common-macros.h b/shared/nm-common-macros.h index 3e5f349f46..627d72abf6 100644 --- a/shared/nm-common-macros.h +++ b/shared/nm-common-macros.h @@ -37,6 +37,7 @@ #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS "org.freedesktop.NetworkManager.settings.modify.global-dns" #define NM_AUTH_PERMISSION_RELOAD "org.freedesktop.NetworkManager.reload" +#define NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK "org.freedesktop.NetworkManager.checkpoint-rollback" #define NM_CLONED_MAC_PRESERVE "preserve" #define NM_CLONED_MAC_PERMANENT "permanent" diff --git a/src/nm-manager.c b/src/nm-manager.c index 9aa5c1360d..9d0a897c09 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -5137,6 +5137,71 @@ _checkpoint_mgr_get (NMManager *self, gboolean create_as_needed) } static void +checkpoint_auth_done_cb (NMAuthChain *chain, + GError *auth_error, + GDBusMethodInvocation *context, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + char *op, *checkpoint_path, **devices; + NMCheckpoint *checkpoint; + NMAuthCallResult result; + guint32 timeout, flags; + GVariant *variant = NULL; + GError *error = NULL; + + op = nm_auth_chain_get_data (chain, "op"); + priv->auth_chains = g_slist_remove (priv->auth_chains, chain); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK); + + if (auth_error) { + error = g_error_new (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "checkpoint check 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 checkpoint/rollback"); + } else { + if (nm_streq0 (op, "create")) { + timeout = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "timeout")); + flags = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "flags")); + devices = nm_auth_chain_get_data (chain, "devices"); + + checkpoint = nm_checkpoint_manager_create (_checkpoint_mgr_get (self, TRUE), + (const char *const *) devices, + timeout, + (NMCheckpointCreateFlags) flags, + &error); + if (checkpoint) { + NMExportedObject *exported; + + exported = NM_EXPORTED_OBJECT (checkpoint); + variant = g_variant_new ("(o)", nm_exported_object_get_path (exported)); + } + } else if (nm_streq0 (op, "destroy")) { + checkpoint_path = nm_auth_chain_get_data (chain, "checkpoint_path"); + nm_checkpoint_manager_destroy (_checkpoint_mgr_get (self, TRUE), + checkpoint_path, &error); + } else if (nm_streq0 (op, "rollback")) { + checkpoint_path = nm_auth_chain_get_data (chain, "checkpoint_path"); + nm_checkpoint_manager_rollback (_checkpoint_mgr_get (self, TRUE), + checkpoint_path, &variant, &error); + } else + g_return_if_reached (); + } + + if (error) + g_dbus_method_invocation_take_error (context, error); + else + g_dbus_method_invocation_return_value (context, variant); + + nm_auth_chain_unref (chain); +} + +static void impl_manager_checkpoint_create (NMManager *self, GDBusMethodInvocation *context, const char *const *devices, @@ -5144,33 +5209,28 @@ impl_manager_checkpoint_create (NMManager *self, guint32 flags) { NMManagerPrivate *priv; - NMCheckpoint *checkpoint; + NMAuthChain *chain; GError *error = NULL; - const char *path; G_STATIC_ASSERT_EXPR (sizeof (flags) <= sizeof (NMCheckpointCreateFlags)); g_return_if_fail (NM_IS_MANAGER (self)); priv = NM_MANAGER_GET_PRIVATE (self); - if (!nm_bus_manager_ensure_root (priv->dbus_mgr, - context, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED)) - return; - - checkpoint = nm_checkpoint_manager_create (_checkpoint_mgr_get (self, TRUE), - (const char *const *) devices, - rollback_timeout, - (NMCheckpointCreateFlags) flags, - &error); - - if (!checkpoint) { + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); g_dbus_method_invocation_take_error (context, error); return; } - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint)); - g_dbus_method_invocation_return_value (context, g_variant_new ("(o)", path)); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "op", "create", NULL); + nm_auth_chain_set_data (chain, "devices", g_strdupv ((char **) devices), (GDestroyNotify) g_strfreev); + nm_auth_chain_set_data (chain, "flags", GUINT_TO_POINTER (flags), NULL); + nm_auth_chain_set_data (chain, "timeout", GUINT_TO_POINTER (rollback_timeout), NULL); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); } static void @@ -5180,26 +5240,24 @@ impl_manager_checkpoint_destroy (NMManager *self, { NMManagerPrivate *priv; GError *error = NULL; - gboolean r; + NMAuthChain *chain; g_return_if_fail (NM_IS_MANAGER (self)); priv = NM_MANAGER_GET_PRIVATE (self); - if (!nm_bus_manager_ensure_root (priv->dbus_mgr, - context, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED)) - return; - - r = nm_checkpoint_manager_destroy (_checkpoint_mgr_get (self, TRUE), - checkpoint_path, &error); - - if (!r) { + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); g_dbus_method_invocation_take_error (context, error); return; } - g_dbus_method_invocation_return_value (context, NULL); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "op", "destroy", NULL); + nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); } static void @@ -5209,29 +5267,24 @@ impl_manager_checkpoint_rollback (NMManager *self, { NMManagerPrivate *priv; GError *error = NULL; - GVariant *results; - gboolean r; + NMAuthChain *chain; g_return_if_fail (NM_IS_MANAGER (self)); priv = NM_MANAGER_GET_PRIVATE (self); - if (!nm_bus_manager_ensure_root (priv->dbus_mgr, - context, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED)) - return; - - r = nm_checkpoint_manager_rollback (_checkpoint_mgr_get (self, TRUE), - checkpoint_path, - &results, - &error); - - if (!r) { + chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + if (!chain) { + error = g_error_new_literal (NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); g_dbus_method_invocation_take_error (context, error); return; } - g_dbus_method_invocation_return_value (context, results); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); + nm_auth_chain_set_data (chain, "op", "rollback", NULL); + nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); } /******************************************************************************/ |