PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Wed Jul 15 09:52:24 PDT 2009


 docs/polkit/polkit-1-docs.xml                         |    1 
 docs/polkit/polkit-1-sections.txt                     |   18 
 docs/polkit/polkit-1.types                            |    3 
 src/polkitbackend/Makefile.am                         |    2 
 src/polkitbackend/polkitbackend.h                     |    1 
 src/polkitbackend/polkitbackendinteractiveauthority.c | 1882 ++++++++++++++++++
 src/polkitbackend/polkitbackendinteractiveauthority.h |  138 +
 src/polkitbackend/polkitbackendlocalauthority.c       | 1721 ----------------
 src/polkitbackend/polkitbackendlocalauthority.h       |   31 
 src/polkitbackend/polkitbackendtypes.h                |    9 
 10 files changed, 2102 insertions(+), 1704 deletions(-)

New commits:
commit 84a83a871e1aefd3d6138f1094af76d3c17e94dd
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Jul 15 12:48:32 2009 -0400

    Move authentication agent bits to separate authority subclass

diff --git a/docs/polkit/polkit-1-docs.xml b/docs/polkit/polkit-1-docs.xml
index a4705f4..4744e58 100644
--- a/docs/polkit/polkit-1-docs.xml
+++ b/docs/polkit/polkit-1-docs.xml
@@ -90,6 +90,7 @@
   <part id="ref-backend-api">
     <title>Backend API Reference</title>
     <xi:include href="xml/polkitbackendauthority.xml"/>
+    <xi:include href="xml/polkitbackendinteractiveauthority.xml"/>
     <xi:include href="xml/polkitbackendlocalauthority.xml"/>
     <xi:include href="xml/polkitbackendactionpool.xml"/>
     <xi:include href="xml/polkitbackendsessionmonitor.xml"/>
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
index 498b0b8..a5a03c8 100644
--- a/docs/polkit/polkit-1-sections.txt
+++ b/docs/polkit/polkit-1-sections.txt
@@ -291,7 +291,6 @@ POLKIT_BACKEND_ACTION_LOOKUP_GET_IFACE
 <TITLE>PolkitBackendLocalAuthority</TITLE>
 PolkitBackendLocalAuthority
 PolkitBackendLocalAuthorityClass
-polkit_backend_local_authority_new
 <SUBSECTION Standard>
 POLKIT_BACKEND_LOCAL_AUTHORITY
 POLKIT_BACKEND_IS_LOCAL_AUTHORITY
@@ -303,6 +302,23 @@ POLKIT_BACKEND_LOCAL_AUTHORITY_GET_CLASS
 </SECTION>
 
 <SECTION>
+<FILE>polkitbackendinteractiveauthority</FILE>
+<TITLE>PolkitBackendInteractiveAuthority</TITLE>
+PolkitBackendInteractiveAuthority
+PolkitBackendInteractiveAuthorityClass
+polkit_backend_interactive_authority_get_admin_identities
+polkit_backend_interactive_authority_check_authorization_sync
+<SUBSECTION Standard>
+POLKIT_BACKEND_INTERACTIVE_AUTHORITY
+POLKIT_BACKEND_IS_INTERACTIVE_AUTHORITY
+POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY
+polkit_backend_interactive_authority_get_type
+POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS
+POLKIT_BACKEND_IS_INTERACTIVE_AUTHORITY_CLASS
+POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_CLASS
+</SECTION>
+
+<SECTION>
 <FILE>polkitbackendactionpool</FILE>
 <TITLE>PolkitBackendActionPool</TITLE>
 PolkitBackendActionPool
diff --git a/docs/polkit/polkit-1.types b/docs/polkit/polkit-1.types
index 0105bad..fd9fe53 100644
--- a/docs/polkit/polkit-1.types
+++ b/docs/polkit/polkit-1.types
@@ -14,8 +14,9 @@ polkit_error_get_type
 polkit_authorization_result_get_type
 
 polkit_backend_authority_get_type
-polkit_backend_action_lookup_get_type
+polkit_backend_interactive_authority_get_type
 polkit_backend_local_authority_get_type
+polkit_backend_action_lookup_get_type
 polkit_backend_action_pool_get_type
 polkit_backend_session_monitor_get_type
 polkit_backend_config_source_get_type
diff --git a/src/polkitbackend/Makefile.am b/src/polkitbackend/Makefile.am
index cf7a88c..a41201f 100644
--- a/src/polkitbackend/Makefile.am
+++ b/src/polkitbackend/Makefile.am
@@ -41,6 +41,7 @@ libpolkit_backend_1include_HEADERS =                        		\
 	polkitbackend.h							\
 	polkitbackendtypes.h						\
 	polkitbackendauthority.h					\
+	polkitbackendinteractiveauthority.h				\
 	polkitbackendlocalauthority.h					\
 	polkitbackendactionpool.h					\
 	polkitbackendsessionmonitor.h					\
@@ -55,6 +56,7 @@ libpolkit_backend_1_la_SOURCES =                                   			\
 	polkitbackendtypes.h								\
 	polkitbackendprivate.h								\
 	polkitbackendauthority.h		polkitbackendauthority.c		\
+	polkitbackendinteractiveauthority.h	polkitbackendinteractiveauthority.c	\
 	polkitbackendlocalauthority.h		polkitbackendlocalauthority.c		\
 	polkitbackendactionpool.h		polkitbackendactionpool.c		\
 	polkitbackendsessionmonitor.h		polkitbackendsessionmonitor.c		\
diff --git a/src/polkitbackend/polkitbackend.h b/src/polkitbackend/polkitbackend.h
index 3efa131..c734945 100644
--- a/src/polkitbackend/polkitbackend.h
+++ b/src/polkitbackend/polkitbackend.h
@@ -31,6 +31,7 @@
 #define _POLKIT_BACKEND_INSIDE_POLKIT_BACKEND_H 1
 #include <polkitbackend/polkitbackendtypes.h>
 #include <polkitbackend/polkitbackendauthority.h>
+#include <polkitbackend/polkitbackendinteractiveauthority.h>
 #include <polkitbackend/polkitbackendlocalauthority.h>
 #include <polkitbackend/polkitbackendactionpool.h>
 #include <polkitbackend/polkitbackendsessionmonitor.h>
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
new file mode 100644
index 0000000..8018b00
--- /dev/null
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -0,0 +1,1882 @@
+/*
+ * 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>
+ */
+
+#include "config.h"
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
+#include <glib/gstdio.h>
+#include <locale.h>
+
+#include <polkit/polkit.h>
+#include "polkitbackendinteractiveauthority.h"
+#include "polkitbackendactionpool.h"
+#include "polkitbackendsessionmonitor.h"
+#include "polkitbackendconfigsource.h"
+#include "polkitbackendactionlookup.h"
+
+#include <polkit/polkitprivate.h>
+
+/**
+ * SECTION:polkitbackendinteractiveauthority
+ * @title: PolkitBackendInteractiveAuthority
+ * @short_description: Interactive Authority
+ * @stability: Unstable
+ *
+ * An subclass of #PolkitBackendAuthority that supports interaction
+ * with authentication agents.
+ */
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct TemporaryAuthorizationStore TemporaryAuthorizationStore;
+
+static TemporaryAuthorizationStore *temporary_authorization_store_new (void);
+static void                         temporary_authorization_store_free (TemporaryAuthorizationStore *store);
+
+static gboolean temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
+                                                                 PolkitSubject               *subject,
+                                                                 const gchar                 *action_id);
+
+static void     temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
+                                                                 PolkitSubject               *subject,
+                                                                 const gchar                 *action_id);
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+struct AuthenticationAgent;
+typedef struct AuthenticationAgent AuthenticationAgent;
+
+struct AuthenticationSession;
+typedef struct AuthenticationSession AuthenticationSession;
+
+typedef void (*AuthenticationAgentCallback) (AuthenticationAgent         *agent,
+                                             PolkitSubject               *subject,
+                                             PolkitIdentity              *user_of_subject,
+                                             PolkitBackendInteractiveAuthority *authority,
+                                             const gchar                 *action_id,
+                                             PolkitImplicitAuthorization  implicit_authorization,
+                                             gboolean                     authentication_success,
+                                             gpointer                     user_data);
+
+static void                authentication_agent_free (AuthenticationAgent *agent);
+
+static void                authentication_agent_initiate_challenge (AuthenticationAgent         *agent,
+                                                                    PolkitSubject               *subject,
+                                                                    PolkitIdentity              *user_of_subject,
+                                                                    PolkitBackendInteractiveAuthority *authority,
+                                                                    const gchar                 *action_id,
+                                                                    PolkitDetails               *details,
+                                                                    PolkitSubject               *caller,
+                                                                    PolkitImplicitAuthorization  implicit_authorization,
+                                                                    GCancellable                *cancellable,
+                                                                    AuthenticationAgentCallback  callback,
+                                                                    gpointer                     user_data);
+
+static AuthenticationAgent *get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authority,
+                                                                  PolkitSubject *subject);
+
+static AuthenticationSession *get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *authority,
+                                                                     const gchar *cookie);
+
+static GList *get_authentication_sessions_initiated_by_system_bus_unique_name (PolkitBackendInteractiveAuthority *authority,
+                                                                               const gchar *system_bus_unique_name);
+
+static void authentication_session_cancel (AuthenticationSession *session);
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void polkit_backend_interactive_authority_system_bus_name_owner_changed (PolkitBackendAuthority   *authority,
+                                                                          const gchar              *name,
+                                                                          const gchar              *old_owner,
+                                                                          const gchar              *new_owner);
+
+static GList *polkit_backend_interactive_authority_enumerate_actions  (PolkitBackendAuthority   *authority,
+                                                                 PolkitSubject            *caller,
+                                                                 const gchar              *locale,
+                                                                 GError                  **error);
+
+static void polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority        *authority,
+                                                                PolkitSubject                 *caller,
+                                                                PolkitSubject                 *subject,
+                                                                const gchar                   *action_id,
+                                                                PolkitDetails                 *details,
+                                                                PolkitCheckAuthorizationFlags  flags,
+                                                                GCancellable                  *cancellable,
+                                                                GAsyncReadyCallback            callback,
+                                                                gpointer                       user_data);
+
+static PolkitAuthorizationResult *polkit_backend_interactive_authority_check_authorization_finish (
+                                                                 PolkitBackendAuthority  *authority,
+                                                                 GAsyncResult            *res,
+                                                                 GError                 **error);
+
+static PolkitAuthorizationResult *check_authorization_sync (PolkitBackendAuthority         *authority,
+                                                            PolkitSubject                  *caller,
+                                                            PolkitSubject                  *subject,
+                                                            const gchar                    *action_id,
+                                                            PolkitDetails                  *details,
+                                                            PolkitCheckAuthorizationFlags   flags,
+                                                            PolkitImplicitAuthorization    *out_implicit_authorization,
+                                                            GError                        **error);
+
+static gboolean polkit_backend_interactive_authority_register_authentication_agent (PolkitBackendAuthority   *authority,
+                                                                              PolkitSubject            *caller,
+                                                                              const gchar              *session_id,
+                                                                              const gchar              *locale,
+                                                                              const gchar              *object_path,
+                                                                              GError                  **error);
+
+static gboolean polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBackendAuthority   *authority,
+                                                                                PolkitSubject            *caller,
+                                                                                const gchar              *session_id,
+                                                                                const gchar              *object_path,
+                                                                                GError                  **error);
+
+static gboolean polkit_backend_interactive_authority_authentication_agent_response (PolkitBackendAuthority   *authority,
+                                                                              PolkitSubject            *caller,
+                                                                              const gchar              *cookie,
+                                                                              PolkitIdentity           *identity,
+                                                                              GError                  **error);
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+  PolkitBackendActionPool *action_pool;
+
+  PolkitBackendSessionMonitor *session_monitor;
+
+  TemporaryAuthorizationStore *temporary_authorization_store;
+
+  GHashTable *hash_session_to_authentication_agent;
+
+} PolkitBackendInteractiveAuthorityPrivate;
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+G_DEFINE_TYPE (PolkitBackendInteractiveAuthority,
+               polkit_backend_interactive_authority,
+               POLKIT_BACKEND_TYPE_AUTHORITY);
+
+#define POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY, PolkitBackendInteractiveAuthorityPrivate))
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+action_pool_changed (PolkitBackendActionPool *action_pool,
+                     PolkitBackendInteractiveAuthority *authority)
+{
+  g_signal_emit_by_name (authority, "changed");
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *authority)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GFile *directory;
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  directory = g_file_new_for_path (PACKAGE_DATA_DIR "/polkit-1/actions");
+  priv->action_pool = polkit_backend_action_pool_new (directory);
+  g_object_unref (directory);
+  g_signal_connect (priv->action_pool,
+                    "changed",
+                    (GCallback) action_pool_changed,
+                    authority);
+
+  priv->temporary_authorization_store = temporary_authorization_store_new ();
+
+  priv->hash_session_to_authentication_agent = g_hash_table_new_full ((GHashFunc) polkit_subject_hash,
+                                                                      (GEqualFunc) polkit_subject_equal,
+                                                                      (GDestroyNotify) g_object_unref,
+                                                                      (GDestroyNotify) authentication_agent_free);
+
+  priv->session_monitor = polkit_backend_session_monitor_new ();
+}
+
+static void
+polkit_backend_interactive_authority_finalize (GObject *object)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (object);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  if (priv->action_pool != NULL)
+    g_object_unref (priv->action_pool);
+
+  if (priv->session_monitor != NULL)
+    g_object_unref (priv->session_monitor);
+
+  temporary_authorization_store_free (priv->temporary_authorization_store);
+
+  g_hash_table_unref (priv->hash_session_to_authentication_agent);
+
+  G_OBJECT_CLASS (polkit_backend_interactive_authority_parent_class)->finalize (object);
+}
+
+static void
+polkit_backend_interactive_authority_class_init (PolkitBackendInteractiveAuthorityClass *klass)
+{
+  GObjectClass *gobject_class;
+  PolkitBackendAuthorityClass *authority_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
+
+  gobject_class->finalize = polkit_backend_interactive_authority_finalize;
+
+  authority_class->system_bus_name_owner_changed   = polkit_backend_interactive_authority_system_bus_name_owner_changed;
+  authority_class->enumerate_actions               = polkit_backend_interactive_authority_enumerate_actions;
+  authority_class->check_authorization             = polkit_backend_interactive_authority_check_authorization;
+  authority_class->check_authorization_finish      = polkit_backend_interactive_authority_check_authorization_finish;
+  authority_class->register_authentication_agent   = polkit_backend_interactive_authority_register_authentication_agent;
+  authority_class->unregister_authentication_agent = polkit_backend_interactive_authority_unregister_authentication_agent;
+  authority_class->authentication_agent_response   = polkit_backend_interactive_authority_authentication_agent_response;
+
+
+  g_type_class_add_private (klass, sizeof (PolkitBackendInteractiveAuthorityPrivate));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GList *
+polkit_backend_interactive_authority_enumerate_actions (PolkitBackendAuthority   *authority,
+                                                  PolkitSubject            *caller,
+                                                  const gchar              *interactivee,
+                                                  GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GList *actions;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  actions = polkit_backend_action_pool_get_all_actions (priv->action_pool, interactivee);
+
+  return actions;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+check_authorization_challenge_cb (AuthenticationAgent         *agent,
+                                  PolkitSubject               *subject,
+                                  PolkitIdentity              *user_of_subject,
+                                  PolkitBackendInteractiveAuthority *authority,
+                                  const gchar                 *action_id,
+                                  PolkitImplicitAuthorization  implicit_authorization,
+                                  gboolean                     authentication_success,
+                                  gpointer                     user_data)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitAuthorizationResult *result;
+  gchar *subject_str;
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  result = NULL;
+  subject_str = polkit_subject_to_string (subject);
+
+  g_debug ("In check_authorization_challenge_cb\n"
+           "  subject                %s\n"
+           "  action_id              %s\n"
+           "  authentication_success %d\n",
+           subject_str,
+           action_id,
+           authentication_success);
+
+  if (authentication_success)
+    {
+      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+
+      /* store temporary authorization depending on value of implicit_authorization */
+      if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED ||
+          implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
+        {
+          temporary_authorization_store_add_authorization (priv->temporary_authorization_store,
+                                                           subject,
+                                                           action_id);
+        }
+    }
+  else
+    {
+      /* TODO: maybe return set is_challenge? */
+      result = polkit_authorization_result_new (FALSE, FALSE, NULL);
+    }
+
+  g_simple_async_result_set_op_res_gpointer (simple,
+                                             result,
+                                             g_object_unref);
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+
+  g_free (subject_str);
+}
+
+static PolkitAuthorizationResult *
+polkit_backend_interactive_authority_check_authorization_finish (PolkitBackendAuthority  *authority,
+                                                           GAsyncResult            *res,
+                                                           GError                 **error)
+{
+  GSimpleAsyncResult *simple;
+  PolkitAuthorizationResult *result;
+
+  simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_backend_interactive_authority_check_authorization);
+
+  result = NULL;
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    goto out;
+
+  result = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+
+ out:
+  return result;
+}
+
+static void
+polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority         *authority,
+                                                    PolkitSubject                  *caller,
+                                                    PolkitSubject                  *subject,
+                                                    const gchar                    *action_id,
+                                                    PolkitDetails                  *details,
+                                                    PolkitCheckAuthorizationFlags   flags,
+                                                    GCancellable                   *cancellable,
+                                                    GAsyncReadyCallback             callback,
+                                                    gpointer                        user_data)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  gchar *caller_str;
+  gchar *subject_str;
+  PolkitIdentity *user_of_caller;
+  PolkitIdentity *user_of_subject;
+  gchar *user_of_caller_str;
+  gchar *user_of_subject_str;
+  PolkitAuthorizationResult *result;
+  PolkitImplicitAuthorization implicit_authorization;
+  GError *error;
+  GSimpleAsyncResult *simple;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  error = NULL;
+  caller_str = NULL;
+  subject_str = NULL;
+  user_of_caller = NULL;
+  user_of_subject = NULL;
+  user_of_caller_str = NULL;
+  user_of_subject_str = NULL;
+  result = NULL;
+
+  simple = g_simple_async_result_new (G_OBJECT (authority),
+                                      callback,
+                                      user_data,
+                                      polkit_backend_interactive_authority_check_authorization);
+
+  caller_str = polkit_subject_to_string (caller);
+  subject_str = polkit_subject_to_string (subject);
+
+  g_debug ("%s is inquiring whether %s is authorized for %s",
+           caller_str,
+           subject_str,
+           action_id);
+
+  user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+                                                                        caller,
+                                                                        &error);
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+      g_error_free (error);
+      goto out;
+    }
+
+  user_of_caller_str = polkit_identity_to_string (user_of_caller);
+  g_debug (" user of caller is %s", user_of_caller_str);
+
+  /* we only allow trusted callers (uid 0 + others) to check authorizations */
+  if (!POLKIT_IS_UNIX_USER (user_of_caller) ||
+      polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0) /* TODO: allow other uids like 'haldaemon'? */
+    {
+      g_simple_async_result_set_error (simple,
+                                       POLKIT_ERROR,
+                                       POLKIT_ERROR_NOT_AUTHORIZED,
+                                       "Only trusted callers can use CheckAuthorization(), %s is not trusted",
+                                       user_of_caller_str);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+      goto out;
+    }
+
+  user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+                                                                         subject,
+                                                                         &error);
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+      g_error_free (error);
+      goto out;
+    }
+
+  user_of_subject_str = polkit_identity_to_string (user_of_subject);
+  g_debug (" user of subject is %s", user_of_subject_str);
+
+  implicit_authorization = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED;
+  result = check_authorization_sync (authority,
+                                     caller,
+                                     subject,
+                                     action_id,
+                                     details,
+                                     flags,
+                                     &implicit_authorization,
+                                     &error);
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+      g_error_free (error);
+      goto out;
+    }
+
+  /* Caller is up for a challenge! With light sabers! Use an authentication agent if one exists... */
+  if (polkit_authorization_result_get_is_challenge (result) &&
+      (flags & POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION))
+    {
+      AuthenticationAgent *agent;
+
+      agent = get_authentication_agent_for_subject (interactive_authority, subject);
+      if (agent != NULL)
+        {
+          g_object_unref (result);
+          result = NULL;
+
+          g_debug (" using authentication agent for challenge");
+
+          authentication_agent_initiate_challenge (agent,
+                                                   subject,
+                                                   user_of_subject,
+                                                   interactive_authority,
+                                                   action_id,
+                                                   details,
+                                                   caller,
+                                                   implicit_authorization,
+                                                   cancellable,
+                                                   check_authorization_challenge_cb,
+                                                   simple);
+
+          /* keep going */
+          goto out;
+        }
+    }
+
+  /* Otherwise just return the result */
+  g_simple_async_result_set_op_res_gpointer (simple,
+                                             result,
+                                             g_object_unref);
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+
+ out:
+
+  if (user_of_caller != NULL)
+    g_object_unref (user_of_caller);
+
+  if (user_of_subject != NULL)
+    g_object_unref (user_of_subject);
+
+  g_free (caller_str);
+  g_free (subject_str);
+  g_free (user_of_caller_str);
+  g_free (user_of_subject_str);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static PolkitAuthorizationResult *
+check_authorization_sync (PolkitBackendAuthority         *authority,
+                          PolkitSubject                  *caller,
+                          PolkitSubject                  *subject,
+                          const gchar                    *action_id,
+                          PolkitDetails                  *details,
+                          PolkitCheckAuthorizationFlags   flags,
+                          PolkitImplicitAuthorization    *out_implicit_authorization,
+                          GError                        **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitAuthorizationResult *result;
+  PolkitIdentity *user_of_subject;
+  PolkitSubject *session_for_subject;
+  gchar *subject_str;
+  GList *groups_of_user;
+  PolkitActionDescription *action_desc;
+  gboolean session_is_local;
+  gboolean session_is_active;
+  PolkitImplicitAuthorization implicit_authorization;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  result = NULL;
+
+  user_of_subject = NULL;
+  groups_of_user = NULL;
+  subject_str = NULL;
+  session_for_subject = NULL;
+
+  session_is_local = FALSE;
+  session_is_active = FALSE;
+
+  subject_str = polkit_subject_to_string (subject);
+
+  g_debug ("checking whether %s is authorized for %s",
+           subject_str,
+           action_id);
+
+  /* get the action description */
+  action_desc = polkit_backend_action_pool_get_action (priv->action_pool,
+                                                       action_id,
+                                                       NULL);
+
+  if (action_desc == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Action %s is not registered",
+                   action_id);
+      goto out;
+    }
+
+  /* every subject has a user */
+  user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+                                                                         subject,
+                                                                         error);
+  if (user_of_subject == NULL)
+      goto out;
+
+  /* special case: uid 0, root, is _always_ authorized for anything */
+  if (POLKIT_IS_UNIX_USER (user_of_subject) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_subject)) == 0)
+    {
+      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+      goto out;
+    }
+
+  /* a subject *may* be in a session */
+  session_for_subject = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
+                                                                                subject,
+                                                                                NULL);
+  g_debug ("  %p", session_for_subject);
+  if (session_for_subject != NULL)
+    {
+      session_is_local = polkit_backend_session_monitor_is_session_local (priv->session_monitor, session_for_subject);
+      session_is_active = polkit_backend_session_monitor_is_session_active (priv->session_monitor, session_for_subject);
+
+      g_debug (" subject is in session %s (local=%d active=%d)",
+               polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session_for_subject)),
+               session_is_local,
+               session_is_active);
+    }
+
+  /* find the implicit authorization to use; it depends on is_local and is_active */
+  if (session_is_local)
+    {
+      if (session_is_active)
+        implicit_authorization = polkit_action_description_get_implicit_active (action_desc);
+      else
+        implicit_authorization = polkit_action_description_get_implicit_inactive (action_desc);
+    }
+  else
+    {
+      implicit_authorization = polkit_action_description_get_implicit_any (action_desc);
+    }
+
+  /* allow subclasses to rewrite implicit_authorization */
+  implicit_authorization = polkit_backend_interactive_authority_check_authorization_sync (interactive_authority,
+                                                                                          caller,
+                                                                                          subject,
+                                                                                          action_id,
+                                                                                          details,
+                                                                                          implicit_authorization);
+
+  /* first see if there's an implicit authorization for subject available */
+  if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED)
+    {
+      g_debug (" is authorized (has implicit authorization local=%d active=%d)",
+               session_is_local,
+               session_is_active);
+      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+      goto out;
+    }
+
+  /* then see if there's a temporary authorization for the subject */
+  if (temporary_authorization_store_has_authorization (priv->temporary_authorization_store,
+                                                       subject,
+                                                       action_id))
+    {
+      g_debug (" is authorized (has temporary authorization)");
+      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+      goto out;
+    }
+
+#if 0
+  /* then see if we have an authorization for the user */
+  if (check_authorization_for_identity (interactive_authority, user_of_subject, action_id))
+    {
+      g_debug (" is authorized (user identity has authorization)");
+      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+      goto out;
+    }
+
+  /* then see if we have a permanent authorization for any of the groups the user is in */
+  groups_of_user = get_groups_for_user (interactive_authority, user_of_subject);
+  for (l = groups_of_user; l != NULL; l = l->next)
+    {
+      PolkitIdentity *group = POLKIT_IDENTITY (l->data);
+
+      if (check_authorization_for_identity (interactive_authority, group, action_id))
+        {
+          g_debug (" is authorized (group identity has authorization)");
+          result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+          goto out;
+        }
+    }
+#endif
+
+  if (implicit_authorization != POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED)
+    {
+      result = polkit_authorization_result_new (FALSE, TRUE, NULL);
+
+      /* return implicit_authorization so the caller can use an authentication agent if applicable */
+      if (out_implicit_authorization != NULL)
+        *out_implicit_authorization = implicit_authorization;
+
+      g_debug (" challenge (implicit_authorization = %s)",
+               polkit_implicit_authorization_to_string (implicit_authorization));
+    }
+  else
+    {
+      result = polkit_authorization_result_new (FALSE, FALSE, NULL);
+      g_debug (" not authorized");
+    }
+ out:
+  g_free (subject_str);
+
+  g_list_foreach (groups_of_user, (GFunc) g_object_unref, NULL);
+  g_list_free (groups_of_user);
+
+  if (user_of_subject != NULL)
+    g_object_unref (user_of_subject);
+
+  if (session_for_subject != NULL)
+    g_object_unref (session_for_subject);
+
+  if (action_desc != NULL)
+    g_object_unref (action_desc);
+
+  g_debug (" ");
+
+  return result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * polkit_backend_interactive_authority_get_admin_identities:
+ * @authority: A #PolkitBackendInteractiveAuthority.
+ * @caller: The subject that is inquiring whether @subject is authorized.
+ * @subject: The subject we are about to authenticate for.
+ * @action_id: The action we are about to authenticate for.
+ * @details: Details about the action.
+ *
+ * Gets a list of identities to use for administrator authentication.
+ *
+ * The default implementation returns a list with a single element for the super user.
+ *
+ * Returns: A list of #PolkitIdentities. Free each element
+ *     g_object_unref(), then free the list with g_list_free().
+ */
+GList *
+polkit_backend_interactive_authority_get_admin_identities (PolkitBackendInteractiveAuthority *authority,
+                                                           PolkitSubject                     *caller,
+                                                           PolkitSubject                     *subject,
+                                                           const gchar                       *action_id,
+                                                           PolkitDetails                     *details)
+{
+  PolkitBackendInteractiveAuthorityClass *klass;
+  GList *ret;
+
+  klass = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_CLASS (authority);
+
+  if (klass->get_admin_identities == NULL)
+    {
+      ret = g_list_prepend (NULL, polkit_unix_user_new (0));
+    }
+  else
+    {
+      ret = klass->get_admin_identities (authority,
+                                         caller,
+                                         subject,
+                                         action_id,
+                                         details);
+    }
+
+  return ret;
+}
+
+/**
+ * polkit_backend_interactive_authority_check_authorization_sync:
+ * @authority: A #PolkitBackendInteractiveAuthority.
+ * @caller: The subject that is inquiring whether @subject is authorized.
+ * @subject: The subject we are checking an authorization for.
+ * @action_id: The action we are checking an authorization for.
+ * @details: Details about the action.
+ * @implicit: A #PolkitImplicitAuthorization value computed from the policy file and @subject.
+ *
+ * Checks whether @subject is authorized to perform the action
+ * specified by @action_id and @details.
+ *
+ * The default implementation of this method simply returns @implicit.
+ *
+ * Returns: A #PolkitImplicitAuthorization that specifies if the subject is authorized or whether
+ *     authentication is required.
+ */
+PolkitImplicitAuthorization
+polkit_backend_interactive_authority_check_authorization_sync (PolkitBackendInteractiveAuthority *authority,
+                                                               PolkitSubject                     *caller,
+                                                               PolkitSubject                     *subject,
+                                                               const gchar                       *action_id,
+                                                               PolkitDetails                     *details,
+                                                               PolkitImplicitAuthorization        implicit)
+{
+  PolkitBackendInteractiveAuthorityClass *klass;
+  PolkitImplicitAuthorization ret;
+
+  klass = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_CLASS (authority);
+
+  if (klass->check_authorization_sync == NULL)
+    {
+      ret = implicit;
+    }
+  else
+    {
+      ret = klass->check_authorization_sync (authority,
+                                             caller,
+                                             subject,
+                                             action_id,
+                                             details,
+                                             implicit);
+    }
+
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+struct AuthenticationAgent
+{
+  PolkitSubject *session;
+
+  gchar *locale;
+  gchar *object_path;
+  gchar *unique_system_bus_name;
+
+  EggDBusObjectProxy *object_proxy;
+
+  GList *active_sessions;
+};
+
+struct AuthenticationSession
+{
+  AuthenticationAgent         *agent;
+
+  gchar                       *cookie;
+
+  PolkitSubject               *subject;
+
+  PolkitIdentity              *user_of_subject;
+
+  PolkitBackendInteractiveAuthority *authority;
+
+  GList                       *identities;
+
+  gchar                       *action_id;
+
+  gchar                       *initiated_by_system_bus_unique_name;
+
+  PolkitImplicitAuthorization  implicit_authorization;
+
+  AuthenticationAgentCallback  callback;
+
+  gpointer                     user_data;
+
+  guint                        call_id;
+
+  gboolean                     is_authenticated;
+
+  GCancellable                *cancellable;
+
+  gulong                       cancellable_signal_handler_id;
+};
+
+static void
+authentication_session_cancelled_cb (GCancellable *cancellable,
+                                     AuthenticationSession *session)
+{
+  authentication_session_cancel (session);
+}
+
+static AuthenticationSession *
+authentication_session_new (AuthenticationAgent         *agent,
+                            const gchar                 *cookie,
+                            PolkitSubject               *subject,
+                            PolkitIdentity              *user_of_subject,
+                            PolkitBackendInteractiveAuthority *authority,
+                            GList                       *identities,
+                            const gchar                 *action_id,
+                            const gchar                 *initiated_by_system_bus_unique_name,
+                            PolkitImplicitAuthorization  implicit_authorization,
+                            GCancellable                *cancellable,
+                            AuthenticationAgentCallback  callback,
+                            gpointer                     user_data)
+{
+  AuthenticationSession *session;
+
+  session = g_new0 (AuthenticationSession, 1);
+  session->agent = agent;
+  session->cookie = g_strdup (cookie);
+  session->subject = g_object_ref (subject);
+  session->user_of_subject = g_object_ref (user_of_subject);
+  session->authority = g_object_ref (authority);
+  session->identities = g_list_copy (identities);
+  g_list_foreach (session->identities, (GFunc) g_object_ref, NULL);
+  session->action_id = g_strdup (action_id);
+  session->initiated_by_system_bus_unique_name = g_strdup (initiated_by_system_bus_unique_name);
+  session->implicit_authorization = implicit_authorization;
+  session->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+  session->callback = callback;
+  session->user_data = user_data;
+
+  if (session->cancellable != NULL)
+    {
+      session->cancellable_signal_handler_id = g_signal_connect (session->cancellable,
+                                                                 "cancelled",
+                                                                 G_CALLBACK (authentication_session_cancelled_cb),
+                                                                 session);
+    }
+
+  return session;
+}
+
+static void
+authentication_session_free (AuthenticationSession *session)
+{
+  g_free (session->cookie);
+  g_list_foreach (session->identities, (GFunc) g_object_unref, NULL);
+  g_list_free (session->identities);
+  g_object_unref (session->subject);
+  g_object_unref (session->user_of_subject);
+  g_object_unref (session->authority);
+  g_free (session->action_id);
+  g_free (session->initiated_by_system_bus_unique_name);
+  if (session->cancellable_signal_handler_id > 0)
+    g_signal_handler_disconnect (session->cancellable, session->cancellable_signal_handler_id);
+  if (session->cancellable != NULL)
+    g_object_unref (session->cancellable);
+  g_free (session);
+}
+
+static gchar *
+authentication_agent_new_cookie (AuthenticationAgent *agent)
+{
+  static gint counter = 0;
+
+  /* TODO: use a more random-looking cookie */
+
+  return g_strdup_printf ("cookie%d", counter++);
+}
+
+static void
+authentication_agent_free (AuthenticationAgent *agent)
+{
+  /* cancel all active authentication sessions; use a copy of the list since
+   * callbacks will modify the list
+   */
+  if (agent->active_sessions != NULL)
+    {
+      GList *l;
+      GList *active_sessions;
+
+      active_sessions = g_list_copy (agent->active_sessions);
+      for (l = active_sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          authentication_session_cancel (session);
+        }
+      g_list_free (active_sessions);
+    }
+
+  g_object_unref (agent->object_proxy);
+
+  g_object_unref (agent->session);
+  g_free (agent->locale);
+  g_free (agent->object_path);
+  g_free (agent->unique_system_bus_name);
+  g_free (agent);
+}
+
+static AuthenticationAgent *
+authentication_agent_new (PolkitSubject *session,
+                          const gchar *unique_system_bus_name,
+                          const gchar *locale,
+                          const gchar *object_path)
+{
+  AuthenticationAgent *agent;
+  EggDBusConnection *system_bus;
+
+  agent = g_new0 (AuthenticationAgent, 1);
+
+  agent->session = g_object_ref (session);
+  agent->object_path = g_strdup (object_path);
+  agent->unique_system_bus_name = g_strdup (unique_system_bus_name);
+  agent->locale = g_strdup (locale);
+
+  system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  agent->object_proxy = egg_dbus_connection_get_object_proxy (system_bus,
+                                                              agent->unique_system_bus_name,
+                                                              agent->object_path);
+
+  g_object_unref (system_bus);
+
+  return agent;
+}
+
+static AuthenticationAgent *
+get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authority,
+                                      PolkitSubject *subject)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitSubject *session_for_subject;
+  AuthenticationAgent *agent;
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  agent = NULL;
+  session_for_subject = NULL;
+
+  session_for_subject = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
+                                                                                subject,
+                                                                                NULL);
+  if (session_for_subject == NULL)
+    goto out;
+
+  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_subject);
+
+ out:
+  if (session_for_subject != NULL)
+    g_object_unref (session_for_subject);
+
+  return agent;
+}
+
+static AuthenticationSession *
+get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *authority,
+                                       const gchar *cookie)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GHashTableIter hash_iter;
+  AuthenticationAgent *agent;
+  AuthenticationSession *result;
+
+  result = NULL;
+
+  /* TODO: perhaps use a hash on the cookie to speed this up */
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
+    {
+      GList *l;
+
+      for (l = agent->active_sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          if (strcmp (session->cookie, cookie) == 0)
+            {
+              result = session;
+              goto out;
+            }
+        }
+    }
+
+ out:
+  return result;
+}
+
+static GList *
+get_authentication_sessions_initiated_by_system_bus_unique_name (PolkitBackendInteractiveAuthority *authority,
+                                                                 const gchar *system_bus_unique_name)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GHashTableIter hash_iter;
+  AuthenticationAgent *agent;
+  GList *result;
+
+  result = NULL;
+
+  /* TODO: perhaps use a hash on the cookie to speed this up */
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
+    {
+      GList *l;
+
+      for (l = agent->active_sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          if (strcmp (session->initiated_by_system_bus_unique_name, system_bus_unique_name) == 0)
+            {
+              result = g_list_prepend (result, session);
+            }
+        }
+    }
+
+   return result;
+}
+
+static GList *
+get_authentication_sessions_for_system_bus_unique_name_subject (PolkitBackendInteractiveAuthority *authority,
+                                                                const gchar *system_bus_unique_name)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GHashTableIter hash_iter;
+  AuthenticationAgent *agent;
+  GList *result;
+
+  result = NULL;
+
+  /* TODO: perhaps use a hash on the cookie to speed this up */
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
+    {
+      GList *l;
+
+      for (l = agent->active_sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          if (POLKIT_IS_SYSTEM_BUS_NAME (session->subject) &&
+              strcmp (polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (session->subject)),
+                      system_bus_unique_name) == 0)
+            {
+              result = g_list_prepend (result, session);
+            }
+        }
+    }
+
+   return result;
+}
+
+
+static AuthenticationAgent *
+get_authentication_agent_by_unique_system_bus_name (PolkitBackendInteractiveAuthority *authority,
+                                                    const gchar *unique_system_bus_name)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  GHashTableIter hash_iter;
+  AuthenticationAgent *agent;
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
+  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
+    {
+      if (strcmp (agent->unique_system_bus_name, unique_system_bus_name) == 0)
+        goto out;
+    }
+
+  agent = NULL;
+
+  out:
+  return agent;
+}
+
+static void
+authentication_agent_begin_callback (GObject *source_object,
+                                     GAsyncResult *res,
+                                     gpointer user_data)
+{
+  _PolkitAuthenticationAgent *agent_dbus = _POLKIT_AUTHENTICATION_AGENT (source_object);
+  AuthenticationSession *session = user_data;
+  GError *error;
+  gboolean gained_authorization;
+
+  error = NULL;
+  if (!_polkit_authentication_agent_begin_authentication_finish (agent_dbus,
+                                                                 res,
+                                                                 &error))
+    {
+      g_warning ("Error performing authentication: %s", error->message);
+      g_error_free (error);
+      gained_authorization = FALSE;
+    }
+  else
+    {
+      gained_authorization = session->is_authenticated;
+
+      g_debug ("Authentication complete, is_authenticated = %d", session->is_authenticated);
+    }
+
+  session->agent->active_sessions = g_list_remove (session->agent->active_sessions, session);
+
+  session->callback (session->agent,
+                     session->subject,
+                     session->user_of_subject,
+                     session->authority,
+                     session->action_id,
+                     session->implicit_authorization,
+                     gained_authorization,
+                     session->user_data);
+
+  authentication_session_free (session);
+}
+
+static GList *
+get_action_lookup_list (void)
+{
+  GList *extensions;
+  GList *l;
+  GIOExtensionPoint *action_lookup_ep;
+  static GList *action_lookup_list = NULL;
+  static gboolean have_looked_up_extensions = FALSE;
+
+  if (have_looked_up_extensions)
+    goto out;
+
+  action_lookup_ep = g_io_extension_point_lookup (POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME);
+  g_assert (action_lookup_ep != NULL);
+
+  extensions = g_io_extension_point_get_extensions (action_lookup_ep);
+  for (l = extensions; l != NULL; l = l->next)
+    {
+      GIOExtension *extension = l->data;
+      PolkitBackendActionLookup *lookup;
+
+      lookup = g_object_new (g_io_extension_get_type (extension), NULL);
+      action_lookup_list = g_list_prepend (action_lookup_list, lookup);
+    }
+  action_lookup_list = g_list_reverse (action_lookup_list);
+
+ out:
+  have_looked_up_extensions = TRUE;
+  return action_lookup_list;
+}
+
+static void
+get_localized_data_for_challenge (PolkitBackendInteractiveAuthority *authority,
+                                  PolkitSubject               *caller,
+                                  PolkitSubject               *subject,
+                                  PolkitIdentity              *user_of_subject,
+                                  const gchar                 *action_id,
+                                  PolkitDetails               *details,
+                                  const gchar                 *locale,
+                                  gchar                      **out_localized_message,
+                                  gchar                      **out_localized_icon_name,
+                                  EggDBusHashMap             **out_localized_details)
+{
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitActionDescription *action_desc;
+  GList *action_lookup_list;
+  GList *l;
+  gchar *message;
+  gchar *icon_name;
+  PolkitDetails *localized_details;
+
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
+
+  message = NULL;
+  icon_name = NULL;
+  localized_details = NULL;
+  action_desc = NULL;
+
+  *out_localized_message = NULL;
+  *out_localized_icon_name = NULL;
+  *out_localized_details = egg_dbus_hash_map_new (G_TYPE_STRING, NULL,
+                                                  G_TYPE_STRING, NULL);
+
+  action_desc = polkit_backend_action_pool_get_action (priv->action_pool,
+                                                       action_id,
+                                                       locale);
+  if (action_desc == NULL)
+    goto out;
+
+  /* Set LANG and locale so gettext() + friends work when running the code in the extensions */
+  if (setlocale (LC_ALL, locale) == NULL)
+    {
+      g_warning ("Invalid locale '%s'", locale);
+    }
+  g_setenv ("LANG", locale, TRUE);
+
+  /* call into extension points to get localized auth dialog data - the list is sorted by priority */
+  action_lookup_list = get_action_lookup_list ();
+  for (l = action_lookup_list; l != NULL; l = l->next)
+    {
+      PolkitBackendActionLookup *lookup = POLKIT_BACKEND_ACTION_LOOKUP (l->data);
+
+      if (message != NULL && icon_name != NULL && localized_details != NULL)
+        break;
+
+      if (message == NULL)
+        message = polkit_backend_action_lookup_get_message (lookup,
+                                                            action_id,
+                                                            details,
+                                                            action_desc);
+
+      if (icon_name == NULL)
+        icon_name = polkit_backend_action_lookup_get_icon_name (lookup,
+                                                                action_id,
+                                                                details,
+                                                                action_desc);
+
+      if (localized_details == NULL)
+        localized_details = polkit_backend_action_lookup_get_details (lookup,
+                                                                      action_id,
+                                                                      details,
+                                                                      action_desc);
+    }
+
+  /* Back to C! */
+  setlocale (LC_ALL, "C");
+  g_setenv ("LANG", "C", TRUE);
+
+  /* fall back to action description */
+  if (message == NULL)
+    {
+      message = g_strdup (polkit_action_description_get_message (action_desc));
+    }
+  if (icon_name == NULL)
+    {
+      icon_name = g_strdup (polkit_action_description_get_icon_name (action_desc));
+    }
+
+
+  if (localized_details != NULL)
+    {
+      GHashTable *hash;
+      GHashTableIter iter;
+      const gchar *key;
+      const gchar *value;
+
+      hash = polkit_details_get_hash (localized_details);
+      if (hash != NULL)
+        {
+          g_hash_table_iter_init (&iter, hash);
+          while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
+            {
+              egg_dbus_hash_map_insert (*out_localized_details, key, value);
+            }
+        }
+    }
+
+ out:
+  if (message == NULL)
+    message = g_strdup ("");
+  if (icon_name == NULL)
+    icon_name = g_strdup ("");
+  *out_localized_message = message;
+  *out_localized_icon_name = icon_name;
+  if (action_desc != NULL)
+    g_object_unref (action_desc);
+}
+
+static void
+authentication_agent_initiate_challenge (AuthenticationAgent         *agent,
+                                         PolkitSubject               *subject,
+                                         PolkitIdentity              *user_of_subject,
+                                         PolkitBackendInteractiveAuthority *authority,
+                                         const gchar                 *action_id,
+                                         PolkitDetails               *details,
+                                         PolkitSubject               *caller,
+                                         PolkitImplicitAuthorization  implicit_authorization,
+                                         GCancellable                *cancellable,
+                                         AuthenticationAgentCallback  callback,
+                                         gpointer                     user_data)
+{
+  AuthenticationSession *session;
+  _PolkitAuthenticationAgent *agent_dbus;
+  gchar *cookie;
+  GList *l;
+  GList *identities;
+  EggDBusArraySeq *real_identities;
+  gchar *localized_message;
+  gchar *localized_icon_name;
+  EggDBusHashMap *localized_details;
+
+  get_localized_data_for_challenge (authority,
+                                    caller,
+                                    subject,
+                                    user_of_subject,
+                                    action_id,
+                                    details,
+                                    agent->locale,
+                                    &localized_message,
+                                    &localized_icon_name,
+                                    &localized_details);
+
+  cookie = authentication_agent_new_cookie (agent);
+
+  identities = NULL;
+
+  /* select admin user if required by the implicit authorization */
+  if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED ||
+      implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
+    {
+      identities = polkit_backend_interactive_authority_get_admin_identities (authority,
+                                                                              caller,
+                                                                              subject,
+                                                                              action_id,
+                                                                              details);
+    }
+  else
+    {
+      identities = g_list_prepend (identities, g_object_ref (user_of_subject));
+    }
+
+  session = authentication_session_new (agent,
+                                        cookie,
+                                        subject,
+                                        user_of_subject,
+                                        authority,
+                                        identities,
+                                        action_id,
+                                        polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
+                                        implicit_authorization,
+                                        cancellable,
+                                        callback,
+                                        user_data);
+
+  agent->active_sessions = g_list_prepend (agent->active_sessions, session);
+
+  agent_dbus = _POLKIT_QUERY_INTERFACE_AUTHENTICATION_AGENT (agent->object_proxy);
+
+  real_identities = egg_dbus_array_seq_new (EGG_DBUS_TYPE_STRUCTURE, g_object_unref, NULL, NULL);
+  for (l = identities; l != NULL; l = l->next)
+    {
+      PolkitIdentity *identity = POLKIT_IDENTITY (l->data);
+      egg_dbus_array_seq_add (real_identities, polkit_identity_get_real (identity));
+    }
+
+  session->call_id = _polkit_authentication_agent_begin_authentication (agent_dbus,
+                                                                        EGG_DBUS_CALL_FLAGS_TIMEOUT_NONE,
+                                                                        action_id,
+                                                                        localized_message,
+                                                                        localized_icon_name,
+                                                                        localized_details,
+                                                                        session->cookie,
+                                                                        real_identities,
+                                                                        NULL,
+                                                                        authentication_agent_begin_callback,
+                                                                        session);
+
+  g_list_foreach (identities, (GFunc) g_object_unref, NULL);
+  g_list_free (identities);
+  g_object_unref (real_identities);
+  g_free (cookie);
+
+  g_free (localized_message);
+  g_free (localized_icon_name);
+  g_object_unref (localized_details);
+}
+
+static void
+authentication_agent_cancel_callback (GObject *source_object,
+                                      GAsyncResult *res,
+                                      gpointer user_data)
+{
+  _PolkitAuthenticationAgent *agent_dbus = _POLKIT_AUTHENTICATION_AGENT (source_object);
+
+  _polkit_authentication_agent_cancel_authentication_finish (agent_dbus,
+                                                             res,
+                                                             NULL);
+}
+
+static void
+authentication_session_cancel (AuthenticationSession *session)
+{
+  EggDBusConnection *system_bus;
+  _PolkitAuthenticationAgent *agent_dbus;
+
+  system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  agent_dbus = _POLKIT_QUERY_INTERFACE_AUTHENTICATION_AGENT (session->agent->object_proxy);
+
+  _polkit_authentication_agent_cancel_authentication (agent_dbus,
+                                                      EGG_DBUS_CALL_FLAGS_NONE,
+                                                      session->cookie,
+                                                      NULL,
+                                                      authentication_agent_cancel_callback,
+                                                      NULL);
+
+  egg_dbus_connection_pending_call_cancel (system_bus, session->call_id);
+
+  g_object_unref (system_bus);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+polkit_backend_interactive_authority_register_authentication_agent (PolkitBackendAuthority   *authority,
+                                                              PolkitSubject            *caller,
+                                                              const gchar              *session_id,
+                                                              const gchar              *locale,
+                                                              const gchar              *object_path,
+                                                              GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitSubject *session_for_caller;
+  AuthenticationAgent *agent;
+  gboolean ret;
+
+  session_for_caller = NULL;
+  ret = FALSE;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  if (session_id != NULL && strlen (session_id) > 0)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "The session_id parameter must be blank for now.");
+      goto out;
+    }
+
+  session_for_caller = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
+                                                                               caller,
+                                                                               NULL);
+  if (session_for_caller == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Cannot determine session");
+      goto out;
+    }
+
+  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_caller);
+  if (agent != NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "An authentication agent already exists for session");
+      goto out;
+    }
+
+  /* TODO: validate that object path is well-formed */
+
+  agent = authentication_agent_new (session_for_caller,
+                                    polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
+                                    locale,
+                                    object_path);
+
+  g_hash_table_insert (priv->hash_session_to_authentication_agent,
+                       g_object_ref (session_for_caller),
+                       agent);
+
+  g_debug ("Added authentication agent for session %s at name %s, object path %s, locale %s",
+           polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session_for_caller)),
+           polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
+           object_path,
+           locale);
+
+  ret = TRUE;
+
+ out:
+  if (session_for_caller != NULL)
+    g_object_unref (session_for_caller);
+
+  return ret;
+}
+
+static gboolean
+polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBackendAuthority   *authority,
+                                                                PolkitSubject            *caller,
+                                                                const gchar              *session_id,
+                                                                const gchar              *object_path,
+                                                                GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitSubject *session_for_caller;
+  AuthenticationAgent *agent;
+  gboolean ret;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  ret = FALSE;
+  session_for_caller = NULL;
+
+  if (session_id != NULL && strlen (session_id) > 0)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "The session_id parameter must be blank for now.");
+      goto out;
+    }
+
+  session_for_caller = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
+                                                                               caller,
+                                                                               NULL);
+  if (session_for_caller == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Cannot determine session");
+      goto out;
+    }
+
+  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_caller);
+  if (agent == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "No such agent registered");
+      goto out;
+    }
+
+  if (strcmp (agent->unique_system_bus_name,
+              polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller))) != 0)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "System bus names do not match");
+      goto out;
+    }
+
+  if (strcmp (agent->object_path, object_path) != 0)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Object paths do not match");
+      goto out;
+    }
+
+
+  g_debug ("Removing authentication agent for session %s at name %s, object path %s (unregistered)",
+           polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (agent->session)),
+           agent->unique_system_bus_name,
+           agent->object_path);
+
+  /* this works because we have exactly one agent per session */
+  g_hash_table_remove (priv->hash_session_to_authentication_agent, agent->session);
+
+  ret = TRUE;
+
+ out:
+  if (session_for_caller != NULL)
+    g_object_unref (session_for_caller);
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+polkit_backend_interactive_authority_authentication_agent_response (PolkitBackendAuthority   *authority,
+                                                              PolkitSubject            *caller,
+                                                              const gchar              *cookie,
+                                                              PolkitIdentity           *identity,
+                                                              GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitIdentity *user_of_caller;
+  gchar *identity_str;
+  AuthenticationSession *session;
+  GList *l;
+  gboolean ret;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  ret = FALSE;
+  user_of_caller = NULL;
+
+  identity_str = polkit_identity_to_string (identity);
+
+  g_debug ("In authentication_agent_response for cookie '%s' and identity %s",
+           cookie,
+           identity_str);
+
+  user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
+                                                                        caller,
+                                                                        error);
+  if (user_of_caller == NULL)
+    goto out;
+
+  /* only uid 0 is allowed to invoke this method */
+  if (!POLKIT_IS_UNIX_USER (user_of_caller) || polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Only uid 0 may invoke this method. This incident has been logged.");
+      /* TODO: actually log this */
+      goto out;
+    }
+
+  /* find the authentication session */
+  session = get_authentication_session_for_cookie (interactive_authority, cookie);
+  if (session == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "No session for cookie");
+      goto out;
+    }
+
+  /* check that the authentication identity was one of the possibilities we allowed */
+  for (l = session->identities; l != NULL; l = l->next)
+    {
+      PolkitIdentity *i = POLKIT_IDENTITY (l->data);
+
+      if (polkit_identity_equal (i, identity))
+        break;
+    }
+
+  if (l == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "The authenticated identity is wrong");
+      goto out;
+    }
+
+  /* checks out, mark the session as authenticated */
+  session->is_authenticated = TRUE;
+
+  ret = TRUE;
+
+ out:
+  g_free (identity_str);
+
+  if (user_of_caller != NULL)
+    g_object_unref (user_of_caller);
+
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+polkit_backend_interactive_authority_system_bus_name_owner_changed (PolkitBackendAuthority   *authority,
+                                                              const gchar              *name,
+                                                              const gchar              *old_owner,
+                                                              const gchar              *new_owner)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  //g_debug ("name-owner-changed: '%s' '%s' '%s'", name, old_owner, new_owner);
+
+  if (name[0] == ':' && strlen (new_owner) == 0)
+    {
+      AuthenticationAgent *agent;
+      GList *sessions;
+      GList *l;
+
+      agent = get_authentication_agent_by_unique_system_bus_name (interactive_authority, name);
+      if (agent != NULL)
+        {
+          g_debug ("Removing authentication agent for session %s at name %s, object path %s (disconnected from bus)",
+                   polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (agent->session)),
+                   agent->unique_system_bus_name,
+                   agent->object_path);
+
+          /* this works because we have exactly one agent per session */
+          g_hash_table_remove (priv->hash_session_to_authentication_agent, agent->session);
+        }
+
+      /* cancel all authentication sessions initiated by the process owning the vanished name */
+      sessions = get_authentication_sessions_initiated_by_system_bus_unique_name (interactive_authority, name);
+      for (l = sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          authentication_session_cancel (session);
+        }
+      g_list_free (sessions);
+
+      /* cancel all authentication sessions that is about the vanished name */
+      sessions = get_authentication_sessions_for_system_bus_unique_name_subject (interactive_authority, name);
+      for (l = sessions; l != NULL; l = l->next)
+        {
+          AuthenticationSession *session = l->data;
+
+          authentication_session_cancel (session);
+        }
+      g_list_free (sessions);
+
+    }
+
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct TemporaryAuthorization TemporaryAuthorization;
+
+struct TemporaryAuthorizationStore
+{
+  GList *authorizations;
+};
+
+struct TemporaryAuthorization
+{
+  PolkitSubject *subject;
+  gchar *action_id;
+  guint64 time_granted;
+};
+
+static void
+temporary_authorization_free (TemporaryAuthorization *authorization)
+{
+  g_object_unref (authorization->subject);
+  g_free (authorization->action_id);
+  g_free (authorization);
+}
+
+static TemporaryAuthorization *
+temporary_authorization_new (PolkitSubject *subject,
+                             const gchar   *action_id)
+{
+  TemporaryAuthorization *authorization;
+
+  authorization = g_new0 (TemporaryAuthorization, 1);
+  authorization->subject = g_object_ref (subject);
+  authorization->action_id = g_strdup (action_id);
+  authorization->time_granted = time (NULL);
+
+  return authorization;
+}
+
+static TemporaryAuthorizationStore *
+temporary_authorization_store_new (void)
+{
+  TemporaryAuthorizationStore *store;
+
+  store = g_new0 (TemporaryAuthorizationStore, 1);
+  store->authorizations = NULL;
+
+  return store;
+}
+
+static void
+temporary_authorization_store_free (TemporaryAuthorizationStore *store)
+{
+  g_list_foreach (store->authorizations, (GFunc) temporary_authorization_free, NULL);
+  g_list_free (store->authorizations);
+  g_free (store);
+}
+
+static gboolean
+temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
+                                                 PolkitSubject               *subject,
+                                                 const gchar                 *action_id)
+{
+  GList *l;
+  gboolean ret;
+
+  g_return_val_if_fail (store != NULL, FALSE);
+  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
+  g_return_val_if_fail (action_id != NULL, FALSE);
+
+  ret = FALSE;
+
+  for (l = store->authorizations; l != NULL; l = l->next) {
+    TemporaryAuthorization *authorization = l->data;
+
+    if (strcmp (action_id, authorization->action_id) == 0 &&
+        polkit_subject_equal (subject, authorization->subject))
+      {
+        ret = TRUE;
+        goto out;
+      }
+  }
+
+ out:
+  return ret;
+}
+
+static void
+temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
+                                                 PolkitSubject               *subject,
+                                                 const gchar                 *action_id)
+{
+  g_return_if_fail (store != NULL);
+  g_return_if_fail (POLKIT_IS_SUBJECT (subject));
+  g_return_if_fail (action_id != NULL);
+  g_return_if_fail (!temporary_authorization_store_has_authorization (store, subject, action_id));
+
+  store->authorizations = g_list_prepend (store->authorizations,
+                                          temporary_authorization_new (subject, action_id));
+}
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.h b/src/polkitbackend/polkitbackendinteractiveauthority.h
new file mode 100644
index 0000000..efef0a4
--- /dev/null
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.h
@@ -0,0 +1,138 @@
+/*
+ * 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>
+ */
+
+#if !defined (_POLKIT_BACKEND_COMPILATION) && !defined(_POLKIT_BACKEND_INSIDE_POLKIT_BACKEND_H)
+#error "Only <polkitbackend/polkitbackend.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __POLKIT_BACKEND_INTERACTIVE_AUTHORITY_H
+#define __POLKIT_BACKEND_INTERACTIVE_AUTHORITY_H
+
+#include <glib-object.h>
+#include <polkitbackend/polkitbackendtypes.h>
+#include <polkitbackend/polkitbackendauthority.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY         (polkit_backend_interactive_authority_get_type ())
+#define POLKIT_BACKEND_INTERACTIVE_AUTHORITY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY, PolkitBackendInteractiveAuthority))
+#define POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY, PolkitBackendInteractiveAuthorityClass))
+#define POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY,PolkitBackendInteractiveAuthorityClass))
+#define POLKIT_BACKEND_IS_INTERACTIVE_AUTHORITY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY))
+#define POLKIT_BACKEND_IS_INTERACTIVE_AUTHORITY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY))
+
+typedef struct _PolkitBackendInteractiveAuthorityClass    PolkitBackendInteractiveAuthorityClass;
+
+/**
+ * PolkitBackendInteractiveAuthority:
+ *
+ * The #PolkitBackendInteractiveAuthority struct should not be accessed directly.
+ */
+struct _PolkitBackendInteractiveAuthority
+{
+  /*< private >*/
+  PolkitBackendAuthority parent_instance;
+};
+
+/**
+ * PolkitBackendInteractiveAuthorityClass:
+ * @parent_class: The parent class.
+ * @get_admin_identities: Returns list of identities for administrator authentication or %NULL to use the default
+ *   implementation. See polkit_backend_interactive_authority_get_admin_identities() for details.
+ * @check_authorization_sync: Checks for an authorization or %NULL to use the default implementation.
+ *  See polkit_backend_interactive_authority_check_authorization_sync() for details.
+ *
+ * Class structure for #PolkitBackendInteractiveAuthority.
+ */
+struct _PolkitBackendInteractiveAuthorityClass
+{
+  /*< public >*/
+  PolkitBackendAuthorityClass parent_class;
+
+  /* VTable */
+  GList *                     (*get_admin_identities)          (PolkitBackendInteractiveAuthority *authority,
+                                                                PolkitSubject                     *caller,
+                                                                PolkitSubject                     *subject,
+                                                                const gchar                       *action_id,
+                                                                PolkitDetails                     *details);
+
+  PolkitImplicitAuthorization (*check_authorization_sync) (PolkitBackendInteractiveAuthority *authority,
+                                                           PolkitSubject                     *caller,
+                                                           PolkitSubject                     *subject,
+                                                           const gchar                       *action_id,
+                                                           PolkitDetails                     *details,
+                                                           PolkitImplicitAuthorization        implicit);
+
+  /*< private >*/
+  /* Padding for future expansion */
+  void (*_polkit_reserved1) (void);
+  void (*_polkit_reserved2) (void);
+  void (*_polkit_reserved3) (void);
+  void (*_polkit_reserved4) (void);
+  void (*_polkit_reserved5) (void);
+  void (*_polkit_reserved6) (void);
+  void (*_polkit_reserved7) (void);
+  void (*_polkit_reserved8) (void);
+  void (*_polkit_reserved9) (void);
+  void (*_polkit_reserved10) (void);
+  void (*_polkit_reserved11) (void);
+  void (*_polkit_reserved12) (void);
+  void (*_polkit_reserved13) (void);
+  void (*_polkit_reserved14) (void);
+  void (*_polkit_reserved15) (void);
+  void (*_polkit_reserved16) (void);
+  void (*_polkit_reserved17) (void);
+  void (*_polkit_reserved18) (void);
+  void (*_polkit_reserved19) (void);
+  void (*_polkit_reserved20) (void);
+  void (*_polkit_reserved21) (void);
+  void (*_polkit_reserved22) (void);
+  void (*_polkit_reserved23) (void);
+  void (*_polkit_reserved24) (void);
+  void (*_polkit_reserved25) (void);
+  void (*_polkit_reserved26) (void);
+  void (*_polkit_reserved27) (void);
+  void (*_polkit_reserved28) (void);
+  void (*_polkit_reserved29) (void);
+  void (*_polkit_reserved30) (void);
+  void (*_polkit_reserved31) (void);
+  void (*_polkit_reserved32) (void);
+};
+
+GType   polkit_backend_interactive_authority_get_type            (void) G_GNUC_CONST;
+GList  *polkit_backend_interactive_authority_get_admin_identities (PolkitBackendInteractiveAuthority *authority,
+                                                                   PolkitSubject                     *caller,
+                                                                   PolkitSubject                     *subject,
+                                                                   const gchar                       *action_id,
+                                                                   PolkitDetails                     *details);
+
+PolkitImplicitAuthorization polkit_backend_interactive_authority_check_authorization_sync (
+                                                          PolkitBackendInteractiveAuthority *authority,
+                                                          PolkitSubject                     *caller,
+                                                          PolkitSubject                     *subject,
+                                                          const gchar                       *action_id,
+                                                          PolkitDetails                     *details,
+                                                          PolkitImplicitAuthorization        implicit);
+
+G_END_DECLS
+
+#endif /* __POLKIT_BACKEND_INTERACTIVE_AUTHORITY_H */
+
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index 4bfa7da..a68663d 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -28,11 +28,8 @@
 #include <locale.h>
 
 #include <polkit/polkit.h>
-#include "polkitbackendlocalauthority.h"
-#include "polkitbackendactionpool.h"
-#include "polkitbackendsessionmonitor.h"
 #include "polkitbackendconfigsource.h"
-#include "polkitbackendactionlookup.h"
+#include "polkitbackendlocalauthority.h"
 
 #include <polkit/polkitprivate.h>
 
@@ -48,148 +45,37 @@
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-typedef struct TemporaryAuthorizationStore TemporaryAuthorizationStore;
-
-static TemporaryAuthorizationStore *temporary_authorization_store_new (void);
-static void                         temporary_authorization_store_free (TemporaryAuthorizationStore *store);
-
-static gboolean temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
-                                                                 PolkitSubject               *subject,
-                                                                 const gchar                 *action_id);
-
-static void     temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
-                                                                 PolkitSubject               *subject,
-                                                                 const gchar                 *action_id);
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-struct AuthenticationAgent;
-typedef struct AuthenticationAgent AuthenticationAgent;
-
-struct AuthenticationSession;
-typedef struct AuthenticationSession AuthenticationSession;
-
-typedef void (*AuthenticationAgentCallback) (AuthenticationAgent         *agent,
-                                             PolkitSubject               *subject,
-                                             PolkitIdentity              *user_of_subject,
-                                             PolkitBackendLocalAuthority *authority,
-                                             const gchar                 *action_id,
-                                             PolkitImplicitAuthorization  implicit_authorization,
-                                             gboolean                     authentication_success,
-                                             gpointer                     user_data);
-
-static void                authentication_agent_free (AuthenticationAgent *agent);
-
-static void                authentication_agent_initiate_challenge (AuthenticationAgent         *agent,
-                                                                    PolkitSubject               *subject,
-                                                                    PolkitIdentity              *user_of_subject,
-                                                                    PolkitBackendLocalAuthority *authority,
-                                                                    const gchar                 *action_id,
-                                                                    PolkitDetails               *details,
-                                                                    PolkitSubject               *caller,
-                                                                    PolkitImplicitAuthorization  implicit_authorization,
-                                                                    GCancellable                *cancellable,
-                                                                    AuthenticationAgentCallback  callback,
-                                                                    gpointer                     user_data);
-
-static AuthenticationAgent *get_authentication_agent_for_subject (PolkitBackendLocalAuthority *authority,
-                                                                  PolkitSubject *subject);
-
-static AuthenticationSession *get_authentication_session_for_cookie (PolkitBackendLocalAuthority *authority,
-                                                                     const gchar *cookie);
-
-static GList *get_authentication_sessions_initiated_by_system_bus_unique_name (PolkitBackendLocalAuthority *authority,
-                                                                               const gchar *system_bus_unique_name);
-
-static void authentication_session_cancel (AuthenticationSession *session);
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static GList *get_users_in_group (PolkitBackendLocalAuthority *authority,
+static GList *get_users_in_group (PolkitBackendInteractiveAuthority *authority,
                                   PolkitIdentity              *group,
                                   gboolean                     include_root);
 
 #if 0
-static GList *get_groups_for_user (PolkitBackendLocalAuthority *authority,
+static GList *get_groups_for_user (PolkitBackendInteractiveAuthority *authority,
                                    PolkitIdentity              *user);
 #endif
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static void polkit_backend_local_authority_system_bus_name_owner_changed (PolkitBackendAuthority   *authority,
-                                                                          const gchar              *name,
-                                                                          const gchar              *old_owner,
-                                                                          const gchar              *new_owner);
-
-static GList *polkit_backend_local_authority_enumerate_actions  (PolkitBackendAuthority   *authority,
-                                                                 PolkitSubject            *caller,
-                                                                 const gchar              *locale,
-                                                                 GError                  **error);
-
-static void polkit_backend_local_authority_check_authorization (PolkitBackendAuthority        *authority,
-                                                                PolkitSubject                 *caller,
-                                                                PolkitSubject                 *subject,
-                                                                const gchar                   *action_id,
-                                                                PolkitDetails                 *details,
-                                                                PolkitCheckAuthorizationFlags  flags,
-                                                                GCancellable                  *cancellable,
-                                                                GAsyncReadyCallback            callback,
-                                                                gpointer                       user_data);
-
-static PolkitAuthorizationResult *polkit_backend_local_authority_check_authorization_finish (
-                                                                 PolkitBackendAuthority  *authority,
-                                                                 GAsyncResult            *res,
-                                                                 GError                 **error);
-
-static PolkitAuthorizationResult *check_authorization_sync (PolkitBackendAuthority         *authority,
-                                                            PolkitSubject                  *subject,
-                                                            const gchar                    *action_id,
-                                                            PolkitCheckAuthorizationFlags   flags,
-                                                            PolkitImplicitAuthorization    *out_implicit_authorization,
-                                                            GError                        **error);
-
-static gboolean polkit_backend_local_authority_register_authentication_agent (PolkitBackendAuthority   *authority,
-                                                                              PolkitSubject            *caller,
-                                                                              const gchar              *session_id,
-                                                                              const gchar              *locale,
-                                                                              const gchar              *object_path,
-                                                                              GError                  **error);
-
-static gboolean polkit_backend_local_authority_unregister_authentication_agent (PolkitBackendAuthority   *authority,
-                                                                                PolkitSubject            *caller,
-                                                                                const gchar              *session_id,
-                                                                                const gchar              *object_path,
-                                                                                GError                  **error);
-
-static gboolean polkit_backend_local_authority_authentication_agent_response (PolkitBackendAuthority   *authority,
-                                                                              PolkitSubject            *caller,
-                                                                              const gchar              *cookie,
-                                                                              PolkitIdentity           *identity,
-                                                                              GError                  **error);
-
-
-/* ---------------------------------------------------------------------------------------------------- */
-
 typedef struct
 {
-  PolkitBackendActionPool *action_pool;
-
-  PolkitBackendSessionMonitor *session_monitor;
-
   PolkitBackendConfigSource *config_source;
 
-  TemporaryAuthorizationStore *temporary_authorization_store;
-
-  GHashTable *hash_session_to_authentication_agent;
-
 } PolkitBackendLocalAuthorityPrivate;
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority, polkit_backend_local_authority,POLKIT_BACKEND_TYPE_AUTHORITY,
+static GList *polkit_backend_local_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
+                                                                        PolkitSubject                     *caller,
+                                                                        PolkitSubject                     *subject,
+                                                                        const gchar                       *action_id,
+                                                                        PolkitDetails                     *details);
+
+G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority,
+                         polkit_backend_local_authority,
+                         POLKIT_BACKEND_TYPE_INTERACTIVE_AUTHORITY,
                          g_io_extension_point_implement (POLKIT_BACKEND_AUTHORITY_EXTENSION_POINT_NAME,
                                                          g_define_type_id,
-                                                         "local-files " PACKAGE_VERSION,
+                                                         "local-authority" PACKAGE_VERSION,
                                                          0));
 
 #define POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), POLKIT_BACKEND_TYPE_LOCAL_AUTHORITY, PolkitBackendLocalAuthorityPrivate))
@@ -197,15 +83,6 @@ G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority, polkit_backend_local_autho
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-action_pool_changed (PolkitBackendActionPool *action_pool,
-                     PolkitBackendLocalAuthority *authority)
-{
-  g_signal_emit_by_name (authority, "changed");
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
 polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
 {
   PolkitBackendLocalAuthorityPrivate *priv;
@@ -213,26 +90,9 @@ polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
 
   priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
 
-  directory = g_file_new_for_path (PACKAGE_DATA_DIR "/polkit-1/actions");
-  priv->action_pool = polkit_backend_action_pool_new (directory);
-  g_object_unref (directory);
-  g_signal_connect (priv->action_pool,
-                    "changed",
-                    (GCallback) action_pool_changed,
-                    authority);
-
   directory = g_file_new_for_path (PACKAGE_SYSCONF_DIR "/polkit-1/localauthority.conf.d");
   priv->config_source = polkit_backend_config_source_new (directory);
   g_object_unref (directory);
-
-  priv->temporary_authorization_store = temporary_authorization_store_new ();
-
-  priv->hash_session_to_authentication_agent = g_hash_table_new_full ((GHashFunc) polkit_subject_hash,
-                                                                      (GEqualFunc) polkit_subject_equal,
-                                                                      (GDestroyNotify) g_object_unref,
-                                                                      (GDestroyNotify) authentication_agent_free);
-
-  priv->session_monitor = polkit_backend_session_monitor_new ();
 }
 
 static void
@@ -244,19 +104,9 @@ polkit_backend_local_authority_finalize (GObject *object)
   local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (object);
   priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
 
-  if (priv->action_pool != NULL)
-    g_object_unref (priv->action_pool);
-
   if (priv->config_source != NULL)
     g_object_unref (priv->config_source);
 
-  if (priv->session_monitor != NULL)
-    g_object_unref (priv->session_monitor);
-
-  temporary_authorization_store_free (priv->temporary_authorization_store);
-
-  g_hash_table_unref (priv->hash_session_to_authentication_agent);
-
   G_OBJECT_CLASS (polkit_backend_local_authority_parent_class)->finalize (object);
 }
 
@@ -264,863 +114,33 @@ static void
 polkit_backend_local_authority_class_init (PolkitBackendLocalAuthorityClass *klass)
 {
   GObjectClass *gobject_class;
-  PolkitBackendAuthorityClass *authority_class;
+  PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
-  authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
-
-  gobject_class->finalize = polkit_backend_local_authority_finalize;
-
-  authority_class->system_bus_name_owner_changed   = polkit_backend_local_authority_system_bus_name_owner_changed;
-  authority_class->enumerate_actions               = polkit_backend_local_authority_enumerate_actions;
-  authority_class->check_authorization             = polkit_backend_local_authority_check_authorization;
-  authority_class->check_authorization_finish      = polkit_backend_local_authority_check_authorization_finish;
-  authority_class->register_authentication_agent   = polkit_backend_local_authority_register_authentication_agent;
-  authority_class->unregister_authentication_agent = polkit_backend_local_authority_unregister_authentication_agent;
-  authority_class->authentication_agent_response   = polkit_backend_local_authority_authentication_agent_response;
+  interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
 
+  gobject_class->finalize                           = polkit_backend_local_authority_finalize;
+  interactive_authority_class->get_admin_identities = polkit_backend_local_authority_get_admin_auth_identities;
 
   g_type_class_add_private (klass, sizeof (PolkitBackendLocalAuthorityPrivate));
 }
 
-PolkitBackendAuthority *
-polkit_backend_local_authority_new (void)
-{
-  return POLKIT_BACKEND_AUTHORITY (g_object_new (POLKIT_BACKEND_TYPE_LOCAL_AUTHORITY,
-                                                 NULL));
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
 static GList *
-polkit_backend_local_authority_enumerate_actions (PolkitBackendAuthority   *authority,
-                                                  PolkitSubject            *caller,
-                                                  const gchar              *locale,
-                                                  GError                  **error)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-  GList *actions;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  actions = polkit_backend_action_pool_get_all_actions (priv->action_pool, locale);
-
-  return actions;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-check_authorization_challenge_cb (AuthenticationAgent         *agent,
-                                  PolkitSubject               *subject,
-                                  PolkitIdentity              *user_of_subject,
-                                  PolkitBackendLocalAuthority *authority,
-                                  const gchar                 *action_id,
-                                  PolkitImplicitAuthorization  implicit_authorization,
-                                  gboolean                     authentication_success,
-                                  gpointer                     user_data)
-{
-  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitAuthorizationResult *result;
-  gchar *subject_str;
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  result = NULL;
-  subject_str = polkit_subject_to_string (subject);
-
-  g_debug ("In check_authorization_challenge_cb\n"
-           "  subject                %s\n"
-           "  action_id              %s\n"
-           "  authentication_success %d\n",
-           subject_str,
-           action_id,
-           authentication_success);
-
-  if (authentication_success)
-    {
-      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-
-      /* store temporary authorization depending on value of implicit_authorization */
-      if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED ||
-          implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
-        {
-          temporary_authorization_store_add_authorization (priv->temporary_authorization_store,
-                                                           subject,
-                                                           action_id);
-        }
-    }
-  else
-    {
-      /* TODO: maybe return set is_challenge? */
-      result = polkit_authorization_result_new (FALSE, FALSE, NULL);
-    }
-
-  g_simple_async_result_set_op_res_gpointer (simple,
-                                             result,
-                                             g_object_unref);
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-
-  g_free (subject_str);
-}
-
-static PolkitAuthorizationResult *
-polkit_backend_local_authority_check_authorization_finish (PolkitBackendAuthority  *authority,
-                                                           GAsyncResult            *res,
-                                                           GError                 **error)
-{
-  GSimpleAsyncResult *simple;
-  PolkitAuthorizationResult *result;
-
-  simple = G_SIMPLE_ASYNC_RESULT (res);
-
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_backend_local_authority_check_authorization);
-
-  result = NULL;
-
-  if (g_simple_async_result_propagate_error (simple, error))
-    goto out;
-
-  result = g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
-
- out:
-  return result;
-}
-
-static void
-polkit_backend_local_authority_check_authorization (PolkitBackendAuthority         *authority,
-                                                    PolkitSubject                  *caller,
-                                                    PolkitSubject                  *subject,
-                                                    const gchar                    *action_id,
-                                                    PolkitDetails                  *details,
-                                                    PolkitCheckAuthorizationFlags   flags,
-                                                    GCancellable                   *cancellable,
-                                                    GAsyncReadyCallback             callback,
-                                                    gpointer                        user_data)
+polkit_backend_local_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
+                                                          PolkitSubject                     *caller,
+                                                          PolkitSubject                     *subject,
+                                                          const gchar                       *action_id,
+                                                          PolkitDetails                     *details)
 {
   PolkitBackendLocalAuthority *local_authority;
   PolkitBackendLocalAuthorityPrivate *priv;
-  gchar *caller_str;
-  gchar *subject_str;
-  PolkitIdentity *user_of_caller;
-  PolkitIdentity *user_of_subject;
-  gchar *user_of_caller_str;
-  gchar *user_of_subject_str;
-  PolkitAuthorizationResult *result;
-  PolkitImplicitAuthorization implicit_authorization;
-  GError *error;
-  GSimpleAsyncResult *simple;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  error = NULL;
-  caller_str = NULL;
-  subject_str = NULL;
-  user_of_caller = NULL;
-  user_of_subject = NULL;
-  user_of_caller_str = NULL;
-  user_of_subject_str = NULL;
-  result = NULL;
-
-  simple = g_simple_async_result_new (G_OBJECT (authority),
-                                      callback,
-                                      user_data,
-                                      polkit_backend_local_authority_check_authorization);
-
-  caller_str = polkit_subject_to_string (caller);
-  subject_str = polkit_subject_to_string (subject);
-
-  g_debug ("%s is inquiring whether %s is authorized for %s",
-           caller_str,
-           subject_str,
-           action_id);
-
-  user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
-                                                                        caller,
-                                                                        &error);
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (simple, error);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
-      g_error_free (error);
-      goto out;
-    }
-
-  user_of_caller_str = polkit_identity_to_string (user_of_caller);
-  g_debug (" user of caller is %s", user_of_caller_str);
-
-  /* we only allow trusted callers (uid 0 + others) to check authorizations */
-  if (!POLKIT_IS_UNIX_USER (user_of_caller) ||
-      polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0) /* TODO: allow other uids like 'haldaemon'? */
-    {
-      g_simple_async_result_set_error (simple,
-                                       POLKIT_ERROR,
-                                       POLKIT_ERROR_NOT_AUTHORIZED,
-                                       "Only trusted callers can use CheckAuthorization(), %s is not trusted",
-                                       user_of_caller_str);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
-      goto out;
-    }
-
-  user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
-                                                                         subject,
-                                                                         &error);
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (simple, error);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
-      g_error_free (error);
-      goto out;
-    }
-
-  user_of_subject_str = polkit_identity_to_string (user_of_subject);
-  g_debug (" user of subject is %s", user_of_subject_str);
-
-  implicit_authorization = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED;
-  result = check_authorization_sync (authority,
-                                     subject,
-                                     action_id,
-                                     flags,
-                                     &implicit_authorization,
-                                     &error);
-  if (error != NULL)
-    {
-      g_simple_async_result_set_from_error (simple, error);
-      g_simple_async_result_complete (simple);
-      g_object_unref (simple);
-      g_error_free (error);
-      goto out;
-    }
-
-  /* Caller is up for a challenge! With light sabers! Use an authentication agent if one exists... */
-  if (polkit_authorization_result_get_is_challenge (result) &&
-      (flags & POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION))
-    {
-      AuthenticationAgent *agent;
-
-      agent = get_authentication_agent_for_subject (local_authority, subject);
-      if (agent != NULL)
-        {
-          g_object_unref (result);
-          result = NULL;
-
-          g_debug (" using authentication agent for challenge");
-
-          authentication_agent_initiate_challenge (agent,
-                                                   subject,
-                                                   user_of_subject,
-                                                   local_authority,
-                                                   action_id,
-                                                   details,
-                                                   caller,
-                                                   implicit_authorization,
-                                                   cancellable,
-                                                   check_authorization_challenge_cb,
-                                                   simple);
-
-          /* keep going */
-          goto out;
-        }
-    }
-
-  /* Otherwise just return the result */
-  g_simple_async_result_set_op_res_gpointer (simple,
-                                             result,
-                                             g_object_unref);
-  g_simple_async_result_complete (simple);
-  g_object_unref (simple);
-
- out:
-
-  if (user_of_caller != NULL)
-    g_object_unref (user_of_caller);
-
-  if (user_of_subject != NULL)
-    g_object_unref (user_of_subject);
-
-  g_free (caller_str);
-  g_free (subject_str);
-  g_free (user_of_caller_str);
-  g_free (user_of_subject_str);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static PolkitAuthorizationResult *
-check_authorization_sync (PolkitBackendAuthority         *authority,
-                          PolkitSubject                  *subject,
-                          const gchar                    *action_id,
-                          PolkitCheckAuthorizationFlags   flags,
-                          PolkitImplicitAuthorization    *out_implicit_authorization,
-                          GError                        **error)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitAuthorizationResult *result;
-  PolkitIdentity *user_of_subject;
-  PolkitSubject *session_for_subject;
-  gchar *subject_str;
-  GList *groups_of_user;
-  PolkitActionDescription *action_desc;
-  gboolean session_is_local;
-  gboolean session_is_active;
-  PolkitImplicitAuthorization implicit_authorization;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  result = NULL;
-
-  user_of_subject = NULL;
-  groups_of_user = NULL;
-  subject_str = NULL;
-  session_for_subject = NULL;
-
-  session_is_local = FALSE;
-  session_is_active = FALSE;
-
-  subject_str = polkit_subject_to_string (subject);
-
-  g_debug ("checking whether %s is authorized for %s",
-           subject_str,
-           action_id);
-
-  /* get the action description */
-  action_desc = polkit_backend_action_pool_get_action (priv->action_pool,
-                                                       action_id,
-                                                       NULL);
-
-  if (action_desc == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Action %s is not registered",
-                   action_id);
-      goto out;
-    }
-
-  /* every subject has a user */
-  user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
-                                                                         subject,
-                                                                         error);
-  if (user_of_subject == NULL)
-      goto out;
-
-  /* special case: uid 0, root, is _always_ authorized for anything */
-  if (POLKIT_IS_UNIX_USER (user_of_subject) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_subject)) == 0)
-    {
-      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-      goto out;
-    }
-
-  /* a subject *may* be in a session */
-  session_for_subject = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
-                                                                                subject,
-                                                                                NULL);
-  g_debug ("  %p", session_for_subject);
-  if (session_for_subject != NULL)
-    {
-      session_is_local = polkit_backend_session_monitor_is_session_local (priv->session_monitor, session_for_subject);
-      session_is_active = polkit_backend_session_monitor_is_session_active (priv->session_monitor, session_for_subject);
-
-      g_debug (" subject is in session %s (local=%d active=%d)",
-               polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session_for_subject)),
-               session_is_local,
-               session_is_active);
-    }
-
-  /* find the implicit authorization to use; it depends on is_local and is_active */
-  if (session_is_local)
-    {
-      if (session_is_active)
-        implicit_authorization = polkit_action_description_get_implicit_active (action_desc);
-      else
-        implicit_authorization = polkit_action_description_get_implicit_inactive (action_desc);
-    }
-  else
-    {
-      implicit_authorization = polkit_action_description_get_implicit_any (action_desc);
-    }
-
-  /* first see if there's an implicit authorization for subject available */
-  if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHORIZED)
-    {
-      g_debug (" is authorized (has implicit authorization local=%d active=%d)",
-               session_is_local,
-               session_is_active);
-      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-      goto out;
-    }
-
-  /* then see if there's a temporary authorization for the subject */
-  if (temporary_authorization_store_has_authorization (priv->temporary_authorization_store,
-                                                       subject,
-                                                       action_id))
-    {
-      g_debug (" is authorized (has temporary authorization)");
-      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-      goto out;
-    }
-
-#if 0
-  /* then see if we have an authorization for the user */
-  if (check_authorization_for_identity (local_authority, user_of_subject, action_id))
-    {
-      g_debug (" is authorized (user identity has authorization)");
-      result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-      goto out;
-    }
-
-  /* then see if we have a permanent authorization for any of the groups the user is in */
-  groups_of_user = get_groups_for_user (local_authority, user_of_subject);
-  for (l = groups_of_user; l != NULL; l = l->next)
-    {
-      PolkitIdentity *group = POLKIT_IDENTITY (l->data);
-
-      if (check_authorization_for_identity (local_authority, group, action_id))
-        {
-          g_debug (" is authorized (group identity has authorization)");
-          result = polkit_authorization_result_new (TRUE, FALSE, NULL);
-          goto out;
-        }
-    }
-#endif
-
-  if (implicit_authorization != POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED)
-    {
-      result = polkit_authorization_result_new (FALSE, TRUE, NULL);
-
-      /* return implicit_authorization so the caller can use an authentication agent if applicable */
-      if (out_implicit_authorization != NULL)
-        *out_implicit_authorization = implicit_authorization;
-
-      g_debug (" challenge (implicit_authorization = %s)",
-               polkit_implicit_authorization_to_string (implicit_authorization));
-    }
-  else
-    {
-      result = polkit_authorization_result_new (FALSE, FALSE, NULL);
-      g_debug (" not authorized");
-    }
- out:
-  g_free (subject_str);
-
-  g_list_foreach (groups_of_user, (GFunc) g_object_unref, NULL);
-  g_list_free (groups_of_user);
-
-  if (user_of_subject != NULL)
-    g_object_unref (user_of_subject);
-
-  if (session_for_subject != NULL)
-    g_object_unref (session_for_subject);
-
-  if (action_desc != NULL)
-    g_object_unref (action_desc);
-
-  g_debug (" ");
-
-  return result;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-struct AuthenticationAgent
-{
-  PolkitSubject *session;
-
-  gchar *locale;
-  gchar *object_path;
-  gchar *unique_system_bus_name;
-
-  EggDBusObjectProxy *object_proxy;
-
-  GList *active_sessions;
-};
-
-struct AuthenticationSession
-{
-  AuthenticationAgent         *agent;
-
-  gchar                       *cookie;
-
-  PolkitSubject               *subject;
-
-  PolkitIdentity              *user_of_subject;
-
-  PolkitBackendLocalAuthority *authority;
-
-  GList                       *identities;
-
-  gchar                       *action_id;
-
-  gchar                       *initiated_by_system_bus_unique_name;
-
-  PolkitImplicitAuthorization  implicit_authorization;
-
-  AuthenticationAgentCallback  callback;
-
-  gpointer                     user_data;
-
-  guint                        call_id;
-
-  gboolean                     is_authenticated;
-
-  GCancellable                *cancellable;
-
-  gulong                       cancellable_signal_handler_id;
-};
-
-static void
-authentication_session_cancelled_cb (GCancellable *cancellable,
-                                     AuthenticationSession *session)
-{
-  authentication_session_cancel (session);
-}
-
-static AuthenticationSession *
-authentication_session_new (AuthenticationAgent         *agent,
-                            const gchar                 *cookie,
-                            PolkitSubject               *subject,
-                            PolkitIdentity              *user_of_subject,
-                            PolkitBackendLocalAuthority *authority,
-                            GList                       *identities,
-                            const gchar                 *action_id,
-                            const gchar                 *initiated_by_system_bus_unique_name,
-                            PolkitImplicitAuthorization  implicit_authorization,
-                            GCancellable                *cancellable,
-                            AuthenticationAgentCallback  callback,
-                            gpointer                     user_data)
-{
-  AuthenticationSession *session;
-
-  session = g_new0 (AuthenticationSession, 1);
-  session->agent = agent;
-  session->cookie = g_strdup (cookie);
-  session->subject = g_object_ref (subject);
-  session->user_of_subject = g_object_ref (user_of_subject);
-  session->authority = g_object_ref (authority);
-  session->identities = g_list_copy (identities);
-  g_list_foreach (session->identities, (GFunc) g_object_ref, NULL);
-  session->action_id = g_strdup (action_id);
-  session->initiated_by_system_bus_unique_name = g_strdup (initiated_by_system_bus_unique_name);
-  session->implicit_authorization = implicit_authorization;
-  session->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
-  session->callback = callback;
-  session->user_data = user_data;
-
-  if (session->cancellable != NULL)
-    {
-      session->cancellable_signal_handler_id = g_signal_connect (session->cancellable,
-                                                                 "cancelled",
-                                                                 G_CALLBACK (authentication_session_cancelled_cb),
-                                                                 session);
-    }
-
-  return session;
-}
-
-static void
-authentication_session_free (AuthenticationSession *session)
-{
-  g_free (session->cookie);
-  g_list_foreach (session->identities, (GFunc) g_object_unref, NULL);
-  g_list_free (session->identities);
-  g_object_unref (session->subject);
-  g_object_unref (session->user_of_subject);
-  g_object_unref (session->authority);
-  g_free (session->action_id);
-  g_free (session->initiated_by_system_bus_unique_name);
-  if (session->cancellable_signal_handler_id > 0)
-    g_signal_handler_disconnect (session->cancellable, session->cancellable_signal_handler_id);
-  if (session->cancellable != NULL)
-    g_object_unref (session->cancellable);
-  g_free (session);
-}
-
-static gchar *
-authentication_agent_new_cookie (AuthenticationAgent *agent)
-{
-  static gint counter = 0;
-
-  /* TODO: use a more random-looking cookie */
-
-  return g_strdup_printf ("cookie%d", counter++);
-}
-
-static void
-authentication_agent_free (AuthenticationAgent *agent)
-{
-  /* cancel all active authentication sessions; use a copy of the list since
-   * callbacks will modify the list
-   */
-  if (agent->active_sessions != NULL)
-    {
-      GList *l;
-      GList *active_sessions;
-
-      active_sessions = g_list_copy (agent->active_sessions);
-      for (l = active_sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          authentication_session_cancel (session);
-        }
-      g_list_free (active_sessions);
-    }
-
-  g_object_unref (agent->object_proxy);
-
-  g_object_unref (agent->session);
-  g_free (agent->locale);
-  g_free (agent->object_path);
-  g_free (agent->unique_system_bus_name);
-  g_free (agent);
-}
-
-static AuthenticationAgent *
-authentication_agent_new (PolkitSubject *session,
-                          const gchar *unique_system_bus_name,
-                          const gchar *locale,
-                          const gchar *object_path)
-{
-  AuthenticationAgent *agent;
-  EggDBusConnection *system_bus;
-
-  agent = g_new0 (AuthenticationAgent, 1);
-
-  agent->session = g_object_ref (session);
-  agent->object_path = g_strdup (object_path);
-  agent->unique_system_bus_name = g_strdup (unique_system_bus_name);
-  agent->locale = g_strdup (locale);
-
-  system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
-
-  agent->object_proxy = egg_dbus_connection_get_object_proxy (system_bus,
-                                                              agent->unique_system_bus_name,
-                                                              agent->object_path);
-
-  g_object_unref (system_bus);
-
-  return agent;
-}
-
-static AuthenticationAgent *
-get_authentication_agent_for_subject (PolkitBackendLocalAuthority *authority,
-                                      PolkitSubject *subject)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitSubject *session_for_subject;
-  AuthenticationAgent *agent;
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  agent = NULL;
-  session_for_subject = NULL;
-
-  session_for_subject = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
-                                                                                subject,
-                                                                                NULL);
-  if (session_for_subject == NULL)
-    goto out;
-
-  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_subject);
-
- out:
-  if (session_for_subject != NULL)
-    g_object_unref (session_for_subject);
-
-  return agent;
-}
-
-static AuthenticationSession *
-get_authentication_session_for_cookie (PolkitBackendLocalAuthority *authority,
-                                       const gchar *cookie)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  GHashTableIter hash_iter;
-  AuthenticationAgent *agent;
-  AuthenticationSession *result;
-
-  result = NULL;
-
-  /* TODO: perhaps use a hash on the cookie to speed this up */
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
-  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
-    {
-      GList *l;
-
-      for (l = agent->active_sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          if (strcmp (session->cookie, cookie) == 0)
-            {
-              result = session;
-              goto out;
-            }
-        }
-    }
-
- out:
-  return result;
-}
-
-static GList *
-get_authentication_sessions_initiated_by_system_bus_unique_name (PolkitBackendLocalAuthority *authority,
-                                                                 const gchar *system_bus_unique_name)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  GHashTableIter hash_iter;
-  AuthenticationAgent *agent;
-  GList *result;
-
-  result = NULL;
-
-  /* TODO: perhaps use a hash on the cookie to speed this up */
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
-  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
-    {
-      GList *l;
-
-      for (l = agent->active_sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          if (strcmp (session->initiated_by_system_bus_unique_name, system_bus_unique_name) == 0)
-            {
-              result = g_list_prepend (result, session);
-            }
-        }
-    }
-
-   return result;
-}
-
-static GList *
-get_authentication_sessions_for_system_bus_unique_name_subject (PolkitBackendLocalAuthority *authority,
-                                                                const gchar *system_bus_unique_name)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  GHashTableIter hash_iter;
-  AuthenticationAgent *agent;
-  GList *result;
-
-  result = NULL;
-
-  /* TODO: perhaps use a hash on the cookie to speed this up */
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
-  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
-    {
-      GList *l;
-
-      for (l = agent->active_sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          if (POLKIT_IS_SYSTEM_BUS_NAME (session->subject) &&
-              strcmp (polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (session->subject)),
-                      system_bus_unique_name) == 0)
-            {
-              result = g_list_prepend (result, session);
-            }
-        }
-    }
-
-   return result;
-}
-
-
-static AuthenticationAgent *
-get_authentication_agent_by_unique_system_bus_name (PolkitBackendLocalAuthority *authority,
-                                                    const gchar *unique_system_bus_name)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  GHashTableIter hash_iter;
-  AuthenticationAgent *agent;
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  g_hash_table_iter_init (&hash_iter, priv->hash_session_to_authentication_agent);
-  while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &agent))
-    {
-      if (strcmp (agent->unique_system_bus_name, unique_system_bus_name) == 0)
-        goto out;
-    }
-
-  agent = NULL;
-
-  out:
-  return agent;
-}
-
-static void
-authentication_agent_begin_callback (GObject *source_object,
-                                     GAsyncResult *res,
-                                     gpointer user_data)
-{
-  _PolkitAuthenticationAgent *agent_dbus = _POLKIT_AUTHENTICATION_AGENT (source_object);
-  AuthenticationSession *session = user_data;
-  GError *error;
-  gboolean gained_authorization;
-
-  error = NULL;
-  if (!_polkit_authentication_agent_begin_authentication_finish (agent_dbus,
-                                                                 res,
-                                                                 &error))
-    {
-      g_warning ("Error performing authentication: %s", error->message);
-      g_error_free (error);
-      gained_authorization = FALSE;
-    }
-  else
-    {
-      gained_authorization = session->is_authenticated;
-
-      g_debug ("Authentication complete, is_authenticated = %d", session->is_authenticated);
-    }
-
-  session->agent->active_sessions = g_list_remove (session->agent->active_sessions, session);
-
-  session->callback (session->agent,
-                     session->subject,
-                     session->user_of_subject,
-                     session->authority,
-                     session->action_id,
-                     session->implicit_authorization,
-                     gained_authorization,
-                     session->user_data);
-
-  authentication_session_free (session);
-}
-
-static GList *
-get_admin_auth_identities (PolkitBackendLocalAuthority *authority)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
   GList *ret;
   guint n;
   gchar **admin_identities;
   GError *error;
 
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
+  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
 
   ret = NULL;
 
@@ -1174,699 +194,10 @@ get_admin_auth_identities (PolkitBackendLocalAuthority *authority)
   return ret;
 }
 
-static GList *
-get_action_lookup_list (void)
-{
-  GList *extensions;
-  GList *l;
-  GIOExtensionPoint *action_lookup_ep;
-  static GList *action_lookup_list = NULL;
-  static gboolean have_looked_up_extensions = FALSE;
-
-  if (have_looked_up_extensions)
-    goto out;
-
-  action_lookup_ep = g_io_extension_point_lookup (POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME);
-  g_assert (action_lookup_ep != NULL);
-
-  extensions = g_io_extension_point_get_extensions (action_lookup_ep);
-  for (l = extensions; l != NULL; l = l->next)
-    {
-      GIOExtension *extension = l->data;
-      PolkitBackendActionLookup *lookup;
-
-      lookup = g_object_new (g_io_extension_get_type (extension), NULL);
-      action_lookup_list = g_list_prepend (action_lookup_list, lookup);
-    }
-  action_lookup_list = g_list_reverse (action_lookup_list);
-
- out:
-  have_looked_up_extensions = TRUE;
-  return action_lookup_list;
-}
-
-static void
-get_localized_data_for_challenge (PolkitBackendLocalAuthority *authority,
-                                  PolkitSubject               *caller,
-                                  PolkitSubject               *subject,
-                                  PolkitIdentity              *user_of_subject,
-                                  const gchar                 *action_id,
-                                  PolkitDetails               *details,
-                                  const gchar                 *locale,
-                                  gchar                      **out_localized_message,
-                                  gchar                      **out_localized_icon_name,
-                                  EggDBusHashMap             **out_localized_details)
-{
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitActionDescription *action_desc;
-  GList *action_lookup_list;
-  GList *l;
-  gchar *message;
-  gchar *icon_name;
-  PolkitDetails *localized_details;
-
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
-
-  message = NULL;
-  icon_name = NULL;
-  localized_details = NULL;
-  action_desc = NULL;
-
-  *out_localized_message = NULL;
-  *out_localized_icon_name = NULL;
-  *out_localized_details = egg_dbus_hash_map_new (G_TYPE_STRING, NULL,
-                                                  G_TYPE_STRING, NULL);
-
-  action_desc = polkit_backend_action_pool_get_action (priv->action_pool,
-                                                       action_id,
-                                                       locale);
-  if (action_desc == NULL)
-    goto out;
-
-  /* Set LANG and locale so gettext() + friends work when running the code in the extensions */
-  if (setlocale (LC_ALL, locale) == NULL)
-    {
-      g_warning ("Invalid locale '%s'", locale);
-    }
-  g_setenv ("LANG", locale, TRUE);
-
-  /* call into extension points to get localized auth dialog data - the list is sorted by priority */
-  action_lookup_list = get_action_lookup_list ();
-  for (l = action_lookup_list; l != NULL; l = l->next)
-    {
-      PolkitBackendActionLookup *lookup = POLKIT_BACKEND_ACTION_LOOKUP (l->data);
-
-      if (message != NULL && icon_name != NULL && localized_details != NULL)
-        break;
-
-      if (message == NULL)
-        message = polkit_backend_action_lookup_get_message (lookup,
-                                                            action_id,
-                                                            details,
-                                                            action_desc);
-
-      if (icon_name == NULL)
-        icon_name = polkit_backend_action_lookup_get_icon_name (lookup,
-                                                                action_id,
-                                                                details,
-                                                                action_desc);
-
-      if (localized_details == NULL)
-        localized_details = polkit_backend_action_lookup_get_details (lookup,
-                                                                      action_id,
-                                                                      details,
-                                                                      action_desc);
-    }
-
-  /* Back to C! */
-  setlocale (LC_ALL, "C");
-  g_setenv ("LANG", "C", TRUE);
-
-  /* fall back to action description */
-  if (message == NULL)
-    {
-      message = g_strdup (polkit_action_description_get_message (action_desc));
-    }
-  if (icon_name == NULL)
-    {
-      icon_name = g_strdup (polkit_action_description_get_icon_name (action_desc));
-    }
-
-
-  if (localized_details != NULL)
-    {
-      GHashTable *hash;
-      GHashTableIter iter;
-      const gchar *key;
-      const gchar *value;
-
-      hash = polkit_details_get_hash (localized_details);
-      if (hash != NULL)
-        {
-          g_hash_table_iter_init (&iter, hash);
-          while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &value))
-            {
-              egg_dbus_hash_map_insert (*out_localized_details, key, value);
-            }
-        }
-    }
-
- out:
-  if (message == NULL)
-    message = g_strdup ("");
-  if (icon_name == NULL)
-    icon_name = g_strdup ("");
-  *out_localized_message = message;
-  *out_localized_icon_name = icon_name;
-  if (action_desc != NULL)
-    g_object_unref (action_desc);
-}
-
-static void
-authentication_agent_initiate_challenge (AuthenticationAgent         *agent,
-                                         PolkitSubject               *subject,
-                                         PolkitIdentity              *user_of_subject,
-                                         PolkitBackendLocalAuthority *authority,
-                                         const gchar                 *action_id,
-                                         PolkitDetails               *details,
-                                         PolkitSubject               *caller,
-                                         PolkitImplicitAuthorization  implicit_authorization,
-                                         GCancellable                *cancellable,
-                                         AuthenticationAgentCallback  callback,
-                                         gpointer                     user_data)
-{
-  AuthenticationSession *session;
-  _PolkitAuthenticationAgent *agent_dbus;
-  gchar *cookie;
-  GList *l;
-  GList *identities;
-  EggDBusArraySeq *real_identities;
-  gchar *localized_message;
-  gchar *localized_icon_name;
-  EggDBusHashMap *localized_details;
-
-  get_localized_data_for_challenge (authority,
-                                    caller,
-                                    subject,
-                                    user_of_subject,
-                                    action_id,
-                                    details,
-                                    agent->locale,
-                                    &localized_message,
-                                    &localized_icon_name,
-                                    &localized_details);
-
-  cookie = authentication_agent_new_cookie (agent);
-
-  identities = NULL;
-
-  /* select admin user if required by the implicit authorization */
-  if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED ||
-      implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
-    {
-      identities = get_admin_auth_identities (authority);
-    }
-  else
-    {
-      identities = g_list_prepend (identities, g_object_ref (user_of_subject));
-    }
-
-  session = authentication_session_new (agent,
-                                        cookie,
-                                        subject,
-                                        user_of_subject,
-                                        authority,
-                                        identities,
-                                        action_id,
-                                        polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
-                                        implicit_authorization,
-                                        cancellable,
-                                        callback,
-                                        user_data);
-
-  agent->active_sessions = g_list_prepend (agent->active_sessions, session);
-
-  agent_dbus = _POLKIT_QUERY_INTERFACE_AUTHENTICATION_AGENT (agent->object_proxy);
-
-  real_identities = egg_dbus_array_seq_new (EGG_DBUS_TYPE_STRUCTURE, g_object_unref, NULL, NULL);
-  for (l = identities; l != NULL; l = l->next)
-    {
-      PolkitIdentity *identity = POLKIT_IDENTITY (l->data);
-      egg_dbus_array_seq_add (real_identities, polkit_identity_get_real (identity));
-    }
-
-  session->call_id = _polkit_authentication_agent_begin_authentication (agent_dbus,
-                                                                        EGG_DBUS_CALL_FLAGS_TIMEOUT_NONE,
-                                                                        action_id,
-                                                                        localized_message,
-                                                                        localized_icon_name,
-                                                                        localized_details,
-                                                                        session->cookie,
-                                                                        real_identities,
-                                                                        NULL,
-                                                                        authentication_agent_begin_callback,
-                                                                        session);
-
-  g_list_foreach (identities, (GFunc) g_object_unref, NULL);
-  g_list_free (identities);
-  g_object_unref (real_identities);
-  g_free (cookie);
-
-  g_free (localized_message);
-  g_free (localized_icon_name);
-  g_object_unref (localized_details);
-}
-
-static void
-authentication_agent_cancel_callback (GObject *source_object,
-                                      GAsyncResult *res,
-                                      gpointer user_data)
-{
-  _PolkitAuthenticationAgent *agent_dbus = _POLKIT_AUTHENTICATION_AGENT (source_object);
-
-  _polkit_authentication_agent_cancel_authentication_finish (agent_dbus,
-                                                             res,
-                                                             NULL);
-}
-
-static void
-authentication_session_cancel (AuthenticationSession *session)
-{
-  EggDBusConnection *system_bus;
-  _PolkitAuthenticationAgent *agent_dbus;
-
-  system_bus = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
-
-  agent_dbus = _POLKIT_QUERY_INTERFACE_AUTHENTICATION_AGENT (session->agent->object_proxy);
-
-  _polkit_authentication_agent_cancel_authentication (agent_dbus,
-                                                      EGG_DBUS_CALL_FLAGS_NONE,
-                                                      session->cookie,
-                                                      NULL,
-                                                      authentication_agent_cancel_callback,
-                                                      NULL);
-
-  egg_dbus_connection_pending_call_cancel (system_bus, session->call_id);
-
-  g_object_unref (system_bus);
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-polkit_backend_local_authority_register_authentication_agent (PolkitBackendAuthority   *authority,
-                                                              PolkitSubject            *caller,
-                                                              const gchar              *session_id,
-                                                              const gchar              *locale,
-                                                              const gchar              *object_path,
-                                                              GError                  **error)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitSubject *session_for_caller;
-  AuthenticationAgent *agent;
-  gboolean ret;
-
-  session_for_caller = NULL;
-  ret = FALSE;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  if (session_id != NULL && strlen (session_id) > 0)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "The session_id parameter must be blank for now.");
-      goto out;
-    }
-
-  session_for_caller = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
-                                                                               caller,
-                                                                               NULL);
-  if (session_for_caller == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Cannot determine session");
-      goto out;
-    }
-
-  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_caller);
-  if (agent != NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "An authentication agent already exists for session");
-      goto out;
-    }
-
-  /* TODO: validate that object path is well-formed */
-
-  agent = authentication_agent_new (session_for_caller,
-                                    polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
-                                    locale,
-                                    object_path);
-
-  g_hash_table_insert (priv->hash_session_to_authentication_agent,
-                       g_object_ref (session_for_caller),
-                       agent);
-
-  g_debug ("Added authentication agent for session %s at name %s, object path %s, locale %s",
-           polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session_for_caller)),
-           polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
-           object_path,
-           locale);
-
-  ret = TRUE;
-
- out:
-  if (session_for_caller != NULL)
-    g_object_unref (session_for_caller);
-
-  return ret;
-}
-
-static gboolean
-polkit_backend_local_authority_unregister_authentication_agent (PolkitBackendAuthority   *authority,
-                                                                PolkitSubject            *caller,
-                                                                const gchar              *session_id,
-                                                                const gchar              *object_path,
-                                                                GError                  **error)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitSubject *session_for_caller;
-  AuthenticationAgent *agent;
-  gboolean ret;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  ret = FALSE;
-  session_for_caller = NULL;
-
-  if (session_id != NULL && strlen (session_id) > 0)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "The session_id parameter must be blank for now.");
-      goto out;
-    }
-
-  session_for_caller = polkit_backend_session_monitor_get_session_for_subject (priv->session_monitor,
-                                                                               caller,
-                                                                               NULL);
-  if (session_for_caller == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Cannot determine session");
-      goto out;
-    }
-
-  agent = g_hash_table_lookup (priv->hash_session_to_authentication_agent, session_for_caller);
-  if (agent == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "No such agent registered");
-      goto out;
-    }
-
-  if (strcmp (agent->unique_system_bus_name,
-              polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller))) != 0)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "System bus names do not match");
-      goto out;
-    }
-
-  if (strcmp (agent->object_path, object_path) != 0)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Object paths do not match");
-      goto out;
-    }
-
-
-  g_debug ("Removing authentication agent for session %s at name %s, object path %s (unregistered)",
-           polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (agent->session)),
-           agent->unique_system_bus_name,
-           agent->object_path);
-
-  /* this works because we have exactly one agent per session */
-  g_hash_table_remove (priv->hash_session_to_authentication_agent, agent->session);
-
-  ret = TRUE;
-
- out:
-  if (session_for_caller != NULL)
-    g_object_unref (session_for_caller);
-  return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static gboolean
-polkit_backend_local_authority_authentication_agent_response (PolkitBackendAuthority   *authority,
-                                                              PolkitSubject            *caller,
-                                                              const gchar              *cookie,
-                                                              PolkitIdentity           *identity,
-                                                              GError                  **error)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-  PolkitIdentity *user_of_caller;
-  gchar *identity_str;
-  AuthenticationSession *session;
-  GList *l;
-  gboolean ret;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  ret = FALSE;
-  user_of_caller = NULL;
-
-  identity_str = polkit_identity_to_string (identity);
-
-  g_debug ("In authentication_agent_response for cookie '%s' and identity %s",
-           cookie,
-           identity_str);
-
-  user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
-                                                                        caller,
-                                                                        error);
-  if (user_of_caller == NULL)
-    goto out;
-
-  /* only uid 0 is allowed to invoke this method */
-  if (!POLKIT_IS_UNIX_USER (user_of_caller) || polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "Only uid 0 may invoke this method. This incident has been logged.");
-      /* TODO: actually log this */
-      goto out;
-    }
-
-  /* find the authentication session */
-  session = get_authentication_session_for_cookie (local_authority, cookie);
-  if (session == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "No session for cookie");
-      goto out;
-    }
-
-  /* check that the authentication identity was one of the possibilities we allowed */
-  for (l = session->identities; l != NULL; l = l->next)
-    {
-      PolkitIdentity *i = POLKIT_IDENTITY (l->data);
-
-      if (polkit_identity_equal (i, identity))
-        break;
-    }
-
-  if (l == NULL)
-    {
-      g_set_error (error,
-                   POLKIT_ERROR,
-                   POLKIT_ERROR_FAILED,
-                   "The authenticated identity is wrong");
-      goto out;
-    }
-
-  /* checks out, mark the session as authenticated */
-  session->is_authenticated = TRUE;
-
-  ret = TRUE;
-
- out:
-  g_free (identity_str);
-
-  if (user_of_caller != NULL)
-    g_object_unref (user_of_caller);
-
-  return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-polkit_backend_local_authority_system_bus_name_owner_changed (PolkitBackendAuthority   *authority,
-                                                              const gchar              *name,
-                                                              const gchar              *old_owner,
-                                                              const gchar              *new_owner)
-{
-  PolkitBackendLocalAuthority *local_authority;
-  PolkitBackendLocalAuthorityPrivate *priv;
-
-  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (authority);
-  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
-
-  //g_debug ("name-owner-changed: '%s' '%s' '%s'", name, old_owner, new_owner);
-
-  if (name[0] == ':' && strlen (new_owner) == 0)
-    {
-      AuthenticationAgent *agent;
-      GList *sessions;
-      GList *l;
-
-      agent = get_authentication_agent_by_unique_system_bus_name (local_authority, name);
-      if (agent != NULL)
-        {
-          g_debug ("Removing authentication agent for session %s at name %s, object path %s (disconnected from bus)",
-                   polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (agent->session)),
-                   agent->unique_system_bus_name,
-                   agent->object_path);
-
-          /* this works because we have exactly one agent per session */
-          g_hash_table_remove (priv->hash_session_to_authentication_agent, agent->session);
-        }
-
-      /* cancel all authentication sessions initiated by the process owning the vanished name */
-      sessions = get_authentication_sessions_initiated_by_system_bus_unique_name (local_authority, name);
-      for (l = sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          authentication_session_cancel (session);
-        }
-      g_list_free (sessions);
-
-      /* cancel all authentication sessions that is about the vanished name */
-      sessions = get_authentication_sessions_for_system_bus_unique_name_subject (local_authority, name);
-      for (l = sessions; l != NULL; l = l->next)
-        {
-          AuthenticationSession *session = l->data;
-
-          authentication_session_cancel (session);
-        }
-      g_list_free (sessions);
-
-    }
-
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-typedef struct TemporaryAuthorization TemporaryAuthorization;
-
-struct TemporaryAuthorizationStore
-{
-  GList *authorizations;
-};
-
-struct TemporaryAuthorization
-{
-  PolkitSubject *subject;
-  gchar *action_id;
-  guint64 time_granted;
-};
-
-static void
-temporary_authorization_free (TemporaryAuthorization *authorization)
-{
-  g_object_unref (authorization->subject);
-  g_free (authorization->action_id);
-  g_free (authorization);
-}
-
-static TemporaryAuthorization *
-temporary_authorization_new (PolkitSubject *subject,
-                             const gchar   *action_id)
-{
-  TemporaryAuthorization *authorization;
-
-  authorization = g_new0 (TemporaryAuthorization, 1);
-  authorization->subject = g_object_ref (subject);
-  authorization->action_id = g_strdup (action_id);
-  authorization->time_granted = time (NULL);
-
-  return authorization;
-}
-
-static TemporaryAuthorizationStore *
-temporary_authorization_store_new (void)
-{
-  TemporaryAuthorizationStore *store;
-
-  store = g_new0 (TemporaryAuthorizationStore, 1);
-  store->authorizations = NULL;
-
-  return store;
-}
-
-static void
-temporary_authorization_store_free (TemporaryAuthorizationStore *store)
-{
-  g_list_foreach (store->authorizations, (GFunc) temporary_authorization_free, NULL);
-  g_list_free (store->authorizations);
-  g_free (store);
-}
-
-static gboolean
-temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
-                                                 PolkitSubject               *subject,
-                                                 const gchar                 *action_id)
-{
-  GList *l;
-  gboolean ret;
-
-  g_return_val_if_fail (store != NULL, FALSE);
-  g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), FALSE);
-  g_return_val_if_fail (action_id != NULL, FALSE);
-
-  ret = FALSE;
-
-  for (l = store->authorizations; l != NULL; l = l->next) {
-    TemporaryAuthorization *authorization = l->data;
-
-    if (strcmp (action_id, authorization->action_id) == 0 &&
-        polkit_subject_equal (subject, authorization->subject))
-      {
-        ret = TRUE;
-        goto out;
-      }
-  }
-
- out:
-  return ret;
-}
-
-static void
-temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
-                                                 PolkitSubject               *subject,
-                                                 const gchar                 *action_id)
-{
-  g_return_if_fail (store != NULL);
-  g_return_if_fail (POLKIT_IS_SUBJECT (subject));
-  g_return_if_fail (action_id != NULL);
-  g_return_if_fail (!temporary_authorization_store_has_authorization (store, subject, action_id));
-
-  store->authorizations = g_list_prepend (store->authorizations,
-                                          temporary_authorization_new (subject, action_id));
-}
-
 /* ---------------------------------------------------------------------------------------------------- */
 
 static GList *
-get_users_in_group (PolkitBackendLocalAuthority *authority,
+get_users_in_group (PolkitBackendInteractiveAuthority *authority,
                     PolkitIdentity              *group,
                     gboolean                     include_root)
 {
@@ -1914,7 +245,7 @@ get_users_in_group (PolkitBackendLocalAuthority *authority,
 
 #if 0
 static GList *
-get_groups_for_user (PolkitBackendLocalAuthority *authority,
+get_groups_for_user (PolkitBackendInteractiveAuthority *authority,
                      PolkitIdentity              *user)
 {
   uid_t uid;
diff --git a/src/polkitbackend/polkitbackendlocalauthority.h b/src/polkitbackend/polkitbackendlocalauthority.h
index be0232f..553da3b 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.h
+++ b/src/polkitbackend/polkitbackendlocalauthority.h
@@ -28,7 +28,7 @@
 
 #include <glib-object.h>
 #include <polkitbackend/polkitbackendtypes.h>
-#include <polkitbackend/polkitbackendauthority.h>
+#include <polkitbackend/polkitbackendinteractiveauthority.h>
 
 G_BEGIN_DECLS
 
@@ -49,7 +49,7 @@ typedef struct _PolkitBackendLocalAuthorityClass    PolkitBackendLocalAuthorityC
 struct _PolkitBackendLocalAuthority
 {
   /*< private >*/
-  PolkitBackendAuthority parent_instance;
+  PolkitBackendInteractiveAuthority parent_instance;
 };
 
 /**
@@ -61,7 +61,7 @@ struct _PolkitBackendLocalAuthority
 struct _PolkitBackendLocalAuthorityClass
 {
   /*< public >*/
-  PolkitBackendAuthorityClass parent_class;
+  PolkitBackendInteractiveAuthorityClass parent_class;
 
   /*< private >*/
   /* Padding for future expansion */
@@ -73,10 +73,33 @@ struct _PolkitBackendLocalAuthorityClass
   void (*_polkit_reserved6) (void);
   void (*_polkit_reserved7) (void);
   void (*_polkit_reserved8) (void);
+  void (*_polkit_reserved9) (void);
+  void (*_polkit_reserved10) (void);
+  void (*_polkit_reserved11) (void);
+  void (*_polkit_reserved12) (void);
+  void (*_polkit_reserved13) (void);
+  void (*_polkit_reserved14) (void);
+  void (*_polkit_reserved15) (void);
+  void (*_polkit_reserved16) (void);
+  void (*_polkit_reserved17) (void);
+  void (*_polkit_reserved18) (void);
+  void (*_polkit_reserved19) (void);
+  void (*_polkit_reserved20) (void);
+  void (*_polkit_reserved21) (void);
+  void (*_polkit_reserved22) (void);
+  void (*_polkit_reserved23) (void);
+  void (*_polkit_reserved24) (void);
+  void (*_polkit_reserved25) (void);
+  void (*_polkit_reserved26) (void);
+  void (*_polkit_reserved27) (void);
+  void (*_polkit_reserved28) (void);
+  void (*_polkit_reserved29) (void);
+  void (*_polkit_reserved30) (void);
+  void (*_polkit_reserved31) (void);
+  void (*_polkit_reserved32) (void);
 };
 
 GType                   polkit_backend_local_authority_get_type (void) G_GNUC_CONST;
-PolkitBackendAuthority *polkit_backend_local_authority_new      (void);
 
 G_END_DECLS
 
diff --git a/src/polkitbackend/polkitbackendtypes.h b/src/polkitbackend/polkitbackendtypes.h
index e0906df..e130d16 100644
--- a/src/polkitbackend/polkitbackendtypes.h
+++ b/src/polkitbackend/polkitbackendtypes.h
@@ -24,9 +24,6 @@
 
 #include <glib-object.h>
 
-struct _PolkitBackendAuthority;
-typedef struct _PolkitBackendAuthority PolkitBackendAuthority;
-
 struct _PolkitBackendSessionMonitor;
 typedef struct _PolkitBackendSessionMonitor PolkitBackendSessionMonitor;
 
@@ -36,6 +33,12 @@ typedef struct _PolkitBackendConfigSource PolkitBackendConfigSource;
 struct _PolkitBackendActionLookup;
 typedef struct _PolkitBackendActionLookup PolkitBackendActionLookup; /* Dummy typedef */
 
+struct _PolkitBackendAuthority;
+typedef struct _PolkitBackendAuthority PolkitBackendAuthority;
+
+struct _PolkitBackendInteractiveAuthority;
+typedef struct _PolkitBackendInteractiveAuthority PolkitBackendInteractiveAuthority;
+
 struct _PolkitBackendLocalAuthority;
 typedef struct _PolkitBackendLocalAuthority PolkitBackendLocalAuthority;
 


More information about the hal-commit mailing list