checkpoint: use polkit to check permission

This commit is contained in:
Beniamino Galvani 2016-08-01 17:57:13 +02:00
parent 3e09aed2a0
commit a52d4654ec
3 changed files with 108 additions and 44 deletions

View file

@ -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>

View file

@ -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"

View file

@ -5136,6 +5136,71 @@ _checkpoint_mgr_get (NMManager *self, gboolean create_as_needed)
return priv->checkpoint_mgr;
}
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,
@ -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);
}
/******************************************************************************/