PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Wed Nov 11 14:11:03 PST 2009


 actions/org.freedesktop.policykit.policy.in           |    4 
 docs/man/Makefile.am                                  |    2 
 docs/man/pklalockdown.xml                             |  136 ----
 docs/polkit/polkit-1-sections.txt                     |    2 
 src/polkit/polkitauthority.c                          |    6 
 src/polkit/polkitauthorizationresult.c                |   13 
 src/polkit/polkitauthorizationresult.h                |    2 
 src/polkitbackend/polkitbackendinteractiveauthority.c |    9 
 src/polkitbackend/polkitbackendlocalauthority.c       |  503 +++++++++++++++++-
 src/programs/Makefile.am                              |   15 
 src/programs/pklalockdown.c                           |  243 --------
 11 files changed, 525 insertions(+), 410 deletions(-)

New commits:
commit 8f7727e1df53e9eaa2a36fd6ee8eaf41b209a3f0
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Nov 11 17:08:36 2009 -0500

    Port lockdown from pklalockdown(1) to D-Bus methods
    
    Also rename the action from org.freedesktop.policykit.localauthority.lockdown
    to org.freedesktop.policykit.lockdown since any authority implementation
    can now implement this.
    
    This changes only ABI/API used by e.g. polkit-gnome. This is fine
    since we're not at 1.0 yet.

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 at 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 at 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;
-}
-


More information about the hal-commit mailing list