summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-08-01 17:57:13 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-08-17 14:55:34 +0200
commita52d4654ec4d3afbbb0ef70ada55f4a5ddac92db (patch)
treec43141210a2b7a1f4de1c5d1cf069afa92c11b9e
parent3e09aed2a09fab11f66b8228e48dc8f732c65cce (diff)
downloadNetworkManager-a52d4654ec4d3afbbb0ef70ada55f4a5ddac92db.tar.gz
checkpoint: use polkit to check permission
-rw-r--r--policy/org.freedesktop.NetworkManager.policy.in.in10
-rw-r--r--shared/nm-common-macros.h1
-rw-r--r--src/nm-manager.c141
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);
}
/******************************************************************************/