summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--actions/org.freedesktop.policykit.policy.in4
-rw-r--r--docs/man/Makefile.am2
-rw-r--r--docs/man/pklalockdown.xml136
-rw-r--r--docs/polkit/polkit-1-sections.txt2
-rw-r--r--src/polkit/polkitauthority.c6
-rw-r--r--src/polkit/polkitauthorizationresult.c13
-rw-r--r--src/polkit/polkitauthorizationresult.h2
-rw-r--r--src/polkitbackend/polkitbackendinteractiveauthority.c9
-rw-r--r--src/polkitbackend/polkitbackendlocalauthority.c503
-rw-r--r--src/programs/Makefile.am15
-rw-r--r--src/programs/pklalockdown.c243
11 files changed, 525 insertions, 410 deletions
diff --git a/actions/org.freedesktop.policykit.policy.in b/actions/org.freedesktop.policykit.policy.in
index 3961001..fc55649 100644
--- a/actions/org.freedesktop.policykit.policy.in
+++ b/actions/org.freedesktop.policykit.policy.in
@@ -59,8 +59,8 @@
</defaults>
</action>
- <action id="org.freedesktop.policykit.localauthority.lockdown">
- <_description>Configure lockdown on the Local Authority</_description>
+ <action id="org.freedesktop.policykit.lockdown">
+ <_description>Configure lock down for an action</_description>
<_message>Authentication is required to configure lock down policy</_message>
<defaults>
<allow_any>no</allow_any>
diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index 6f164c9..076608b 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -10,7 +10,6 @@ man_MANS = \
pkexec.1 \
pkcheck.1 \
pkaction.1 \
- pklalockdown.1 \
$(NULL)
%.8 %.1 : %.xml
@@ -25,7 +24,6 @@ EXTRA_DIST = \
pkexec.xml \
pkcheck.xml \
pkaction.xml \
- pklalockdown.xml \
$(NULL)
clean-local:
diff --git a/docs/man/pklalockdown.xml b/docs/man/pklalockdown.xml
deleted file mode 100644
index 74e4f5d..0000000
--- a/docs/man/pklalockdown.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-<!ENTITY version SYSTEM "../version.xml">
-]>
-<refentry id="pklalockdown.1" xmlns:xi="http://www.w3.org/2003/XInclude">
- <refentryinfo>
- <title>pklalockdown</title>
- <date>May 2009</date>
- <productname>polkit</productname>
- </refentryinfo>
-
- <refmeta>
- <refentrytitle>pklalockdown</refentrytitle>
- <manvolnum>1</manvolnum>
- <refmiscinfo class="version"></refmiscinfo>
- </refmeta>
-
- <refnamediv>
- <refname>pklalockdown</refname>
- <refpurpose>Configure lockdown for the Local Authority</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>pklalockdown</command>
- <arg><option>--version</option></arg>
- <arg><option>--help</option></arg>
- </cmdsynopsis>
-
- <cmdsynopsis>
- <command>pklalockdown</command>
- <arg choice="plain">
- <option>--lockdown</option>
- <replaceable>action</replaceable>
- </arg>
- </cmdsynopsis>
-
- <cmdsynopsis>
- <command>pklalockdown</command>
- <arg choice="plain">
- <option>--remove-lockdown</option>
- <replaceable>action</replaceable>
- </arg>
- </cmdsynopsis>
-
- </refsynopsisdiv>
-
- <refsect1 id="pklalockdown-description">
- <title>DESCRIPTION</title>
- <para>
- <command>pklalockdown</command> is used to configure lockdown
- for the Local Authority.
- </para>
- <para>
- The effect of locking down an action is that administrator
- authentication is always needed in order for subjects to acquire
- the authorization for the action in question (and the subject
- has to be in an active session on a local console). The obtained
- authorization is temporary and as such typically expires five
- minutes after being obtained.
- </para>
- <para>
- To lock down <replaceable>action</replaceable> use the <option>--lockdown</option> option.
- To remove a lockdown for <replaceable>action</replaceable> use the <option>--remove-lockdown</option> option.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-required-auhtz">
- <title>REQUIRED AUTHORIZATIONS</title>
- <para>
- The <emphasis>org.freedesktop.policykit.localauthority.lockdown</emphasis>
- authorization is needed to add or remove lockdown. By default,
- this authorization requires administrator authentication and
- cannot be retained.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-impl-details">
- <title>IMPLEMENTATION DETAILS</title>
- <para>
- Lockdown is implemented through <filename>.pkla</filename>
- files. Locked down actions supersede other most other Local
- Authority configuration as the <filename>.pkla</filename> files
- are placed
- in <filename>/var/lib/polkit-1/localauthority90-mandatory.d</filename>.
- <para>
- </para>
- Programs checking authorizations can check whether an action is
- locked down via by checking
- the <emphasis>polkit.localauthority.lockdown</emphasis> key/value pair in
- the details of the authorization response.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-return-values">
- <title>RETURN VALUE</title>
- <para>
- On success <command>pklalockdown</command> returns 0. Otherwise a
- non-zero value is returned and a diagnostic message is printed
- on standard error.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-author"><title>AUTHOR</title>
- <para>
- Written by David Zeuthen <email>davidz@redhat.com</email> with
- a lot of help from many others.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-bugs">
- <title>BUGS</title>
- <para>
- Please send bug reports to either the distribution or the
- polkit-devel mailing list,
- see the link <ulink url="http://lists.freedesktop.org/mailman/listinfo/polkit-devel"/>
- on how to subscribe.
- </para>
- </refsect1>
-
- <refsect1 id="pklalockdown-see-also">
- <title>SEE ALSO</title>
- <para>
- <citerefentry>
- <refentrytitle>polkit</refentrytitle><manvolnum>8</manvolnum>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>pkcheck</refentrytitle><manvolnum>1</manvolnum>
- </citerefentry>,
- <citerefentry>
- <refentrytitle>pklocalauthority</refentrytitle><manvolnum>8</manvolnum>
- </citerefentry>
- </para>
- </refsect1>
-</refentry>
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
index 2d24e98..ac902b6 100644
--- a/docs/polkit/polkit-1-sections.txt
+++ b/docs/polkit/polkit-1-sections.txt
@@ -74,7 +74,7 @@ polkit_authorization_result_get_is_authorized
polkit_authorization_result_get_is_challenge
polkit_authorization_result_get_retains_authorization
polkit_authorization_result_get_temporary_authorization_id
-polkit_authorization_result_get_local_authority_lock_down
+polkit_authorization_result_get_locked_down
polkit_authorization_result_get_details
<SUBSECTION Standard>
PolkitAuthorizationResultClass
diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
index 0a75b6d..f29be09 100644
--- a/src/polkit/polkitauthority.c
+++ b/src/polkit/polkitauthority.c
@@ -1312,7 +1312,7 @@ polkit_authority_revoke_temporary_authorizations (PolkitAuthority *authority
* @res: A #GAsyncResult obtained from the callback.
* @error: Return location for error or %NULL.
*
- * Finished revoking temporary authorizations.
+ * Finishes revoking temporary authorizations.
*
* Returns: %TRUE if all the temporary authorizations was revoked, %FALSE if error is set.
**/
@@ -1431,7 +1431,7 @@ polkit_authority_revoke_temporary_authorization_by_id (PolkitAuthority *auth
* @res: A #GAsyncResult obtained from the callback.
* @error: Return location for error or %NULL.
*
- * Finished revoking a temporary authorization by id.
+ * Finishes revoking a temporary authorization by id.
*
* Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
**/
@@ -1550,7 +1550,7 @@ polkit_authority_add_lockdown_for_action (PolkitAuthority *authority,
* @res: A #GAsyncResult obtained from the callback.
* @error: Return location for error or %NULL.
*
- * Finished locking down an action.
+ * Finishes locking down an action.
*
* Returns: %TRUE if the action was locked down, %FALSE if error is set.
**/
diff --git a/src/polkit/polkitauthorizationresult.c b/src/polkit/polkitauthorizationresult.c
index e55ae88..20c1434 100644
--- a/src/polkit/polkitauthorizationresult.c
+++ b/src/polkit/polkitauthorizationresult.c
@@ -278,25 +278,26 @@ polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationR
}
/**
- * polkit_authorization_result_get_local_authority_lock_down:
+ * polkit_authorization_result_get_locked_down:
* @result: A #PolkitAuthorizationResult.
*
- * Gets whether the action is locked down in the Local Authority via pklalockdown(1).
+ * Gets whether the action is locked down via
+ * e.g. polkit_authority_add_lockdown_for_action().
*
* This method simply reads the value of the key/value pair in @details with the
- * key <literal>polkit.localauthority.lockdown</literal>.
+ * key <literal>polkit.lockdown</literal>.
*
- * Returns: %TRUE if the authorization is or will be temporary.
+ * Returns: %TRUE if the action for the authorization is locked down.
*/
gboolean
-polkit_authorization_result_get_local_authority_lock_down (PolkitAuthorizationResult *result)
+polkit_authorization_result_get_locked_down (PolkitAuthorizationResult *result)
{
gboolean ret;
PolkitDetails *details;
ret = FALSE;
details = polkit_authorization_result_get_details (result);
- if (details != NULL && polkit_details_lookup (details, "polkit.localauthority.lockdown") != NULL)
+ if (details != NULL && polkit_details_lookup (details, "polkit.lockdown") != NULL)
ret = TRUE;
return ret;
diff --git a/src/polkit/polkitauthorizationresult.h b/src/polkit/polkitauthorizationresult.h
index ae00f83..5a66885 100644
--- a/src/polkit/polkitauthorizationresult.h
+++ b/src/polkit/polkitauthorizationresult.h
@@ -52,7 +52,7 @@ gboolean polkit_authorization_result_get_is_authorized (P
gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result);
const gchar *polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result);
-gboolean polkit_authorization_result_get_local_authority_lock_down (PolkitAuthorizationResult *result);
+gboolean polkit_authorization_result_get_locked_down (PolkitAuthorizationResult *result);
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
index c09067d..5fb0d15 100644
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -481,6 +481,15 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
user_data,
polkit_backend_interactive_authority_check_authorization);
+ /* handle being called from ourselves */
+ if (caller == NULL)
+ {
+ EggDBusConnection *system_bus;
+ system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+ caller = polkit_system_bus_name_new (egg_dbus_connection_get_unique_name (system_bus));
+ g_object_unref (system_bus);
+ }
+
caller_str = polkit_subject_to_string (caller);
subject_str = polkit_subject_to_string (subject);
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index 0f58a81..3672f4c 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -26,11 +26,13 @@
#include <string.h>
#include <glib/gstdio.h>
#include <locale.h>
+#include <glib/gi18n-lib.h>
#include <polkit/polkit.h>
#include "polkitbackendconfigsource.h"
#include "polkitbackendlocalauthority.h"
#include "polkitbackendlocalauthorizationstore.h"
+#include "polkitbackendactionlookup.h"
#include <polkit/polkitprivate.h>
@@ -40,8 +42,11 @@
* @short_description: Local Authority
* @stability: Unstable
*
- * An implementation of #PolkitBackendAuthority that stores authorizations on the local file system
- * and supports interaction with authentication agents.
+ * An implementation of #PolkitBackendAuthority that stores
+ * authorizations on the local file system, supports interaction with
+ * authentication agents (virtue of being based on
+ * #PolkitBackendInteractiveAuthority), and implements support for
+ * lock down.
*/
/* ---------------------------------------------------------------------------------------------------- */
@@ -51,6 +56,8 @@ static GList *get_users_in_group (PolkitIdentity *group,
static GList *get_groups_for_user (PolkitIdentity *user);
+static void register_extensions (void);
+
/* ---------------------------------------------------------------------------------------------------- */
typedef struct
@@ -82,6 +89,26 @@ static PolkitImplicitAuthorization polkit_backend_local_authority_check_authoriz
PolkitImplicitAuthorization implicit,
PolkitDetails *out_details);
+static void polkit_backend_local_authority_add_lockdown_for_action (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *action_id,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+static gboolean polkit_backend_local_authority_add_lockdown_for_action_finish (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ GError **error);
+
+static void polkit_backend_local_authority_remove_lockdown_for_action (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *action_id,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+static gboolean polkit_backend_local_authority_remove_lockdown_for_action_finish (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ GError **error);
+
G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority,
polkit_backend_local_authority,
@@ -194,10 +221,16 @@ polkit_backend_local_authority_class_init (PolkitBackendLocalAuthorityClass *kla
authority_class->get_name = polkit_backend_local_authority_get_name;
authority_class->get_version = polkit_backend_local_authority_get_version;
authority_class->get_features = polkit_backend_local_authority_get_features;
+ authority_class->add_lockdown_for_action = polkit_backend_local_authority_add_lockdown_for_action;
+ authority_class->add_lockdown_for_action_finish = polkit_backend_local_authority_add_lockdown_for_action_finish;
+ authority_class->remove_lockdown_for_action = polkit_backend_local_authority_remove_lockdown_for_action;
+ authority_class->remove_lockdown_for_action_finish = polkit_backend_local_authority_remove_lockdown_for_action_finish;
interactive_authority_class->get_admin_identities = polkit_backend_local_authority_get_admin_auth_identities;
interactive_authority_class->check_authorization_sync = polkit_backend_local_authority_check_authorization_sync;
g_type_class_add_private (klass, sizeof (PolkitBackendLocalAuthorityPrivate));
+
+ register_extensions ();
}
static GList *
@@ -470,3 +503,469 @@ get_groups_for_user (PolkitIdentity *user)
}
/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *
+lockdown_get_filename (const gchar *action_id)
+{
+ return g_strdup_printf (PACKAGE_LOCALSTATE_DIR
+ "/lib/polkit-1/localauthority/90-mandatory.d/"
+ "org.freedesktop.policykit.localauthority.lockdown.action-%s.pkla",
+ action_id);
+}
+
+static gboolean
+lockdown_exists (const gchar *action_id)
+{
+ gchar *filename;
+ gboolean ret;
+
+ ret = FALSE;
+
+ filename = lockdown_get_filename (action_id);
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS))
+ ret = TRUE;
+ g_free (filename);
+
+ return ret;
+}
+
+static gboolean
+lockdown_add (const gchar *action_id,
+ GError **error)
+{
+ gboolean ret;
+ gchar *filename;
+ gchar *contents;
+
+ ret = FALSE;
+
+ filename = lockdown_get_filename (action_id);
+ contents = g_strdup_printf ("# Added by pklalockdown(1)\n"
+ "#\n"
+ "[Lockdown]\n"
+ "Identity=unix-user:*\n"
+ "Action=%s\n"
+ "ResultAny=no\n"
+ "ResultInactive=no\n"
+ "ResultActive=auth_admin_keep\n"
+ "ReturnValue=polkit.lockdown=1",
+ action_id);
+ if (!g_file_set_contents (filename,
+ contents,
+ -1,
+ error))
+ goto out;
+
+ ret = TRUE;
+
+ out:
+ g_free (filename);
+ g_free (contents);
+ return ret;
+}
+
+static gboolean
+lockdown_remove (const gchar *action_id,
+ GError **error)
+{
+ gboolean ret;
+ gchar *filename;
+
+ ret = FALSE;
+
+ filename = lockdown_get_filename (action_id);
+ if (g_unlink (filename) != 0)
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Cannot unlink file %s: %s\n",
+ filename,
+ g_strerror (errno));
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ g_free (filename);
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+add_lockdown_check_auth_cb (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ PolkitAuthorizationResult *result;
+ GError *error;
+
+ result = polkit_backend_authority_check_authorization_finish (authority,
+ res,
+ &error);
+ if (result == NULL)
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+ else
+ {
+ if (polkit_authorization_result_get_is_authorized (result))
+ {
+ const gchar *action_id;
+
+ action_id = g_object_get_data (G_OBJECT (simple), "lock-down-action-id");
+
+ if (lockdown_exists (action_id))
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Action %s is already locked down",
+ action_id);
+ }
+ else
+ {
+ GError *error;
+
+ error = NULL;
+ if (!lockdown_add (action_id, &error))
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Error adding lock down for action %s: %s",
+ action_id,
+ error->message);
+ g_error_free (error);
+ }
+ }
+ }
+ else
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_AUTHORIZED,
+ "Not authorized to add lock down for the requested action");
+ }
+ g_object_unref (result);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static void
+polkit_backend_local_authority_add_lockdown_for_action (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *action_id,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ PolkitDetails *details;
+ GCancellable *cancellable;
+
+ simple = g_simple_async_result_new (G_OBJECT (authority),
+ callback,
+ user_data,
+ polkit_backend_local_authority_add_lockdown_for_action);
+
+ g_object_set_data_full (G_OBJECT (simple), "lock-down-action-id", g_strdup (action_id), g_free);
+
+ details = polkit_details_new ();
+ polkit_details_insert (details, "action-id", action_id);
+ polkit_details_insert (details, "add-lockdown", "1");
+
+ cancellable = g_cancellable_new ();
+
+ /* first check if caller is authorized for this */
+ polkit_backend_authority_check_authorization (POLKIT_BACKEND_AUTHORITY (authority),
+ NULL,
+ caller,
+ "org.freedesktop.policykit.lockdown",
+ details,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ cancellable,
+ (GAsyncReadyCallback) add_lockdown_check_auth_cb,
+ simple);
+
+ g_object_unref (details);
+ g_object_unref (cancellable);
+}
+
+static gboolean
+polkit_backend_local_authority_add_lockdown_for_action_finish (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_backend_local_authority_add_lockdown_for_action);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+remove_lockdown_check_auth_cb (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+ PolkitAuthorizationResult *result;
+ GError *error;
+
+ result = polkit_backend_authority_check_authorization_finish (authority,
+ res,
+ &error);
+ if (result == NULL)
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+ else
+ {
+ if (polkit_authorization_result_get_is_authorized (result))
+ {
+ const gchar *action_id;
+
+ action_id = g_object_get_data (G_OBJECT (simple), "lock-down-action-id");
+
+ if (!lockdown_exists (action_id))
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Action %s is not locked down",
+ action_id);
+ }
+ else
+ {
+ GError *error;
+
+ error = NULL;
+ if (!lockdown_remove (action_id, &error))
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Error removing lock down for action %s: %s",
+ action_id,
+ error->message);
+ g_error_free (error);
+ }
+ }
+ }
+ else
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_AUTHORIZED,
+ "Not authorized to remove lock down for the requested action");
+ }
+ g_object_unref (result);
+ }
+
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static void
+polkit_backend_local_authority_remove_lockdown_for_action (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *action_id,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ PolkitDetails *details;
+ GCancellable *cancellable;
+
+ simple = g_simple_async_result_new (G_OBJECT (authority),
+ callback,
+ user_data,
+ polkit_backend_local_authority_remove_lockdown_for_action);
+
+ g_object_set_data_full (G_OBJECT (simple), "lock-down-action-id", g_strdup (action_id), g_free);
+
+ details = polkit_details_new ();
+ polkit_details_insert (details, "action-id", action_id);
+ polkit_details_insert (details, "remove-lockdown", "1");
+
+ cancellable = g_cancellable_new ();
+
+ /* first check if caller is authorized for this */
+ polkit_backend_authority_check_authorization (POLKIT_BACKEND_AUTHORITY (authority),
+ NULL,
+ caller,
+ "org.freedesktop.policykit.lockdown",
+ details,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ cancellable,
+ (GAsyncReadyCallback) remove_lockdown_check_auth_cb,
+ simple);
+
+ g_object_unref (details);
+ g_object_unref (cancellable);
+}
+
+static gboolean
+polkit_backend_local_authority_remove_lockdown_for_action_finish (PolkitBackendAuthority *authority,
+ GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_backend_local_authority_remove_lockdown_for_action);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+#define PBLA_TYPE_ACTION_LOOKUP (pbla_action_lookup_get_type())
+#define PBLA_ACTION_LOOKUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), PBLA_TYPE_ACTION_LOOKUP, PblaActionLookup))
+#define PBLA_ACTION_LOOKUP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), PBLA_TYPE_ACTION_LOOKUP, PblaActionLookupClass))
+#define PBLA_ACTION_LOOKUP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), PBLA_TYPE_ACTION_LOOKUP, PblaActionLookupClass))
+#define PBLA_IS_ACTION_LOOKUP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), PBLA_TYPE_ACTION_LOOKUP))
+#define PBLA_IS_ACTION_LOOKUP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), PBLA_TYPE_ACTION_LOOKUP))
+
+typedef struct _PblaActionLookup PblaActionLookup;
+typedef struct _PblaActionLookupClass PblaActionLookupClass;
+
+struct _PblaActionLookup
+{
+ GObject parent;
+};
+
+struct _PblaActionLookupClass
+{
+ GObjectClass parent_class;
+};
+
+GType pbla_action_lookup_get_type (void) G_GNUC_CONST;
+
+static void pbla_action_lookup_iface_init (PolkitBackendActionLookupIface *iface);
+
+
+G_DEFINE_TYPE_EXTENDED (PblaActionLookup,
+ pbla_action_lookup,
+ G_TYPE_OBJECT,
+ 0,
+ G_IMPLEMENT_INTERFACE (POLKIT_BACKEND_TYPE_ACTION_LOOKUP,
+ pbla_action_lookup_iface_init))
+
+static void
+pbla_action_lookup_init (PblaActionLookup *lookup)
+{
+}
+
+static void
+pbla_action_lookup_class_init (PblaActionLookupClass *klass)
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gchar *
+pbla_action_lookup_get_message (PolkitBackendActionLookup *lookup,
+ const gchar *action_id,
+ PolkitDetails *details,
+ PolkitActionDescription *action_description)
+{
+ gchar *ret;
+ const gchar *s;
+
+ ret = NULL;
+
+ if (g_strcmp0 (action_id, "org.freedesktop.policykit.lockdown") != 0)
+ goto out;
+
+ s = polkit_details_lookup (details, "remove-lockdown");
+ if (s == NULL)
+ {
+ ret = g_strdup (_("Authentication is needed to lock down an action"));
+ }
+ else
+ {
+ ret = g_strdup (_("Authentication is needed to remove lock down for an action"));
+ }
+
+ out:
+ return ret;
+}
+
+static gchar *
+pbla_action_lookup_get_icon_name (PolkitBackendActionLookup *lookup,
+ const gchar *action_id,
+ PolkitDetails *details,
+ PolkitActionDescription *action_description)
+{
+ gchar *ret;
+
+ ret = NULL;
+
+ /* explicitly left blank for now */
+
+ return ret;
+}
+
+static PolkitDetails *
+pbla_action_lookup_get_details (PolkitBackendActionLookup *lookup,
+ const gchar *action_id,
+ PolkitDetails *details,
+ PolkitActionDescription *action_desc)
+{
+ PolkitDetails *ret;
+ const gchar *s;
+ const gchar *s2;
+
+ ret = NULL;
+
+ if (g_strcmp0 (action_id, "org.freedesktop.policykit.lockdown") != 0)
+ goto out;
+
+ s = polkit_details_lookup (details, "action-id");
+ if (s == NULL)
+ goto out;
+
+ s2 = polkit_details_lookup (details, "remove-lockdown");
+
+ ret = polkit_details_new ();
+ if (s2 == NULL)
+ polkit_details_insert (ret, _("Action to lock down"), s);
+ else
+ polkit_details_insert (ret, _("Locked down action"), s);
+
+ out:
+ return ret;
+}
+
+static void
+pbla_action_lookup_iface_init (PolkitBackendActionLookupIface *iface)
+{
+ iface->get_message = pbla_action_lookup_get_message;
+ iface->get_icon_name = pbla_action_lookup_get_icon_name;
+ iface->get_details = pbla_action_lookup_get_details;
+}
+
+
+static void
+register_extensions (void)
+{
+ g_io_extension_point_implement (POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME,
+ PBLA_TYPE_ACTION_LOOKUP,
+ "lockdown action lookup extension " PACKAGE_VERSION,
+ 0);
+}
diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am
index 1898cdd..6f78c49 100644
--- a/src/programs/Makefile.am
+++ b/src/programs/Makefile.am
@@ -17,7 +17,7 @@ INCLUDES = \
# ----------------------------------------------------------------------------------------------------
-bin_PROGRAMS = pkexec pkcheck pkaction pklalockdown
+bin_PROGRAMS = pkexec pkcheck pkaction
# ----------------------------------------------------------------------------------------------------
@@ -82,19 +82,6 @@ pkaction_LDADD = \
# ----------------------------------------------------------------------------------------------------
-pklalockdown_SOURCES = pklalockdown.c
-
-pklalockdown_CFLAGS = \
- $(GLIB_CFLAGS) \
- $(NULL)
-
-pklalockdown_LDADD = \
- $(GLIB_LIBS) \
- $(top_builddir)/src/polkit/libpolkit-gobject-1.la \
- $(NULL)
-
-# ----------------------------------------------------------------------------------------------------
-
clean-local :
rm -f *~
diff --git a/src/programs/pklalockdown.c b/src/programs/pklalockdown.c
deleted file mode 100644
index 88ce660..0000000
--- a/src/programs/pklalockdown.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2008 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: David Zeuthen <davidz@redhat.com>
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <errno.h>
-#include <glib/gstdio.h>
-
-#include <polkit/polkit.h>
-
-static gchar *get_lockdown_filename (const gchar *action_id);
-static gboolean lockdown_exists (const gchar *action_id);
-
-
-static void
-usage (int argc, char *argv[])
-{
- GError *error;
-
- error = NULL;
- if (!g_spawn_command_line_sync ("man pklalockdown",
- NULL,
- NULL,
- NULL,
- &error))
- {
- g_printerr ("Cannot show manual page: %s\n", error->message);
- g_error_free (error);
- }
-}
-
-int
-main (int argc, char *argv[])
-{
- guint n;
- guint ret;
- gboolean opt_show_help;
- gboolean opt_show_version;
- gchar *opt_lockdown;
- gchar *opt_remove_lockdown;
-
- ret = 1;
-
- opt_show_help = FALSE;
- opt_show_version = FALSE;
- opt_lockdown = NULL;
- opt_remove_lockdown = NULL;
-
- /* if we are not yet uid 0, make us uid 0 through pkexec */
- if (getuid () != 0)
- {
- gchar **exec_argv;
-
- exec_argv = g_new0 (gchar *, argc + 2);
- exec_argv[0] = PACKAGE_BIN_DIR "/pkexec";
- memcpy (exec_argv + 1, argv, argc * sizeof (gchar *));
-
- if (execv (PACKAGE_BIN_DIR "/pkexec", exec_argv) != 0)
- {
- g_printerr ("Error executing " PACKAGE_BIN_DIR "/pkexec: %s\n", g_strerror (errno));
- goto out;
- }
-
- g_assert_not_reached ();
- }
-
- /* We are now uid 0 (by default, the user had to authenticate to get
- * here) - be careful to check all incoming args
- */
- for (n = 1; n < (guint) argc; n++)
- {
- if (strcmp (argv[n], "--help") == 0)
- {
- opt_show_help = TRUE;
- }
- else if (strcmp (argv[n], "--version") == 0)
- {
- opt_show_version = TRUE;
- }
- else if (strcmp (argv[n], "--lockdown") == 0 || strcmp (argv[n], "-l") == 0)
- {
- n++;
- if (n >= (guint) argc)
- {
- usage (argc, argv);
- goto out;
- }
-
- opt_lockdown = g_strdup (argv[n]);
- }
- else if (strcmp (argv[n], "--remove-lockdown") == 0 || strcmp (argv[n], "-r") == 0)
- {
- n++;
- if (n >= (guint) argc)
- {
- usage (argc, argv);
- goto out;
- }
-
- opt_remove_lockdown = g_strdup (argv[n]);
- }
- else
- {
- break;
- }
- }
-
- if (opt_show_help)
- {
- usage (argc, argv);
- ret = 0;
- goto out;
- }
- else if (opt_show_version)
- {
- g_print ("pkexec version %s\n", PACKAGE_VERSION);
- ret = 0;
- goto out;
- }
- else if (opt_lockdown != NULL)
- {
- gchar *filename;
- gchar *contents;
- GError *error;
-
- if (lockdown_exists (opt_lockdown))
- {
- g_printerr ("Error: action %s is already locked down\n", opt_lockdown);
- goto out;
- }
-
- filename = get_lockdown_filename (opt_lockdown);
- contents = g_strdup_printf ("# Added by pklalockdown(1)\n"
- "#\n"
- "[Lockdown]\n"
- "Identity=unix-user:*\n"
- "Action=%s\n"
- "ResultAny=no\n"
- "ResultInactive=no\n"
- "ResultActive=auth_admin_keep\n"
- "ReturnValue=polkit.localauthority.lockdown=1",
- opt_lockdown);
- error = NULL;
- if (!g_file_set_contents (filename,
- contents,
- -1,
- &error))
- {
- g_printerr ("Error: Cannot write to file %s: %s\n", filename, error->message);
- g_error_free (error);
- g_free (filename);
- g_free (contents);
- goto out;
- }
- g_free (filename);
- g_free (contents);
- ret = 0;
- goto out;
- }
- else if (opt_remove_lockdown != NULL)
- {
- gchar *filename;
-
- if (!lockdown_exists (opt_remove_lockdown))
- {
- g_printerr ("Error: action %s is not locked down\n", opt_remove_lockdown);
- goto out;
- }
-
- filename = get_lockdown_filename (opt_remove_lockdown);
- if (g_unlink (filename) != 0)
- {
- g_printerr ("Error: Cannot unlink file %s: %s\n", filename, g_strerror (errno));
- g_free (filename);
- goto out;
- }
- g_free (filename);
-
- ret = 0;
- goto out;
- }
-
- usage (argc, argv);
-
- out:
- g_free (opt_lockdown);
- g_free (opt_remove_lockdown);
- return ret;
-}
-
-static gchar *
-get_lockdown_filename (const gchar *action_id)
-{
- return g_strdup_printf (PACKAGE_LOCALSTATE_DIR
- "/lib/polkit-1/localauthority/90-mandatory.d/"
- "org.freedesktop.policykit.localauthority.lockdown.action-%s.pkla",
- action_id);
-}
-
-static gboolean
-lockdown_exists (const gchar *action_id)
-{
- gchar *filename;
- gboolean ret;
-
- ret = FALSE;
-
- filename = get_lockdown_filename (action_id);
- if (g_file_test (filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS))
- ret = TRUE;
- g_free (filename);
-
- return ret;
-}
-