PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Mon Jul 20 15:53:40 PDT 2009


 data/org.freedesktop.PolicyKit1.Authority.xml         |   70 ++
 docs/polkit/polkit-1-docs.xml                         |    1 
 docs/polkit/polkit-1-sections.txt                     |   34 +
 docs/polkit/polkit-1.types                            |    1 
 src/polkit/Makefile.am                                |    4 
 src/polkit/polkit.h                                   |    1 
 src/polkit/polkitactiondescription.c                  |    2 
 src/polkit/polkitauthority.c                          |  235 +++++++++
 src/polkit/polkitauthority.h                          |   38 +
 src/polkit/polkitprivate.h                            |    3 
 src/polkit/polkitsubject.c                            |   68 ++
 src/polkit/polkitsubject.h                            |   48 +-
 src/polkit/polkitsystembusname.c                      |  154 ++++++
 src/polkit/polkittemporaryauthorization.c             |  211 ++++++++
 src/polkit/polkittemporaryauthorization.h             |   61 ++
 src/polkit/polkittypes.h                              |    3 
 src/polkit/polkitunixprocess.c                        |  189 ++++---
 src/polkit/polkitunixsession.c                        |  432 +++++++++++++++++-
 src/polkit/polkitunixsession.h                        |   19 
 src/polkitagent/polkitagentlistener.c                 |   18 
 src/polkitagent/polkitagentlistener.h                 |   10 
 src/polkitbackend/polkitbackendauthority.c            |  210 ++++++++
 src/polkitbackend/polkitbackendauthority.h            |   36 +
 src/polkitbackend/polkitbackendinteractiveauthority.c |  321 +++++++++++--
 24 files changed, 1958 insertions(+), 211 deletions(-)

New commits:
commit 36fc7a6d358c1d373c181191da6265a538a71dae
Author: David Zeuthen <davidz at redhat.com>
Date:   Mon Jul 20 18:49:25 2009 -0400

    Add support for querying and revoking temporary authorizations
    
    Also change how authentication agents are registered (take a Subject
    instead of the session-id) and add convenience functions to
    asynchronously construct a PolkitUnixSession object given a process id
    (by querying ConsoleKit).

diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
index ed4e57a..6b29e8e 100644
--- a/data/org.freedesktop.PolicyKit1.Authority.xml
+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
@@ -30,7 +30,7 @@
 
     <!-- Identity struct -->
     <annotation name="org.gtk.EggDBus.DeclareStruct" value="Identity">
-      <annotation name="org.gtk.EggDBus.DocString.Summary" value="Subjects"/>
+      <annotation name="org.gtk.EggDBus.DocString.Summary" value="Identities"/>
       <annotation name="org.gtk.EggDBus.DocString" value="<para>This struct describes identities such as UNIX users and UNIX groups. It is typically used to check if a given process is authorized for an action.</para><para>The following kinds of identities are known:</para>
                   <formalpara><title>Unix User</title><para><literal>identity_kind</literal> should be set to <literal>unix-user</literal> with key <literal>uid</literal> (of type <literal>uint32</literal>).</para></formalpara>
                   <formalpara><title>Unix Group</title><para><literal>identity_kind</literal> should be set to <literal>unix-group</literal> with key <literal>gid</literal> (of type <literal>uint32</literal>).</para></formalpara>
@@ -254,8 +254,9 @@
     <method name="RegisterAuthenticationAgent">
       <annotation name="org.gtk.EggDBus.DocString" value="<para>Register an authentication agent.</para><para>Note that current versions of PolicyKit will only work if @session_id is set to the empty string. In the future it might work for non-empty strings if the caller is sufficiently privileged.</para>"/>
 
-      <arg name="session_id" direction="in" type="s">
-        <annotation name="org.gtk.EggDBus.DocString" value="The session to register the authentication for or blank for the session the caller of the method is in."/>
+      <arg name="subject" direction="in" type="(sa{sv})">
+        <annotation name="org.gtk.EggDBus.Type" value="Subject"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The subject to register the authentication agent for, typically a session subject."/>
       </arg>
 
       <arg name="locale" direction="in" type="s">
@@ -270,12 +271,13 @@
     <method name="UnregisterAuthenticationAgent">
       <annotation name="org.gtk.EggDBus.DocString" value="Unregister an authentication agent."/>
 
-      <arg name="session_id" direction="in" type="s">
-        <annotation name="org.gtk.EggDBus.DocString" value="The session identifier passed to org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/>
+      <arg name="subject" direction="in" type="(sa{sv})">
+        <annotation name="org.gtk.EggDBus.Type" value="Subject"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The @subject passed to org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/>
       </arg>
 
       <arg name="object_path" direction="in" type="s">
-        <annotation name="org.gtk.EggDBus.DocString" value="The object path of authentication agent object on the unique name of the caller."/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The @object_path passed to org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/>
       </arg>
     </method>
 
@@ -292,6 +294,62 @@
       </arg>
     </method>
 
+    <!-- ---------------------------------------------------------------------------------------------------- -->
+
+    <!-- TemporaryAuthorization struct -->
+    <annotation name="org.gtk.EggDBus.DeclareStruct" value="TemporaryAuthorization">
+      <annotation name="org.gtk.EggDBus.DocString.Summary" value="Temporary Authorizations"/>
+      <annotation name="org.gtk.EggDBus.DocString" value="This struct describes a temporary authorization."/>
+
+      <annotation name="org.gtk.EggDBus.Struct.Member"  value="String:id">
+        <annotation name="org.gtk.EggDBus.DocString" value="An opaque identifier for the temporary authorization."/>
+      </annotation>
+
+      <annotation name="org.gtk.EggDBus.Struct.Member"  value="String:action_id">
+        <annotation name="org.gtk.EggDBus.DocString" value="The action the temporary authorization is for."/>
+      </annotation>
+
+      <annotation name="org.gtk.EggDBus.Struct.Member"  value="Subject:subject">
+        <annotation name="org.gtk.EggDBus.Type" value="Subject"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The subject the temporary authorization is for."/>
+      </annotation>
+
+      <annotation name="org.gtk.EggDBus.Struct.Member"  value="UInt64:time_obtained">
+        <annotation name="org.gtk.EggDBus.DocString" value="When the temporary authorization was obtained, in seconds since the Epoch Jan 1, 1970 0:00 UTC."/>
+      </annotation>
+
+      <annotation name="org.gtk.EggDBus.Struct.Member"  value="UInt64:time_expires">
+        <annotation name="org.gtk.EggDBus.DocString" value="When the temporary authorization is set to expire, in seconds since the Epoch Jan 1, 1970 0:00 UTC."/>
+      </annotation>
+    </annotation>
+
+    <!-- ---------------------------------------------------------------------------------------------------- -->
+
+    <method name="EnumerateTemporaryAuthorizations">
+      <annotation name="org.gtk.EggDBus.DocString" value="Retrieves all temporary authorizations that applies to @subject."/>
+
+      <arg name="subject" direction="in" type="(sa{sv})">
+        <annotation name="org.gtk.EggDBus.Type" value="Subject"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The subject to get temporary authorizations for."/>
+      </arg>
+
+      <arg name="temporary_authorizations" direction="out" type="a(ss(sa{sv})tt)">
+        <annotation name="org.gtk.EggDBus.Type" value="Array<TemporaryAuthorization>"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="An array of #TemporaryAuthorization structs."/>
+      </arg>
+    </method>
+
+    <method name="RevokeTemporaryAuthorizations">
+      <annotation name="org.gtk.EggDBus.DocString" value="Revokes all temporary authorizations that applies to @subject."/>
+
+      <arg name="subject" direction="in" type="(sa{sv})">
+        <annotation name="org.gtk.EggDBus.Type" value="Subject"/>
+        <annotation name="org.gtk.EggDBus.DocString" value="The subject to revoke temporary authorizations from."/>
+      </arg>
+    </method>
+
+    <!-- ---------------------------------------------------------------------------------------------------- -->
+
     <signal name="Changed">
       <annotation name="org.gtk.EggDBus.DocString" value="This signal is emitted when actions and/or authorizations change"/>
     </signal>
diff --git a/docs/polkit/polkit-1-docs.xml b/docs/polkit/polkit-1-docs.xml
index aa3aa16..f09954b 100644
--- a/docs/polkit/polkit-1-docs.xml
+++ b/docs/polkit/polkit-1-docs.xml
@@ -72,6 +72,7 @@
     <xi:include href="xml/polkitdetails.xml"/>
     <xi:include href="xml/polkiterror.xml"/>
     <xi:include href="xml/polkitactiondescription.xml"/>
+    <xi:include href="xml/polkittemporaryauthorization.xml"/>
     <chapter id="subjects">
       <title>Subjects</title>
       <xi:include href="xml/polkitsubject.xml"/>
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
index 1e3bd8c..f096d2d 100644
--- a/docs/polkit/polkit-1-sections.txt
+++ b/docs/polkit/polkit-1-sections.txt
@@ -31,11 +31,17 @@ polkit_authority_unregister_authentication_agent
 polkit_authority_unregister_authentication_agent_finish
 polkit_authority_authentication_agent_response
 polkit_authority_authentication_agent_response_finish
+polkit_authority_enumerate_temporary_authorizations
+polkit_authority_enumerate_temporary_authorizations_finish
+polkit_authority_revoke_temporary_authorizations
+polkit_authority_revoke_temporary_authorizations_finish
 polkit_authority_check_authorization_sync
 polkit_authority_enumerate_actions_sync
 polkit_authority_register_authentication_agent_sync
 polkit_authority_unregister_authentication_agent_sync
 polkit_authority_authentication_agent_response_sync
+polkit_authority_enumerate_temporary_authorizations_sync
+polkit_authority_revoke_temporary_authorizations_sync
 <SUBSECTION Standard>
 PolkitAuthorityClass
 POLKIT_AUTHORITY
@@ -104,6 +110,9 @@ POLKIT_UNIX_GROUP_GET_CLASS
 <FILE>polkitunixsession</FILE>
 PolkitUnixSession
 polkit_unix_session_new
+polkit_unix_session_new_for_process
+polkit_unix_session_new_for_process_finish
+polkit_unix_session_new_for_process_sync
 polkit_unix_session_get_session_id
 polkit_unix_session_set_session_id
 <SUBSECTION Standard>
@@ -158,6 +167,9 @@ PolkitSubject
 PolkitSubjectIface
 polkit_subject_hash
 polkit_subject_equal
+polkit_subject_exists
+polkit_subject_exists_finish
+polkit_subject_exists_sync
 polkit_subject_to_string
 polkit_subject_from_string
 <SUBSECTION Standard>
@@ -252,6 +264,8 @@ polkit_backend_authority_unregister_authentication_agent
 polkit_backend_authority_authentication_agent_response
 polkit_backend_authority_enumerate_actions
 polkit_backend_authority_system_bus_name_owner_changed
+polkit_backend_authority_enumerate_temporary_authorizations
+polkit_backend_authority_revoke_temporary_authorizations
 polkit_backend_authority_get
 polkit_backend_register_authority
 <SUBSECTION Standard>
@@ -420,3 +434,23 @@ POLKIT_AGENT_LISTENER_CLASS
 POLKIT_AGENT_IS_LISTENER_CLASS
 POLKIT_AGENT_LISTENER_GET_CLASS
 </SECTION>
+
+<SECTION>
+<FILE>polkittemporaryauthorization</FILE>
+<TITLE>PolkitTemporaryAuthorization</TITLE>
+PolkitTemporaryAuthorization
+PolkitTemporaryAuthorizationClass
+polkit_temporary_authorization_get_id
+polkit_temporary_authorization_get_action_id
+polkit_temporary_authorization_get_subject
+polkit_temporary_authorization_get_time_obtained
+polkit_temporary_authorization_get_time_expires
+<SUBSECTION Standard>
+POLKIT_TEMPORARY_AUTHORIZATION
+POLKIT_TEMPORARY_IS_AUTHORIZATION
+POLKIT_TEMPORARY_TYPE_AUTHORIZATION
+polkit_temporary_authorization_get_type
+POLKIT_TEMPORARY_AUTHORIZATION_CLASS
+POLKIT_TEMPORARY_IS_AUTHORIZATION_CLASS
+POLKIT_TEMPORARY_AUTHORIZATION_GET_CLASS
+</SECTION>
diff --git a/docs/polkit/polkit-1.types b/docs/polkit/polkit-1.types
index c212fd2..749b8bc 100644
--- a/docs/polkit/polkit-1.types
+++ b/docs/polkit/polkit-1.types
@@ -12,6 +12,7 @@ polkit_unix_session_get_type
 polkit_system_bus_name_get_type
 polkit_error_get_type
 polkit_authorization_result_get_type
+polkit_temporary_authorization_get_type
 
 polkit_backend_authority_get_type
 polkit_backend_interactive_authority_get_type
diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am
index b035282..88d5f38 100644
--- a/src/polkit/Makefile.am
+++ b/src/polkit/Makefile.am
@@ -33,7 +33,7 @@ polkit-built-sources.stamp : Makefile.am $(top_srcdir)/data/org.freedesktop.Poli
 
 # keep in sync with contents of polkit-built-sources.stamp (Thanks autotools)
 #
-polkit_built_sources = _polkitbindingsmarshal.c _polkitbindingsmarshal.h _polkitbindingsmarshal.list _polkitbindings.c _polkitbindings.h _polkitbindingstypes.h _polkitauthenticationagent.c _polkitauthenticationagent.h docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml _polkitauthority.c _polkitauthority.h docbook-interface-org.freedesktop.PolicyKit1.Authority.xml _polkiterror.c _polkiterror.h _polkitimplicitauthorization.c _polkitimplicitauthorization.h _polkitauthorizationresult.c _polkitauthorizationresult.h _polkitcheckauthorizationflags.c _polkitcheckauthorizationflags.h _polkitactiondescription.c _polkitactiondescription.h _polkitidentity.c _polkitidentity.h _polkitsubject.c _polkitsubject.h
+polkit_built_sources = _polkitactiondescription.c _polkitactiondescription.h _polkitauthenticationagent.c _polkitauthenticationagent.h _polkitauthority.c _polkitauthority.h _polkitauthorizationresult.c _polkitauthorizationresult.h _polkitbindings.c _polkitbindings.h _polkitbindingsmarshal.c _polkitbindingsmarshal.h _polkitbindingstypes.h _polkitcheckauthorizationflags.c _polkitcheckauthorizationflags.h _polkiterror.c _polkiterror.h _polkitidentity.c _polkitidentity.h _polkitimplicitauthorization.c _polkitimplicitauthorization.h _polkitsubject.c _polkitsubject.h _polkittemporaryauthorization.c _polkittemporaryauthorization.h docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
 
 lib_LTLIBRARIES=libpolkit-gobject-1.la
 
@@ -57,6 +57,7 @@ libpolkit_gobject_1include_HEADERS =                        				\
 	polkitauthorizationresult.h							\
 	polkitcheckauthorizationflags.h							\
 	polkitimplicitauthorization.h							\
+	polkittemporaryauthorization.h							\
         $(NULL)
 
 libpolkit_gobject_1_la_SOURCES =                                   			\
@@ -77,6 +78,7 @@ libpolkit_gobject_1_la_SOURCES =                                   			\
 	polkitauthorizationresult.c		polkitauthorizationresult.h		\
 	polkitcheckauthorizationflags.c		polkitcheckauthorizationflags.h		\
 	polkitimplicitauthorization.c		polkitimplicitauthorization.h		\
+	polkittemporaryauthorization.c		polkittemporaryauthorization.h		\
         $(NULL)
 
 libpolkit_gobject_1_la_CFLAGS =                                        	\
diff --git a/src/polkit/polkit.h b/src/polkit/polkit.h
index ee3b0bd..9c16710 100644
--- a/src/polkit/polkit.h
+++ b/src/polkit/polkit.h
@@ -38,6 +38,7 @@
 #include <polkit/polkitcheckauthorizationflags.h>
 #include <polkit/polkitauthority.h>
 #include <polkit/polkitdetails.h>
+#include <polkit/polkittemporaryauthorization.h>
 
 #undef _POLKIT_INSIDE_POLKIT_H
 
diff --git a/src/polkit/polkitactiondescription.c b/src/polkit/polkitactiondescription.c
index f36b68d..cc1a8b5 100644
--- a/src/polkit/polkitactiondescription.c
+++ b/src/polkit/polkitactiondescription.c
@@ -33,7 +33,7 @@
 /**
  * SECTION:polkitactiondescription
  * @title: PolkitActionDescription
- * @short_description: Actions
+ * @short_description: Description of Actions
  *
  * Object used to encapsulate a registered action.
  */
diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
index 4bb7ecd..4d34b16 100644
--- a/src/polkit/polkitauthority.c
+++ b/src/polkit/polkitauthority.c
@@ -572,7 +572,7 @@ polkit_authority_check_authorization_sync (PolkitAuthority               *author
 
 static guint
 polkit_authority_register_authentication_agent_async (PolkitAuthority      *authority,
-                                                      const gchar          *session_id,
+                                                      PolkitSubject        *subject,
                                                       const gchar          *locale,
                                                       const gchar          *object_path,
                                                       GCancellable         *cancellable,
@@ -581,20 +581,24 @@ polkit_authority_register_authentication_agent_async (PolkitAuthority      *auth
 {
   guint call_id;
   GSimpleAsyncResult *simple;
+  _PolkitSubject *real_subject;
 
   simple = g_simple_async_result_new (G_OBJECT (authority),
                                       callback,
                                       user_data,
                                       polkit_authority_register_authentication_agent_async);
 
+  real_subject = polkit_subject_get_real (subject);
+
   call_id = _polkit_authority_register_authentication_agent (authority->real,
                                                              EGG_DBUS_CALL_FLAGS_NONE,
-                                                             session_id,
+                                                             real_subject,
                                                              locale,
                                                              object_path,
                                                              cancellable,
                                                              generic_async_cb,
                                                              simple);
+  g_object_unref (real_subject);
 
   return call_id;
 }
@@ -602,7 +606,7 @@ polkit_authority_register_authentication_agent_async (PolkitAuthority      *auth
 /**
  * polkit_authority_register_authentication_agent:
  * @authority: A #PolkitAuthority.
- * @session_id: The identifier of the session to register for or %NULL for the session of the caller.
+ * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
  * @locale: The locale of the authentication agent.
  * @object_path: The object path for the authentication agent.
  * @cancellable: A #GCancellable or %NULL.
@@ -617,7 +621,7 @@ polkit_authority_register_authentication_agent_async (PolkitAuthority      *auth
  **/
 void
 polkit_authority_register_authentication_agent (PolkitAuthority      *authority,
-                                                const gchar          *session_id,
+                                                PolkitSubject        *subject,
                                                 const gchar          *locale,
                                                 const gchar          *object_path,
                                                 GCancellable         *cancellable,
@@ -625,7 +629,7 @@ polkit_authority_register_authentication_agent (PolkitAuthority      *authority,
                                                 gpointer              user_data)
 {
   polkit_authority_register_authentication_agent_async (authority,
-                                                        session_id,
+                                                        subject,
                                                         locale,
                                                         object_path,
                                                         cancellable,
@@ -673,7 +677,7 @@ polkit_authority_register_authentication_agent_finish (PolkitAuthority *authorit
 /**
  * polkit_authority_register_authentication_agent_sync:
  * @authority: A #PolkitAuthority.
- * @session_id: The identifier of the session to register for or %NULL for the session of the caller.
+ * @subject: The subject the authentication agent is for, typically a #PolkitUnixSession object.
  * @locale: The locale of the authentication agent.
  * @object_path: The object path for the authentication agent.
  * @cancellable: A #GCancellable or %NULL.
@@ -685,7 +689,7 @@ polkit_authority_register_authentication_agent_finish (PolkitAuthority *authorit
  **/
 gboolean
 polkit_authority_register_authentication_agent_sync (PolkitAuthority     *authority,
-                                                     const gchar         *session_id,
+                                                     PolkitSubject       *subject,
                                                      const gchar         *locale,
                                                      const gchar         *object_path,
                                                      GCancellable        *cancellable,
@@ -696,7 +700,7 @@ polkit_authority_register_authentication_agent_sync (PolkitAuthority     *author
   gboolean ret;
 
   call_id = polkit_authority_register_authentication_agent_async (authority,
-                                                                  session_id,
+                                                                  subject,
                                                                   locale,
                                                                   object_path,
                                                                   cancellable,
@@ -716,7 +720,7 @@ polkit_authority_register_authentication_agent_sync (PolkitAuthority     *author
 
 static guint
 polkit_authority_unregister_authentication_agent_async (PolkitAuthority      *authority,
-                                                        const gchar          *session_id,
+                                                        PolkitSubject        *subject,
                                                         const gchar          *object_path,
                                                         GCancellable         *cancellable,
                                                         GAsyncReadyCallback   callback,
@@ -724,27 +728,32 @@ polkit_authority_unregister_authentication_agent_async (PolkitAuthority      *au
 {
   guint call_id;
   GSimpleAsyncResult *simple;
+  _PolkitSubject *real_subject;
 
   simple = g_simple_async_result_new (G_OBJECT (authority),
                                       callback,
                                       user_data,
                                       polkit_authority_unregister_authentication_agent_async);
 
+  real_subject = polkit_subject_get_real (subject);
+
   call_id = _polkit_authority_unregister_authentication_agent (authority->real,
                                                                EGG_DBUS_CALL_FLAGS_NONE,
-                                                               session_id,
+                                                               real_subject,
                                                                object_path,
                                                                cancellable,
                                                                generic_async_cb,
                                                                simple);
 
+  g_object_unref (real_subject);
+
   return call_id;
 }
 
 /**
  * polkit_authority_unregister_authentication_agent:
  * @authority: A #PolkitAuthority.
- * @session_id: The identifier of the session the agent is registered at or %NULL for the session of the caller.
+ * @subject: The #PolkitSubject passed when registering the agent.
  * @object_path: The object path that the authentication agent is registered at.
  * @cancellable: A #GCancellable or %NULL.
  * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
@@ -758,14 +767,14 @@ polkit_authority_unregister_authentication_agent_async (PolkitAuthority      *au
  **/
 void
 polkit_authority_unregister_authentication_agent (PolkitAuthority      *authority,
-                                                  const gchar          *session_id,
+                                                  PolkitSubject        *subject,
                                                   const gchar          *object_path,
                                                   GCancellable         *cancellable,
                                                   GAsyncReadyCallback   callback,
                                                   gpointer              user_data)
 {
   polkit_authority_unregister_authentication_agent_async (authority,
-                                                          session_id,
+                                                          subject,
                                                           object_path,
                                                           cancellable,
                                                           callback,
@@ -811,7 +820,7 @@ polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *author
 /**
  * polkit_authority_unregister_authentication_agent_sync:
  * @authority: A #PolkitAuthority.
- * @session_id: The identifier of the session the agent is registered at or %NULL for the session of the caller.
+ * @subject: The #PolkitSubject passed when registering the agent.
  * @object_path: The object path that the authentication agent is registered at.
  * @cancellable: A #GCancellable or %NULL.
  * @error: Return location for error or %NULL.
@@ -822,7 +831,7 @@ polkit_authority_unregister_authentication_agent_finish (PolkitAuthority *author
  **/
 gboolean
 polkit_authority_unregister_authentication_agent_sync (PolkitAuthority     *authority,
-                                                       const gchar         *session_id,
+                                                       PolkitSubject       *subject,
                                                        const gchar         *object_path,
                                                        GCancellable        *cancellable,
                                                        GError             **error)
@@ -832,7 +841,7 @@ polkit_authority_unregister_authentication_agent_sync (PolkitAuthority     *auth
   gboolean ret;
 
   call_id = polkit_authority_unregister_authentication_agent_async (authority,
-                                                                    session_id,
+                                                                    subject,
                                                                     object_path,
                                                                     cancellable,
                                                                     generic_cb,
@@ -995,3 +1004,197 @@ polkit_authority_authentication_agent_response_sync (PolkitAuthority     *author
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
+
+static guint
+polkit_authority_enumerate_temporary_authorizations_async (PolkitAuthority     *authority,
+                                                           PolkitSubject       *subject,
+                                                           GCancellable        *cancellable,
+                                                           GAsyncReadyCallback  callback,
+                                                           gpointer             user_data)
+{
+  guint call_id;
+  GSimpleAsyncResult *simple;
+  _PolkitSubject *real_subject;
+
+  simple = g_simple_async_result_new (G_OBJECT (authority),
+                                      callback,
+                                      user_data,
+                                      polkit_authority_enumerate_temporary_authorizations_async);
+
+  real_subject = polkit_subject_get_real (subject);
+
+  call_id = _polkit_authority_enumerate_temporary_authorizations (authority->real,
+                                                                  EGG_DBUS_CALL_FLAGS_NONE,
+                                                                  real_subject,
+                                                                  cancellable,
+                                                                  generic_async_cb,
+                                                                  simple);
+
+  g_object_unref (real_subject);
+
+  return call_id;
+}
+
+void
+polkit_authority_enumerate_temporary_authorizations (PolkitAuthority     *authority,
+                                                     PolkitSubject       *subject,
+                                                     GCancellable        *cancellable,
+                                                     GAsyncReadyCallback  callback,
+                                                     gpointer             user_data)
+{
+  polkit_authority_enumerate_temporary_authorizations_async (authority, subject, cancellable, callback, user_data);
+}
+
+GList *
+polkit_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *authority,
+                                                            GAsyncResult    *res,
+                                                            GError         **error)
+{
+  EggDBusArraySeq *array_seq;
+  GList *result;
+  guint n;
+  GSimpleAsyncResult *simple;
+  GAsyncResult *real_res;
+
+  simple = G_SIMPLE_ASYNC_RESULT (res);
+  real_res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (simple));
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_enumerate_temporary_authorizations_async);
+
+  result = NULL;
+
+  if (!_polkit_authority_enumerate_temporary_authorizations_finish (authority->real,
+                                                                    &array_seq,
+                                                                    real_res,
+                                                                    error))
+    goto out;
+
+  for (n = 0; n < array_seq->size; n++)
+    {
+      _PolkitTemporaryAuthorization *real_ta;
+
+      real_ta = array_seq->data.v_ptr[n];
+
+      result = g_list_prepend (result, polkit_temporary_authorization_new_for_real (real_ta));
+    }
+
+  result = g_list_reverse (result);
+
+  g_object_unref (array_seq);
+
+ out:
+  g_object_unref (real_res);
+  return result;
+}
+
+GList *
+polkit_authority_enumerate_temporary_authorizations_sync (PolkitAuthority     *authority,
+                                                          PolkitSubject       *subject,
+                                                          GCancellable        *cancellable,
+                                                          GError             **error)
+{
+  guint call_id;
+  GAsyncResult *res;
+  GList *result;
+
+  call_id = polkit_authority_enumerate_temporary_authorizations_async (authority, subject, cancellable, generic_cb, &res);
+
+  egg_dbus_connection_pending_call_block (authority->system_bus, call_id);
+
+  result = polkit_authority_enumerate_temporary_authorizations_finish (authority, res, error);
+
+  g_object_unref (res);
+
+  return result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static guint
+polkit_authority_revoke_temporary_authorizations_async (PolkitAuthority     *authority,
+                                                        PolkitSubject       *subject,
+                                                        GCancellable        *cancellable,
+                                                        GAsyncReadyCallback  callback,
+                                                        gpointer             user_data)
+{
+  guint call_id;
+  GSimpleAsyncResult *simple;
+  _PolkitSubject *real_subject;
+
+  simple = g_simple_async_result_new (G_OBJECT (authority),
+                                      callback,
+                                      user_data,
+                                      polkit_authority_revoke_temporary_authorizations_async);
+
+  real_subject = polkit_subject_get_real (subject);
+
+  call_id = _polkit_authority_revoke_temporary_authorizations (authority->real,
+                                                               EGG_DBUS_CALL_FLAGS_NONE,
+                                                               real_subject,
+                                                               cancellable,
+                                                               generic_async_cb,
+                                                               simple);
+
+  g_object_unref (real_subject);
+
+  return call_id;
+}
+
+void
+polkit_authority_revoke_temporary_authorizations (PolkitAuthority     *authority,
+                                                  PolkitSubject       *subject,
+                                                  GCancellable        *cancellable,
+                                                  GAsyncReadyCallback  callback,
+                                                  gpointer             user_data)
+{
+  polkit_authority_revoke_temporary_authorizations_async (authority, subject, cancellable, callback, user_data);
+}
+
+gboolean
+polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *authority,
+                                                         GAsyncResult    *res,
+                                                         GError         **error)
+{
+  GSimpleAsyncResult *simple;
+  GAsyncResult *real_res;
+  gboolean ret;
+
+  simple = G_SIMPLE_ASYNC_RESULT (res);
+  real_res = G_ASYNC_RESULT (g_simple_async_result_get_op_res_gpointer (simple));
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_authority_revoke_temporary_authorizations_async);
+
+  ret = _polkit_authority_revoke_temporary_authorizations_finish (authority->real,
+                                                                  real_res,
+                                                                  error);
+
+  if (!ret)
+    goto out;
+
+ out:
+  g_object_unref (real_res);
+  return ret;
+}
+
+gboolean
+polkit_authority_revoke_temporary_authorizations_sync (PolkitAuthority     *authority,
+                                                       PolkitSubject       *subject,
+                                                       GCancellable        *cancellable,
+                                                       GError             **error)
+{
+  guint call_id;
+  GAsyncResult *res;
+  gboolean result;
+
+  call_id = polkit_authority_revoke_temporary_authorizations_async (authority, subject, cancellable, generic_cb, &res);
+
+  egg_dbus_connection_pending_call_block (authority->system_bus, call_id);
+
+  result = polkit_authority_revoke_temporary_authorizations_finish (authority, res, error);
+
+  g_object_unref (res);
+
+  return result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h
index e9df6d0..61a6e7c 100644
--- a/src/polkit/polkitauthority.h
+++ b/src/polkit/polkitauthority.h
@@ -71,14 +71,14 @@ PolkitAuthorizationResult *polkit_authority_check_authorization_sync (PolkitAuth
                                                                       GError                       **error);
 
 gboolean                   polkit_authority_register_authentication_agent_sync (PolkitAuthority     *authority,
-                                                                                const gchar         *session_id,
+                                                                                PolkitSubject       *subject,
                                                                                 const gchar         *locale,
                                                                                 const gchar         *object_path,
                                                                                 GCancellable        *cancellable,
                                                                                 GError             **error);
 
 gboolean                   polkit_authority_unregister_authentication_agent_sync (PolkitAuthority     *authority,
-                                                                                  const gchar         *session_id,
+                                                                                  PolkitSubject       *subject,
                                                                                   const gchar         *object_path,
                                                                                   GCancellable        *cancellable,
                                                                                   GError             **error);
@@ -89,6 +89,16 @@ gboolean                   polkit_authority_authentication_agent_response_sync (
                                                                                 GCancellable        *cancellable,
                                                                                 GError             **error);
 
+GList                     *polkit_authority_enumerate_temporary_authorizations_sync (PolkitAuthority     *authority,
+                                                                                     PolkitSubject       *subject,
+                                                                                     GCancellable        *cancellable,
+                                                                                     GError             **error);
+
+gboolean                   polkit_authority_revoke_temporary_authorizations_sync (PolkitAuthority     *authority,
+                                                                                  PolkitSubject       *subject,
+                                                                                  GCancellable        *cancellable,
+                                                                                  GError             **error);
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 void                       polkit_authority_enumerate_actions (PolkitAuthority     *authority,
@@ -114,7 +124,7 @@ PolkitAuthorizationResult *polkit_authority_check_authorization_finish (PolkitAu
                                                                         GError                  **error);
 
 void                       polkit_authority_register_authentication_agent (PolkitAuthority     *authority,
-                                                                           const gchar         *session_id,
+                                                                           PolkitSubject       *subject,
                                                                            const gchar         *locale,
                                                                            const gchar         *object_path,
                                                                            GCancellable        *cancellable,
@@ -126,7 +136,7 @@ gboolean                   polkit_authority_register_authentication_agent_finish
                                                                                   GError         **error);
 
 void                       polkit_authority_unregister_authentication_agent (PolkitAuthority     *authority,
-                                                                             const gchar         *session_id,
+                                                                             PolkitSubject       *subject,
                                                                              const gchar         *object_path,
                                                                              GCancellable        *cancellable,
                                                                              GAsyncReadyCallback  callback,
@@ -147,6 +157,26 @@ gboolean                   polkit_authority_authentication_agent_response_finish
                                                                                   GAsyncResult    *res,
                                                                                   GError         **error);
 
+void                       polkit_authority_enumerate_temporary_authorizations (PolkitAuthority     *authority,
+                                                                                PolkitSubject       *subject,
+                                                                                GCancellable        *cancellable,
+                                                                                GAsyncReadyCallback  callback,
+                                                                                gpointer             user_data);
+
+GList                     *polkit_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *authority,
+                                                                                       GAsyncResult    *res,
+                                                                                       GError         **error);
+
+void                       polkit_authority_revoke_temporary_authorizations (PolkitAuthority     *authority,
+                                                                             PolkitSubject       *subject,
+                                                                             GCancellable        *cancellable,
+                                                                             GAsyncReadyCallback  callback,
+                                                                             gpointer             user_data);
+
+gboolean                   polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *authority,
+                                                                                    GAsyncResult    *res,
+                                                                                    GError         **error);
+
 /* ---------------------------------------------------------------------------------------------------- */
 
 G_END_DECLS
diff --git a/src/polkit/polkitprivate.h b/src/polkit/polkitprivate.h
index 89601fc..3d4ed16 100644
--- a/src/polkit/polkitprivate.h
+++ b/src/polkit/polkitprivate.h
@@ -26,6 +26,7 @@
 #include "polkitactiondescription.h"
 #include "polkitsubject.h"
 #include "polkitauthorizationresult.h"
+#include "polkittemporaryauthorization.h"
 #include "_polkitbindings.h"
 
 /* notes:
@@ -47,6 +48,8 @@ _PolkitIdentity *polkit_identity_get_real     (PolkitIdentity  *identity);
 PolkitAuthorizationResult  *polkit_authorization_result_new_for_real (_PolkitAuthorizationResult *real);
 _PolkitAuthorizationResult *polkit_authorization_result_get_real (PolkitAuthorizationResult *authorization_result);
 
+_PolkitTemporaryAuthorization *polkit_temporary_authorization_get_real (PolkitTemporaryAuthorization *authorization);
+PolkitTemporaryAuthorization *polkit_temporary_authorization_new_for_real (_PolkitTemporaryAuthorization *real);
 
 PolkitDetails *polkit_details_new_for_hash (GHashTable *hash);
 GHashTable *polkit_details_get_hash (PolkitDetails *details);
diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c
index 43be6b9..b2f9290 100644
--- a/src/polkit/polkitsubject.c
+++ b/src/polkit/polkitsubject.c
@@ -126,6 +126,74 @@ polkit_subject_to_string (PolkitSubject *subject)
 }
 
 /**
+ * polkit_subject_exists:
+ * @subject: A #PolkitSubject.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: The data to pass to @callback.
+ *
+ * Asynchronously checks if @subject exists.
+ *
+ * When the operation is finished, @callback will be invoked. You can
+ * then call polkit_subject_exists_finish() to get the result of the
+ * operation.
+ **/
+void
+polkit_subject_exists (PolkitSubject       *subject,
+                       GCancellable        *cancellable,
+                       GAsyncReadyCallback  callback,
+                       gpointer             user_data)
+{
+  POLKIT_SUBJECT_GET_IFACE (subject)->exists (subject,
+                                              cancellable,
+                                              callback,
+                                              user_data);
+}
+
+/**
+ * polkit_subject_exists_finish:
+ * @subject: A #PolkitSubject.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to polkit_subject_exists().
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes checking whether a subject exists.
+ *
+ * Returns: %TRUE if the subject exists, %FALSE if not or @error is set.
+ */
+gboolean
+polkit_subject_exists_finish (PolkitSubject   *subject,
+                              GAsyncResult    *res,
+                              GError         **error)
+{
+  return POLKIT_SUBJECT_GET_IFACE (subject)->exists_finish (subject,
+                                                            res,
+                                                            error);
+}
+
+/**
+ * polkit_subject_exists_sync:
+ * @subject: A #PolkitSubject.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Checks if @subject exists.
+ *
+ * This is a synchronous blocking call, see polkit_subject_exists()
+ * for the asynchronous version.
+ *
+ * Returns: %TRUE if the subject exists, %FALSE if not or @error is set.
+ */
+gboolean
+polkit_subject_exists_sync   (PolkitSubject  *subject,
+                              GCancellable   *cancellable,
+                              GError        **error)
+{
+  return POLKIT_SUBJECT_GET_IFACE (subject)->exists_sync (subject,
+                                                          cancellable,
+                                                          error);
+}
+
+/**
  * polkit_subject_from_string:
  * @str: A string obtained from polkit_subject_to_string().
  * @error: Return location for error.
diff --git a/src/polkit/polkitsubject.h b/src/polkit/polkitsubject.h
index 6eb8fef..616d95e 100644
--- a/src/polkit/polkitsubject.h
+++ b/src/polkit/polkitsubject.h
@@ -54,6 +54,9 @@ typedef struct _PolkitSubjectIface PolkitSubjectIface;
  * @equal: Checks if two #PolkitSubject<!-- -->s are equal.
  * @to_string: Serializes a #PolkitSubject to a string that can be
  * used in polkit_subject_from_string().
+ * @exists: Asynchronously check if a #PolkitSubject exists.
+ * @exists_finish: Finishes checking if a #PolkitSubject exists.
+ * @exists_sync: Synchronously check if a #PolkitSubject exists.
  *
  * An interface for subjects.
  */
@@ -61,21 +64,44 @@ struct _PolkitSubjectIface
 {
   GTypeInterface parent_iface;
 
-  guint    (*hash)      (PolkitSubject *subject);
+  guint    (*hash)          (PolkitSubject       *subject);
 
-  gboolean (*equal)     (PolkitSubject *a,
-                         PolkitSubject *b);
+  gboolean (*equal)         (PolkitSubject       *a,
+                             PolkitSubject       *b);
 
-  gchar *  (*to_string) (PolkitSubject *subject);
+  gchar *  (*to_string)     (PolkitSubject       *subject);
+
+  void     (*exists)        (PolkitSubject       *subject,
+                             GCancellable        *cancellable,
+                             GAsyncReadyCallback  callback,
+                             gpointer             user_data);
+
+  gboolean (*exists_finish) (PolkitSubject       *subject,
+                             GAsyncResult        *res,
+                             GError             **error);
+
+  gboolean (*exists_sync)   (PolkitSubject       *subject,
+                             GCancellable        *cancellable,
+                             GError             **error);
 };
 
-GType          polkit_subject_get_type     (void) G_GNUC_CONST;
-guint          polkit_subject_hash         (PolkitSubject *subject);
-gboolean       polkit_subject_equal        (PolkitSubject *a,
-                                            PolkitSubject *b);
-gchar         *polkit_subject_to_string    (PolkitSubject *subject);
-PolkitSubject *polkit_subject_from_string  (const gchar   *str,
-                                            GError       **error);
+GType          polkit_subject_get_type      (void) G_GNUC_CONST;
+guint          polkit_subject_hash          (PolkitSubject       *subject);
+gboolean       polkit_subject_equal         (PolkitSubject       *a,
+                                             PolkitSubject       *b);
+gchar         *polkit_subject_to_string     (PolkitSubject       *subject);
+PolkitSubject *polkit_subject_from_string   (const gchar         *str,
+                                             GError             **error);
+void           polkit_subject_exists        (PolkitSubject       *subject,
+                                             GCancellable        *cancellable,
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+gboolean       polkit_subject_exists_finish (PolkitSubject       *subject,
+                                             GAsyncResult        *res,
+                                             GError             **error);
+gboolean       polkit_subject_exists_sync   (PolkitSubject       *subject,
+                                             GCancellable        *cancellable,
+                                             GError             **error);
 
 G_END_DECLS
 
diff --git a/src/polkit/polkitsystembusname.c b/src/polkit/polkitsystembusname.c
index 44b71e5..180b6b6 100644
--- a/src/polkit/polkitsystembusname.c
+++ b/src/polkit/polkitsystembusname.c
@@ -224,10 +224,158 @@ polkit_system_bus_name_to_string (PolkitSubject *subject)
   return g_strdup_printf ("system-bus-name:%s", system_bus_name->name);
 }
 
+
+static void
+name_exists_cb (GObject      *source_object,
+                GAsyncResult *res,
+                gpointer      user_data)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  EggDBusMessage *reply;
+  GError *error;
+
+  error = NULL;
+  reply = egg_dbus_connection_send_message_with_reply_finish (EGG_DBUS_CONNECTION (source_object),
+                                                              res,
+                                                              &error);
+  if (reply != NULL)
+    {
+      gboolean has_owner;
+      if (egg_dbus_message_extract_boolean (reply, &has_owner, &error))
+        {
+          g_simple_async_result_set_op_res_gboolean (simple, has_owner);
+        }
+      g_object_unref (reply);
+    }
+
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_error_free (error);
+    }
+
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+static void
+polkit_system_bus_name_exists (PolkitSubject       *subject,
+                               GCancellable        *cancellable,
+                               GAsyncReadyCallback  callback,
+                               gpointer             user_data)
+{
+  PolkitSystemBusName *name = POLKIT_SYSTEM_BUS_NAME (subject);
+  EggDBusMessage *message;
+  EggDBusConnection *connection;
+  GSimpleAsyncResult *simple;
+
+  message = NULL;
+  connection = NULL;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.DBus",
+                                                             "/org/freedesktop/DBus",
+                                                             "org.freedesktop.DBus",
+                                                             "NameHasOwner");
+  egg_dbus_message_append_string (message, name->name, NULL);
+
+  simple = g_simple_async_result_new (G_OBJECT (name),
+                                      callback,
+                                      user_data,
+                                      polkit_system_bus_name_exists);
+
+  egg_dbus_connection_send_message_with_reply (connection,
+                                               EGG_DBUS_CALL_FLAGS_NONE,
+                                               message,
+                                               NULL,
+                                               cancellable,
+                                               name_exists_cb,
+                                               simple);
+
+  g_object_unref (message);
+  g_object_unref (connection);
+}
+
+static gboolean
+polkit_system_bus_name_exists_sync (PolkitSubject   *subject,
+                                    GCancellable    *cancellable,
+                                    GError         **error)
+{
+  PolkitSystemBusName *name = POLKIT_SYSTEM_BUS_NAME (subject);
+  EggDBusMessage *message;
+  EggDBusMessage *reply;
+  EggDBusConnection *connection;
+  gboolean ret;
+
+  message = NULL;
+  reply = NULL;
+  connection = NULL;
+  ret = FALSE;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.DBus",
+                                                             "/org/freedesktop/DBus",
+                                                             "org.freedesktop.DBus",
+                                                             "NameHasOwner");
+  egg_dbus_message_append_string (message, name->name, NULL);
+
+  reply = egg_dbus_connection_send_message_with_reply_sync (connection,
+                                                            EGG_DBUS_CALL_FLAGS_NONE,
+                                                            message,
+                                                            NULL,
+                                                            cancellable,
+                                                            error);
+  if (reply == NULL)
+    goto out;
+
+  if (!egg_dbus_message_extract_boolean (reply, &ret, error))
+    goto out;
+
+ out:
+  if (message != NULL)
+    g_object_unref (message);
+  if (reply != NULL)
+    g_object_unref (reply);
+  if (connection != NULL)
+    g_object_unref (connection);
+
+  return ret;
+}
+
+static gboolean
+polkit_system_bus_name_exists_finish (PolkitSubject  *subject,
+                                      GAsyncResult   *res,
+                                      GError        **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  gboolean ret;
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_system_bus_name_exists);
+
+  ret = FALSE;
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    goto out;
+
+  ret = g_simple_async_result_get_op_res_gboolean (simple);
+
+ out:
+  return ret;
+}
+
 static void
 subject_iface_init (PolkitSubjectIface *subject_iface)
 {
-  subject_iface->hash      = polkit_system_bus_name_hash;
-  subject_iface->equal     = polkit_system_bus_name_equal;
-  subject_iface->to_string = polkit_system_bus_name_to_string;
+  subject_iface->hash          = polkit_system_bus_name_hash;
+  subject_iface->equal         = polkit_system_bus_name_equal;
+  subject_iface->to_string     = polkit_system_bus_name_to_string;
+  subject_iface->exists        = polkit_system_bus_name_exists;
+  subject_iface->exists_finish = polkit_system_bus_name_exists_finish;
+  subject_iface->exists_sync   = polkit_system_bus_name_exists_sync;
 }
diff --git a/src/polkit/polkittemporaryauthorization.c b/src/polkit/polkittemporaryauthorization.c
new file mode 100644
index 0000000..409a5ec
--- /dev/null
+++ b/src/polkit/polkittemporaryauthorization.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz at redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <string.h>
+#include "polkitimplicitauthorization.h"
+#include "polkittemporaryauthorization.h"
+#include "_polkittemporaryauthorization.h"
+
+#include "polkitprivate.h"
+
+/**
+ * SECTION:polkittemporaryauthorization
+ * @title: PolkitTemporaryAuthorization
+ * @short_description: Temporary Authorizations
+ *
+ * Object used to describe a temporary authorization.
+ */
+
+/**
+ * PolkitTemporaryAuthorization:
+ *
+ * The #PolkitTemporaryAuthorization struct should not be accessed directly.
+ */
+struct _PolkitTemporaryAuthorization
+{
+  GObject parent_instance;
+
+  _PolkitTemporaryAuthorization *real;
+
+  gchar **annotation_keys;
+};
+
+struct _PolkitTemporaryAuthorizationClass
+{
+  GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (PolkitTemporaryAuthorization, polkit_temporary_authorization, G_TYPE_OBJECT);
+
+static void
+polkit_temporary_authorization_init (PolkitTemporaryAuthorization *authorization)
+{
+}
+
+static void
+polkit_temporary_authorization_finalize (GObject *object)
+{
+  PolkitTemporaryAuthorization *authorization;
+
+  authorization = POLKIT_TEMPORARY_AUTHORIZATION (object);
+
+  g_object_unref (authorization->real);
+
+  if (G_OBJECT_CLASS (polkit_temporary_authorization_parent_class)->finalize != NULL)
+    G_OBJECT_CLASS (polkit_temporary_authorization_parent_class)->finalize (object);
+}
+
+static void
+polkit_temporary_authorization_class_init (PolkitTemporaryAuthorizationClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = polkit_temporary_authorization_finalize;
+}
+
+/**
+ * polkit_temporary_authorization_new:
+ * @id: Id for temporary authorization
+ * @action_id: An action id.
+ * @subject: A #PolkitSubject.
+ * @time_obtained: Time obtained, since the Epoch Jan 1, 1970 0:00 UTC.
+ * @time_expires: Time the temporary authorization will expire, since the Epoch Jan 1, 1970 0:00 UTC.
+ *
+ * Creates a new temporary authorization.
+ *
+ * Returns: A #PolkitTemporaryAuthorization, free with g_object_unref()
+ **/
+PolkitTemporaryAuthorization *
+polkit_temporary_authorization_new (const gchar                  *id,
+                                    const gchar                  *action_id,
+                                    PolkitSubject                *subject,
+                                    guint64                       time_obtained,
+                                    guint64                       time_expires)
+{
+  PolkitTemporaryAuthorization *ret;
+  _PolkitTemporaryAuthorization *real;
+  _PolkitSubject *real_subject;
+
+  real_subject = polkit_subject_get_real (subject);
+  real = _polkit_temporary_authorization_new (id,
+                                              action_id,
+                                              real_subject,
+                                              time_obtained,
+                                              time_expires);
+  g_object_unref (real_subject);
+
+  ret = polkit_temporary_authorization_new_for_real (real);
+  g_object_unref (real);
+
+  return ret;
+}
+
+
+PolkitTemporaryAuthorization *
+polkit_temporary_authorization_new_for_real (_PolkitTemporaryAuthorization *real)
+{
+  PolkitTemporaryAuthorization *authorization;
+
+  authorization = POLKIT_TEMPORARY_AUTHORIZATION (g_object_new (POLKIT_TYPE_TEMPORARY_AUTHORIZATION, NULL));
+  authorization->real = g_object_ref (real);
+
+  return authorization;
+}
+
+_PolkitTemporaryAuthorization *
+polkit_temporary_authorization_get_real (PolkitTemporaryAuthorization *authorization)
+{
+  return g_object_ref (authorization->real);
+}
+
+/**
+ * polkit_temporary_authorization_get_id:
+ * @authorization: A #PolkitTemporaryAuthorization.
+ *
+ * Gets the opaque identifier for @authorization.
+ *
+ * Returns: A string owned by @authorization. Do not free.
+ */
+const gchar *
+polkit_temporary_authorization_get_id (PolkitTemporaryAuthorization *authorization)
+{
+  return _polkit_temporary_authorization_get_id (authorization->real);
+}
+
+/**
+ * polkit_temporary_authorization_get_action_id:
+ * @authorization: A #PolkitTemporaryAuthorization.
+ *
+ * Gets the action that @authorization is for.
+ *
+ * Returns: A string owned by @authorization. Do not free.
+ **/
+const gchar *
+polkit_temporary_authorization_get_action_id (PolkitTemporaryAuthorization *authorization)
+{
+  return _polkit_temporary_authorization_get_action_id (authorization->real);
+}
+
+/**
+ * polkit_temporary_authorization_get_subject:
+ * @authorization: A #PolkitTemporaryAuthorization.
+ *
+ * Gets the subject that @authorization is for.
+ *
+ * Returns: A #PolkitSubject, free with g_object_unref().
+ **/
+PolkitSubject *
+polkit_temporary_authorization_get_subject (PolkitTemporaryAuthorization *authorization)
+{
+  return polkit_subject_new_for_real (_polkit_temporary_authorization_get_subject (authorization->real));
+}
+
+/**
+ * polkit_temporary_authorization_get_time_obtained:
+ * @authorization: A #PolkitTemporaryAuthorization.
+ *
+ * Gets the time when @authorization was obtained.
+ *
+ * Returns: Seconds since the Epoch Jan 1. 1970, 0:00 UTC.
+ **/
+guint64
+polkit_temporary_authorization_get_time_obtained (PolkitTemporaryAuthorization *authorization)
+{
+  return _polkit_temporary_authorization_get_time_obtained (authorization->real);
+}
+
+/**
+ * polkit_temporary_authorization_get_time_expires:
+ * @authorization: A #PolkitTemporaryAuthorization.
+ *
+ * Gets the time when @authorization will expire.
+ *
+ * Returns: Seconds since the Epoch Jan 1. 1970, 0:00 UTC.
+ **/
+guint64
+polkit_temporary_authorization_get_time_expires (PolkitTemporaryAuthorization *authorization)
+{
+  return _polkit_temporary_authorization_get_time_expires (authorization->real);
+}
diff --git a/src/polkit/polkittemporaryauthorization.h b/src/polkit/polkittemporaryauthorization.h
new file mode 100644
index 0000000..4d0c530
--- /dev/null
+++ b/src/polkit/polkittemporaryauthorization.h
@@ -0,0 +1,61 @@
+/*
+ * 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_COMPILATION) && !defined(_POLKIT_INSIDE_POLKIT_H)
+#error "Only <polkit/polkit.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef __POLKIT_TEMPORARY_AUTHORIZATION_H
+#define __POLKIT_TEMPORARY_AUTHORIZATION_H
+
+#include <glib-object.h>
+#include <gio/gio.h>
+#include <polkit/polkittypes.h>
+
+G_BEGIN_DECLS
+
+#define POLKIT_TYPE_TEMPORARY_AUTHORIZATION          (polkit_temporary_authorization_get_type())
+#define POLKIT_TEMPORARY_AUTHORIZATION(o)            (G_TYPE_CHECK_INSTANCE_CAST ((o), POLKIT_TYPE_TEMPORARY_AUTHORIZATION, PolkitTemporaryAuthorization))
+#define POLKIT_TEMPORARY_AUTHORIZATION_CLASS(k)      (G_TYPE_CHECK_CLASS_CAST((k), POLKIT_TYPE_TEMPORARY_AUTHORIZATION, PolkitTemporaryAuthorizationClass))
+#define POLKIT_TEMPORARY_AUTHORIZATION_GET_CLASS(o)  (G_TYPE_INSTANCE_GET_CLASS ((o), POLKIT_TYPE_TEMPORARY_AUTHORIZATION, PolkitTemporaryAuthorizationClass))
+#define POLKIT_IS_TEMPORARY_AUTHORIZATION(o)         (G_TYPE_CHECK_INSTANCE_TYPE ((o), POLKIT_TYPE_TEMPORARY_AUTHORIZATION))
+#define POLKIT_IS_TEMPORARY_AUTHORIZATION_CLASS(k)   (G_TYPE_CHECK_CLASS_TYPE ((k), POLKIT_TYPE_TEMPORARY_AUTHORIZATION))
+
+#if 0
+typedef struct _PolkitTemporaryAuthorization PolkitTemporaryAuthorization;
+#endif
+typedef struct _PolkitTemporaryAuthorizationClass PolkitTemporaryAuthorizationClass;
+
+GType          polkit_temporary_authorization_get_type              (void) G_GNUC_CONST;
+PolkitTemporaryAuthorization *polkit_temporary_authorization_new    (const gchar                  *id,
+                                                                     const gchar                  *action_id,
+                                                                     PolkitSubject                *subject,
+                                                                     guint64                       time_obtained,
+                                                                     guint64                       time_expires);
+const gchar   *polkit_temporary_authorization_get_id                (PolkitTemporaryAuthorization *authorization);
+const gchar   *polkit_temporary_authorization_get_action_id         (PolkitTemporaryAuthorization *authorization);
+PolkitSubject *polkit_temporary_authorization_get_subject           (PolkitTemporaryAuthorization *authorization);
+guint64        polkit_temporary_authorization_get_time_obtained     (PolkitTemporaryAuthorization *authorization);
+guint64        polkit_temporary_authorization_get_time_expires      (PolkitTemporaryAuthorization *authorization);
+
+G_END_DECLS
+
+#endif /* __POLKIT_TEMPORARY_AUTHORIZATION_H */
diff --git a/src/polkit/polkittypes.h b/src/polkit/polkittypes.h
index fcc98fa..0da7faf 100644
--- a/src/polkit/polkittypes.h
+++ b/src/polkit/polkittypes.h
@@ -55,4 +55,7 @@ typedef struct _PolkitAuthorizationResult PolkitAuthorizationResult;
 struct _PolkitDetails;
 typedef struct _PolkitDetails PolkitDetails;
 
+struct _PolkitTemporaryAuthorization;
+typedef struct _PolkitTemporaryAuthorization PolkitTemporaryAuthorization;
+
 #endif /* __POLKIT_TYPES_H */
diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
index 181f221..0a410be 100644
--- a/src/polkit/polkitunixprocess.c
+++ b/src/polkit/polkitunixprocess.c
@@ -28,6 +28,7 @@
 #include "polkitunixprocess.h"
 #include "polkitsubject.h"
 #include "polkitprivate.h"
+#include "polkiterror.h"
 
 /**
  * SECTION:polkitunixprocess
@@ -68,7 +69,8 @@ enum
 
 static void subject_iface_init (PolkitSubjectIface *subject_iface);
 
-static guint64 get_start_time_for_pid (pid_t pid);
+static guint64 get_start_time_for_pid (pid_t    pid,
+                                       GError **error);
 
 G_DEFINE_TYPE_WITH_CODE (PolkitUnixProcess, polkit_unix_process, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, subject_iface_init)
@@ -211,7 +213,7 @@ polkit_unix_process_set_pid (PolkitUnixProcess *process,
 {
   process->pid = pid;
   if (pid != (pid_t) -1)
-    process->start_time = get_start_time_for_pid (pid);
+    process->start_time = get_start_time_for_pid (pid, NULL);
 }
 
 /**
@@ -286,12 +288,81 @@ polkit_unix_process_to_string (PolkitSubject *subject)
   return g_strdup_printf ("unix-process:%d:%" G_GUINT64_FORMAT, process->pid, process->start_time);
 }
 
+static gboolean
+polkit_unix_process_exists_sync (PolkitSubject   *subject,
+                                 GCancellable    *cancellable,
+                                 GError         **error)
+{
+  PolkitUnixProcess *process = POLKIT_UNIX_PROCESS (subject);
+  GError *local_error;
+  guint64 start_time;
+  gboolean ret;
+
+  ret = TRUE;
+
+  local_error = NULL;
+  start_time = get_start_time_for_pid (process->pid, &local_error);
+  if (local_error != NULL)
+    {
+      g_propagate_error (error, local_error);
+      g_error_free (local_error);
+      ret = FALSE;
+    }
+  else
+    {
+      if (start_time != process->start_time)
+        {
+          ret = FALSE;
+          g_set_error (error,
+                       POLKIT_ERROR,
+                       POLKIT_ERROR_FAILED,
+                       "Start times for pid %d do not match",
+                       (gint) process->pid);
+        }
+    }
+
+  return ret;
+}
+
+static void
+polkit_unix_process_exists (PolkitSubject       *subject,
+                            GCancellable        *cancellable,
+                            GAsyncReadyCallback  callback,
+                            gpointer             user_data)
+{
+  GSimpleAsyncResult *simple;
+  simple = g_simple_async_result_new (G_OBJECT (subject),
+                                      callback,
+                                      user_data,
+                                      polkit_unix_process_exists);
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+static gboolean
+polkit_unix_process_exists_finish (PolkitSubject  *subject,
+                                   GAsyncResult   *res,
+                                   GError        **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_unix_process_exists);
+
+  return polkit_unix_process_exists_sync (subject,
+                                          NULL,
+                                          error);
+}
+
+
 static void
 subject_iface_init (PolkitSubjectIface *subject_iface)
 {
-  subject_iface->hash      = polkit_unix_process_hash;
-  subject_iface->equal     = polkit_unix_process_equal;
-  subject_iface->to_string = polkit_unix_process_to_string;
+  subject_iface->hash          = polkit_unix_process_hash;
+  subject_iface->equal         = polkit_unix_process_equal;
+  subject_iface->to_string     = polkit_unix_process_to_string;
+  subject_iface->exists        = polkit_unix_process_exists;
+  subject_iface->exists_finish = polkit_unix_process_exists_finish;
+  subject_iface->exists_sync   = polkit_unix_process_exists_sync;
 }
 
 #ifdef HAVE_SOLARIS
@@ -317,126 +388,78 @@ get_pid_psinfo (pid_t pid, struct psinfo *ps)
 #endif
 
 static guint64
-get_start_time_for_pid (pid_t pid)
+get_start_time_for_pid (pid_t    pid,
+                        GError **error)
 {
   gchar *filename;
   gchar *contents;
   size_t length;
   guint64 start_time;
-  GError *error;
-#ifdef HAVE_SOLARIS
-  struct psinfo info;
-#else
   gchar **tokens;
   guint num_tokens;
   gchar *p;
   gchar *endp;
-#endif
 
   start_time = 0;
   contents = NULL;
 
-#ifdef HAVE_SOLARIS
-  if (polkit_sysdeps_pid_psinfo (pid, &info))
-    {
-      goto out;
-    }
-  start_time = (unsigned long long) (info.pr_start.tv_sec);
-#else
-#ifdef __FreeBSD__
-  filename = g_strdup_printf ("/proc/%d/status", pid);
-#else
   filename = g_strdup_printf ("/proc/%d/stat", pid);
-#endif
 
-  error = NULL;
-  if (!g_file_get_contents (filename, &contents, &length, &error))
-    {
-      g_warning ("Cannot get contents of '%s': %s\n", filename, error->message);
-      goto out;
-    }
-
-#ifdef __FreeBSD__
-  tokens = kit_strsplit (contents, " ", &num_tokens);
-  if (tokens == NULL)
+  if (!g_file_get_contents (filename, &contents, &length, error))
     goto out;
 
-  if (num_tokens < 8)
-    {
-      g_strfreev (tokens);
-      goto out;
-    }
-
-  p = g_strdup (tokens[7]);
-  g_strfreev (tokens);
-
-  tokens = g_strsplit (p, ",", 0);
-  g_free (p);
-
-  if (tokens == NULL)
-    goto out;
-
-  num_tokens = g_strv_length (tokens);
-
-  if (num_tokens >= 1)
-    {
-      start_time = strtoll (tokens[0], &endp, 10);
-      if (endp == tokens[0])
-        {
-          g_strfreev (tokens);
-          goto out;
-        }
-    }
-  else
-    {
-      g_strfreev (tokens);
-      goto out;
-    }
-
-  g_strfreev (tokens);
-
-#else
-
-    /* start time is the 19th token after the '(process name)' entry */
+  /* start time is the 19th token after the '(process name)' entry */
   p = strchr (contents, ')');
   if (p == NULL)
     {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Error parsing file %s",
+                   filename);
       goto out;
     }
   p += 2; /* skip ') ' */
   if (p - contents >= (int) length)
     {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Error parsing file %s",
+                   filename);
       goto out;
     }
 
   tokens = g_strsplit (p, " ", 0);
 
-  if (tokens == NULL)
-    goto out;
-
   num_tokens = g_strv_length (tokens);
 
   if (num_tokens < 20)
-    goto out;
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Error parsing file %s",
+                   filename);
+      goto out;
+    }
 
   start_time = strtoll (tokens[19], &endp, 10);
   if (endp == tokens[19])
-    goto out;
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Error parsing file %s",
+                   filename);
+      goto out;
+    }
 
   g_strfreev (tokens);
-#endif
-#endif
 
  out:
-#ifndef HAVE_SOLARIS
   g_free (filename);
   g_free (contents);
-#endif
-
-  if (start_time == 0)
-    {
-      g_warning ("Cannot lookup start-time for pid %d", pid);
-    }
 
   return start_time;
 }
diff --git a/src/polkit/polkitunixsession.c b/src/polkit/polkitunixsession.c
index 968be2d..fc6a18b 100644
--- a/src/polkit/polkitunixsession.c
+++ b/src/polkit/polkitunixsession.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include "polkitunixsession.h"
 #include "polkitsubject.h"
+#include "polkiterror.h"
 #include "polkitprivate.h"
 
 /**
@@ -48,6 +49,8 @@ struct _PolkitUnixSession
   GObject parent_instance;
 
   gchar *session_id;
+
+  pid_t pid;
 };
 
 struct _PolkitUnixSessionClass
@@ -59,16 +62,21 @@ enum
 {
   PROP_0,
   PROP_SESSION_ID,
+  PROP_PID,
 };
 
-static void subject_iface_init (PolkitSubjectIface *subject_iface);
+static void subject_iface_init        (PolkitSubjectIface *subject_iface);
+static void initable_iface_init       (GInitableIface *initable_iface);
+static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
 
 G_DEFINE_TYPE_WITH_CODE (PolkitUnixSession, polkit_unix_session, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, subject_iface_init)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
                          );
 
 static void
-polkit_unix_session_init (PolkitUnixSession *unix_session)
+polkit_unix_session_init (PolkitUnixSession *session)
 {
 }
 
@@ -117,6 +125,10 @@ polkit_unix_session_set_property (GObject      *object,
       polkit_unix_session_set_session_id (session, g_value_get_string (value));
       break;
 
+    case PROP_PID:
+      session->pid = g_value_get_uint (value);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -149,6 +161,26 @@ polkit_unix_session_class_init (PolkitUnixSessionClass *klass)
                                                         G_PARAM_STATIC_BLURB |
                                                         G_PARAM_STATIC_NICK));
 
+
+  /**
+   * PolkitUnixSession:pid:
+   *
+   * The UNIX process id to look up the session.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_PID,
+                                   g_param_spec_uint ("pid",
+                                                      "Process ID",
+                                                      "Process ID to use for looking up the session",
+                                                      0,
+                                                      G_MAXUINT,
+                                                      0,
+                                                      G_PARAM_CONSTRUCT_ONLY |
+                                                      G_PARAM_WRITABLE |
+                                                      G_PARAM_STATIC_NAME |
+                                                      G_PARAM_STATIC_BLURB |
+                                                      G_PARAM_STATIC_NICK));
+
 }
 
 /**
@@ -197,6 +229,95 @@ polkit_unix_session_new (const gchar *session_id)
                                        NULL));
 }
 
+/**
+ * polkit_unix_session_new_for_process:
+ * @pid: The process id of the process to get the session for.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: The data to pass to @callback.
+ *
+ * Asynchronously creates a new #PolkitUnixSession object for the
+ * process with process id @pid.
+ *
+ * When the operation is finished, @callback will be invoked. You can
+ * then call polkit_unix_session_new_for_process_finish() to get the
+ * result of the operation.
+ *
+ * This method constructs the object asynchronously, for the synchronous and blocking version
+ * use polkit_unix_session_new_for_process_sync().
+ **/
+void
+polkit_unix_session_new_for_process (pid_t               pid,
+                                     GCancellable       *cancellable,
+                                     GAsyncReadyCallback callback,
+                                     gpointer            user_data)
+{
+  g_async_initable_new_async (POLKIT_TYPE_UNIX_SESSION,
+                              G_PRIORITY_DEFAULT,
+                              cancellable,
+                              callback,
+                              user_data,
+                              "pid", pid,
+                              NULL);
+}
+
+/**
+ * polkit_unix_session_new_for_process_finish:
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to polkit_unix_session_new_for_process().
+ * @error: Return location for error.
+ *
+ * Finishes constructing a #PolkitSubject for a process id.
+ *
+ * Returns: A #PolkitUnixSession for the @pid passed to polkit_unix_session_new_for_process() or %NULL
+ *     if @error is set. Free with g_object_unref().
+ **/
+PolkitSubject *
+polkit_unix_session_new_for_process_finish (GAsyncResult   *res,
+                                            GError        **error)
+{
+  GObject *object;
+  GObject *source_object;
+
+  source_object = g_async_result_get_source_object (res);
+  g_assert (source_object != NULL);
+
+  object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
+                                        res,
+                                        error);
+  g_object_unref (source_object);
+
+  if (object != NULL)
+    return POLKIT_SUBJECT (object);
+  else
+    return NULL;
+}
+
+
+/**
+ * polkit_unix_session_new_for_process_sync:
+ * @pid: The process id of the process to get the session for.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error.
+ *
+ * Creates a new #PolkitUnixSession for the process with process id @pid.
+ *
+ * This is a synchronous call that does blocking IO, for the asynchronous version, use
+ * polkit_unix_session_new_for_process().
+ *
+ * Returns: A #PolkitUnixSession for @pid or %NULL if @error is set. Free with g_object_unref().
+ **/
+PolkitSubject *
+polkit_unix_session_new_for_process_sync (pid_t          pid,
+                                          GCancellable  *cancellable,
+                                          GError       **error)
+{
+  return POLKIT_SUBJECT (g_initable_new (POLKIT_TYPE_UNIX_SESSION,
+                                         cancellable,
+                                         error,
+                                         "pid", pid,
+                                         NULL));
+}
+
 static guint
 polkit_unix_session_hash (PolkitSubject *subject)
 {
@@ -227,9 +348,310 @@ polkit_unix_session_to_string (PolkitSubject *subject)
 }
 
 static void
+session_exists_cb (GObject      *source_object,
+                   GAsyncResult *res,
+                   gpointer      user_data)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  EggDBusMessage *reply;
+  GError *error;
+
+  error = NULL;
+  reply = egg_dbus_connection_send_message_with_reply_finish (EGG_DBUS_CONNECTION (source_object),
+                                                              res,
+                                                              &error);
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_error_free (error);
+    }
+  if (reply != NULL)
+    g_object_unref (reply);
+
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+static void
+polkit_unix_session_exists (PolkitSubject       *subject,
+                            GCancellable        *cancellable,
+                            GAsyncReadyCallback  callback,
+                            gpointer             user_data)
+{
+  PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+  EggDBusMessage *message;
+  EggDBusConnection *connection;
+  GSimpleAsyncResult *simple;
+
+  message = NULL;
+  connection = NULL;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.ConsoleKit",
+                                                             session->session_id,
+                                                             "org.freedesktop.ConsoleKit.Session",
+                                                             "GetUser");
+
+  simple = g_simple_async_result_new (G_OBJECT (session),
+                                      callback,
+                                      user_data,
+                                      polkit_unix_session_exists);
+
+  egg_dbus_connection_send_message_with_reply (connection,
+                                               EGG_DBUS_CALL_FLAGS_NONE,
+                                               message,
+                                               NULL,
+                                               cancellable,
+                                               session_exists_cb,
+                                               simple);
+
+  g_object_unref (message);
+  g_object_unref (connection);
+}
+
+static gboolean
+polkit_unix_session_exists_sync (PolkitSubject   *subject,
+                                 GCancellable    *cancellable,
+                                 GError         **error)
+{
+  PolkitUnixSession *session = POLKIT_UNIX_SESSION (subject);
+  EggDBusMessage *message;
+  EggDBusMessage *reply;
+  EggDBusConnection *connection;
+  gboolean ret;
+
+  message = NULL;
+  reply = NULL;
+  connection = NULL;
+  ret = FALSE;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.ConsoleKit",
+                                                             session->session_id,
+                                                             "org.freedesktop.ConsoleKit.Session",
+                                                             "GetUser");
+
+  reply = egg_dbus_connection_send_message_with_reply_sync (connection,
+                                                            EGG_DBUS_CALL_FLAGS_NONE,
+                                                            message,
+                                                            NULL,
+                                                            cancellable,
+                                                            error);
+  if (reply == NULL)
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  if (message != NULL)
+    g_object_unref (message);
+  if (reply != NULL)
+    g_object_unref (reply);
+  if (connection != NULL)
+    g_object_unref (connection);
+
+  return ret;
+}
+
+static gboolean
+polkit_unix_session_exists_finish (PolkitSubject  *subject,
+                                   GAsyncResult   *res,
+                                   GError        **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  gboolean ret;
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_unix_session_exists);
+
+  ret = FALSE;
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  return ret;
+}
+
+static void
 subject_iface_init (PolkitSubjectIface *subject_iface)
 {
-  subject_iface->hash      = polkit_unix_session_hash;
-  subject_iface->equal     = polkit_unix_session_equal;
-  subject_iface->to_string = polkit_unix_session_to_string;
+  subject_iface->hash          = polkit_unix_session_hash;
+  subject_iface->equal         = polkit_unix_session_equal;
+  subject_iface->to_string     = polkit_unix_session_to_string;
+  subject_iface->exists        = polkit_unix_session_exists;
+  subject_iface->exists_finish = polkit_unix_session_exists_finish;
+  subject_iface->exists_sync   = polkit_unix_session_exists_sync;
+}
+
+static gboolean
+polkit_unix_session_initable_init (GInitable     *initable,
+                                   GCancellable  *cancellable,
+                                   GError       **error)
+{
+  PolkitUnixSession *session = POLKIT_UNIX_SESSION (initable);
+  EggDBusMessage *message;
+  EggDBusMessage *reply;
+  EggDBusConnection *connection;
+  gboolean ret;
+
+  message = NULL;
+  reply = NULL;
+  connection = NULL;
+  ret = FALSE;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.ConsoleKit",
+                                                             "/org/freedesktop/ConsoleKit/Manager",
+                                                             "org.freedesktop.ConsoleKit.Manager",
+                                                             "GetSessionForUnixProcess");
+  egg_dbus_message_append_uint (message, session->pid, NULL);
+
+  reply = egg_dbus_connection_send_message_with_reply_sync (connection,
+                                                            EGG_DBUS_CALL_FLAGS_NONE,
+                                                            message,
+                                                            NULL,
+                                                            cancellable,
+                                                            error);
+  if (reply == NULL)
+    goto out;
+
+  if (!egg_dbus_message_extract_object_path (reply, &session->session_id, error))
+    goto out;
+
+  ret = TRUE;
+
+ out:
+  if (message != NULL)
+    g_object_unref (message);
+  if (reply != NULL)
+    g_object_unref (reply);
+  if (connection != NULL)
+    g_object_unref (connection);
+
+  return ret;
+}
+
+static void
+initable_iface_init (GInitableIface *initable_iface)
+{
+  initable_iface->init = polkit_unix_session_initable_init;
+}
+
+static void
+async_init_cb (GObject      *source_object,
+               GAsyncResult *res,
+               gpointer      user_data)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
+  EggDBusMessage *reply;
+  GError *error;
+
+  error = NULL;
+  reply = egg_dbus_connection_send_message_with_reply_finish (EGG_DBUS_CONNECTION (source_object),
+                                                              res,
+                                                              &error);
+
+  if (reply != NULL)
+    {
+      gchar *session_id;
+      if (egg_dbus_message_extract_object_path (reply, &session_id, &error))
+        {
+          g_simple_async_result_set_op_res_gpointer (simple,
+                                                     session_id,
+                                                     g_free);
+        }
+      g_object_unref (reply);
+    }
+
+  if (error != NULL)
+    {
+      g_simple_async_result_set_from_error (simple, error);
+      g_error_free (error);
+    }
+
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+}
+
+static void
+polkit_unix_session_async_initable_init_async (GAsyncInitable      *async_initable,
+                                               gint                 io_priority,
+                                               GCancellable        *cancellable,
+                                               GAsyncReadyCallback  callback,
+                                               gpointer             user_data)
+{
+  PolkitUnixSession *session = POLKIT_UNIX_SESSION (async_initable);
+  EggDBusMessage *message;
+  EggDBusConnection *connection;
+  GSimpleAsyncResult *simple;
+
+  message = NULL;
+  connection = NULL;
+
+  connection = egg_dbus_connection_get_for_bus (EGG_DBUS_BUS_TYPE_SYSTEM);
+
+  message = egg_dbus_connection_new_message_for_method_call (connection,
+                                                             NULL,
+                                                             "org.freedesktop.ConsoleKit",
+                                                             "/org/freedesktop/ConsoleKit/Manager",
+                                                             "org.freedesktop.ConsoleKit.Manager",
+                                                             "GetSessionForUnixProcess");
+  egg_dbus_message_append_uint (message, session->pid, NULL);
+
+  simple = g_simple_async_result_new (G_OBJECT (session),
+                                      callback,
+                                      user_data,
+                                      polkit_unix_session_async_initable_init_async);
+
+  egg_dbus_connection_send_message_with_reply (connection,
+                                               EGG_DBUS_CALL_FLAGS_NONE,
+                                               message,
+                                               NULL,
+                                               cancellable,
+                                               async_init_cb,
+                                               simple);
+
+  g_object_unref (message);
+  g_object_unref (connection);
+}
+
+static gboolean
+polkit_unix_session_async_initable_init_finish (GAsyncInitable   *async_initable,
+                                                GAsyncResult     *res,
+                                                GError          **error)
+{
+  PolkitUnixSession *session = POLKIT_UNIX_SESSION (async_initable);
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+  gboolean ret;
+
+  ret = FALSE;
+
+  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == polkit_unix_session_async_initable_init_async);
+
+  if (g_simple_async_result_propagate_error (simple, error))
+    goto out;
+
+  session->session_id = g_strdup (g_simple_async_result_get_op_res_gpointer (simple));
+  ret = TRUE;
+
+ out:
+  return ret;
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
+{
+  async_initable_iface->init_async = polkit_unix_session_async_initable_init_async;
+  async_initable_iface->init_finish = polkit_unix_session_async_initable_init_finish;
 }
diff --git a/src/polkit/polkitunixsession.h b/src/polkit/polkitunixsession.h
index 949811d..e858094 100644
--- a/src/polkit/polkitunixsession.h
+++ b/src/polkit/polkitunixsession.h
@@ -44,11 +44,20 @@ typedef struct _PolkitUnixSession PolkitUnixSession;
 #endif
 typedef struct _PolkitUnixSessionClass PolkitUnixSessionClass;
 
-GType           polkit_unix_session_get_type       (void) G_GNUC_CONST;
-PolkitSubject  *polkit_unix_session_new            (const gchar       *session_id);
-const gchar    *polkit_unix_session_get_session_id (PolkitUnixSession *session);
-void            polkit_unix_session_set_session_id (PolkitUnixSession *session,
-                                                    const gchar       *session_id);
+GType           polkit_unix_session_get_type               (void) G_GNUC_CONST;
+PolkitSubject  *polkit_unix_session_new                    (const gchar        *session_id);
+void            polkit_unix_session_new_for_process        (pid_t               pid,
+                                                            GCancellable       *cancellable,
+                                                            GAsyncReadyCallback callback,
+                                                            gpointer            user_data);
+PolkitSubject  *polkit_unix_session_new_for_process_finish (GAsyncResult       *res,
+                                                            GError            **error);
+PolkitSubject  *polkit_unix_session_new_for_process_sync   (pid_t               pid,
+                                                            GCancellable       *cancellable,
+                                                            GError            **error);
+const gchar    *polkit_unix_session_get_session_id         (PolkitUnixSession  *session);
+void            polkit_unix_session_set_session_id         (PolkitUnixSession  *session,
+                                                            const gchar        *session_id);
 
 G_END_DECLS
 
diff --git a/src/polkitagent/polkitagentlistener.c b/src/polkitagent/polkitagentlistener.c
index 0251ed4..c2ab69a 100644
--- a/src/polkitagent/polkitagentlistener.c
+++ b/src/polkitagent/polkitagentlistener.c
@@ -70,7 +70,7 @@ struct _Server
 
   PolkitAgentListener *listener;
 
-  gchar *session_id;
+  PolkitSubject *subject;
   gchar *object_path;
 
   GHashTable *cookie_to_pending_auth;
@@ -103,7 +103,7 @@ server_register (Server   *server,
 
   local_error = NULL;
   if (!polkit_authority_register_authentication_agent_sync (server->authority,
-                                                            server->session_id,
+                                                            server->subject,
                                                             g_getenv ("LANG"),
                                                             server->object_path,
                                                             NULL,
@@ -199,7 +199,7 @@ server_finalize (GObject *object)
 
       error = NULL;
       if (!polkit_authority_unregister_authentication_agent_sync (server->authority,
-                                                                  server->session_id,
+                                                                  server->subject,
                                                                   server->object_path,
                                                                   NULL,
                                                                   &error))
@@ -209,7 +209,7 @@ server_finalize (GObject *object)
         }
     }
 
-  g_free (server->session_id);
+  g_object_unref (server->subject);
   g_free (server->object_path);
 
   g_object_unref (server->authority);
@@ -244,15 +244,15 @@ listener_died (gpointer user_data,
 /**
  * polkit_agent_register_listener:
  * @listener: An instance of a class that is derived from #PolkitAgentListener.
- * @session_id: The session id to become an authentication agent for or %NULL for the current session.
+ * @subject: The subject to become an authentication agent for, typically a #PolkitUnixSession object.
  * @object_path: The D-Bus object path to use for the authentication agent or %NULL for the default object path.
  * @error: Return location for error.
  *
- * Registers @listener with the PolicyKit daemon as an authentication agent for @session_id. This
+ * Registers @listener with the PolicyKit daemon as an authentication agent for @subject. This
  * is implemented by registering a D-Bus object at @object_path on the unique name assigned by the
  * system message bus.
  *
- * Whenever the PolicyKit daemon needs to authenticate the user of @session_id for an action, the methods
+ * Whenever the PolicyKit daemon needs to authenticate a processes that is related @subject, the methods
  * polkit_agent_listener_initiate_authentication() and polkit_agent_listener_initiate_authentication_finish()
  * will be invoked on @listener.
  *
@@ -265,14 +265,14 @@ listener_died (gpointer user_data,
  **/
 gboolean
 polkit_agent_register_listener (PolkitAgentListener  *listener,
-                                const gchar          *session_id,
+                                PolkitSubject        *subject,
                                 const gchar          *object_path,
                                 GError              **error)
 {
   Server *server;
 
   server = SERVER (g_object_new (TYPE_SERVER, NULL));
-  server->session_id = g_strdup (session_id);
+  server->subject = g_object_ref (subject);
   server->object_path = object_path != NULL ? g_strdup (object_path) :
                                               g_strdup ("/org/freedesktop/PolicyKit1/AuthenticationAgent");
   server->listener = listener;
diff --git a/src/polkitagent/polkitagentlistener.h b/src/polkitagent/polkitagentlistener.h
index 0f0b295..a20feb8 100644
--- a/src/polkitagent/polkitagentlistener.h
+++ b/src/polkitagent/polkitagentlistener.h
@@ -93,6 +93,7 @@ struct _PolkitAgentListenerClass
 };
 
 GType     polkit_agent_listener_get_type                        (void) G_GNUC_CONST;
+
 void      polkit_agent_listener_initiate_authentication         (PolkitAgentListener  *listener,
                                                                  const gchar          *action_id,
                                                                  const gchar          *message,
@@ -103,14 +104,15 @@ void      polkit_agent_listener_initiate_authentication         (PolkitAgentList
                                                                  GCancellable         *cancellable,
                                                                  GAsyncReadyCallback   callback,
                                                                  gpointer              user_data);
+
 gboolean  polkit_agent_listener_initiate_authentication_finish  (PolkitAgentListener  *listener,
                                                                  GAsyncResult         *res,
                                                                  GError              **error);
 
-gboolean  polkit_agent_register_listener                          (PolkitAgentListener  *listener,
-                                                                   const gchar          *session_id,
-                                                                   const gchar          *object_path,
-                                                                   GError              **error);
+gboolean  polkit_agent_register_listener                        (PolkitAgentListener  *listener,
+                                                                 PolkitSubject        *subject,
+                                                                 const gchar          *object_path,
+                                                                 GError              **error);
 
 G_END_DECLS
 
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
index 93911ca..eec0664 100644
--- a/src/polkitbackend/polkitbackendauthority.c
+++ b/src/polkitbackend/polkitbackendauthority.c
@@ -224,7 +224,7 @@ polkit_backend_authority_check_authorization_finish (PolkitBackendAuthority  *au
  * polkit_backend_authority_register_authentication_agent:
  * @authority: A #PolkitBackendAuthority.
  * @caller: The system bus name that initiated the query.
- * @session_id: The identifier of the session to register for or %NULL for the session of the caller.
+ * @subject: The subject the authentication agent wants to register for.
  * @locale: The locale of the authentication agent.
  * @object_path: The object path for the authentication agent.
  * @error: Return location for error or %NULL.
@@ -236,7 +236,7 @@ polkit_backend_authority_check_authorization_finish (PolkitBackendAuthority  *au
 gboolean
 polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority    *authority,
                                                         PolkitSubject             *caller,
-                                                        const gchar               *session_id,
+                                                        PolkitSubject             *subject,
                                                         const gchar               *locale,
                                                         const gchar               *object_path,
                                                         GError                   **error)
@@ -255,7 +255,7 @@ polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority
     }
   else
     {
-      return klass->register_authentication_agent (authority, caller, session_id, locale, object_path, error);
+      return klass->register_authentication_agent (authority, caller, subject, locale, object_path, error);
     }
 }
 
@@ -263,7 +263,7 @@ polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority
  * polkit_backend_authority_unregister_authentication_agent:
  * @authority: A #PolkitBackendAuthority.
  * @caller: The system bus name that initiated the query.
- * @session_id: The identifier of the session the agent is registered at or %NULL for the session of the caller.
+ * @subject: The subject the agent claims to be registered at.
  * @object_path: The object path that the authentication agent is registered at.
  * @error: Return location for error or %NULL.
  *
@@ -274,7 +274,7 @@ polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority
 gboolean
 polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority    *authority,
                                                           PolkitSubject             *caller,
-                                                          const gchar               *session_id,
+                                                          PolkitSubject             *subject,
                                                           const gchar               *object_path,
                                                           GError                   **error)
 {
@@ -292,7 +292,7 @@ polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority
     }
   else
     {
-      return klass->unregister_authentication_agent (authority, caller, session_id, object_path, error);
+      return klass->unregister_authentication_agent (authority, caller, subject, object_path, error);
     }
 }
 
@@ -336,6 +336,80 @@ polkit_backend_authority_authentication_agent_response (PolkitBackendAuthority
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+/**
+ * polkit_backend_authority_enumerate_temporary_authorizations:
+ * @authority: A #PolkitBackendAuthority.
+ * @caller: The system bus name that initiated the query.
+ * @subject: The subject to get temporary authorizations for.
+ * @error: Return location for error.
+ *
+ * Gets temporary authorizations for @subject.
+ *
+ * Returns: A list of #PolkitTemporaryAuthorization objects or %NULL if @error is set. The returned list
+ * should be freed with g_list_free() after each element have been freed with g_object_unref().
+ */
+GList *
+polkit_backend_authority_enumerate_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                             PolkitSubject            *caller,
+                                                             PolkitSubject            *subject,
+                                                             GError                  **error)
+{
+  PolkitBackendAuthorityClass *klass;
+
+  klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority);
+
+  if (klass->enumerate_temporary_authorizations == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_NOT_SUPPORTED,
+                   "Operation not supported");
+      return NULL;
+    }
+  else
+    {
+      return klass->enumerate_temporary_authorizations (authority, caller, subject, error);
+    }
+}
+
+/**
+ * polkit_backend_authority_revoke_temporary_authorizations:
+ * @authority: A #PolkitBackendAuthority.
+ * @caller: The system bus name that initiated the query.
+ * @subject: The subject to revoke temporary authorizations for.
+ * @error: Return location for error.
+ *
+ * Revokes temporary authorizations for @subject.
+ *
+ * Returns: %TRUE if the operatoin succeeded, %FALSE if @error is set.
+ **/
+gboolean
+polkit_backend_authority_revoke_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                          PolkitSubject            *caller,
+                                                          PolkitSubject            *subject,
+                                                          GError                  **error)
+{
+  PolkitBackendAuthorityClass *klass;
+
+  klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority);
+
+  if (klass->revoke_temporary_authorizations == NULL)
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_NOT_SUPPORTED,
+                   "Operation not supported");
+      return FALSE;
+    }
+  else
+    {
+      return klass->revoke_temporary_authorizations (authority, caller, subject, error);
+    }
+}
+
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 #define TYPE_SERVER         (server_get_type ())
 #define SERVER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_SERVER, Server))
 #define SERVER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), TYPE_SERVER, ServerClass))
@@ -639,21 +713,24 @@ authority_handle_cancel_check_authorization (_PolkitAuthority               *ins
 
 static void
 authority_handle_register_authentication_agent (_PolkitAuthority               *instance,
-                                                const gchar                    *session_id,
+                                                _PolkitSubject                 *real_subject,
                                                 const gchar                    *locale,
                                                 const gchar                    *object_path,
                                                 EggDBusMethodInvocation        *method_invocation)
 {
   Server *server = SERVER (instance);
   PolkitSubject *caller;
+  PolkitSubject *subject;
   GError *error;
 
   caller = polkit_system_bus_name_new (egg_dbus_method_invocation_get_caller (method_invocation));
+  subject = polkit_subject_new_for_real (real_subject);
+  g_object_set_data_full (G_OBJECT (method_invocation), "subject", subject, (GDestroyNotify) g_object_unref);
 
   error = NULL;
   if (!polkit_backend_authority_register_authentication_agent (server->authority,
                                                                caller,
-                                                               session_id,
+                                                               subject,
                                                                locale,
                                                                object_path,
                                                                &error))
@@ -673,20 +750,23 @@ authority_handle_register_authentication_agent (_PolkitAuthority               *
 
 static void
 authority_handle_unregister_authentication_agent (_PolkitAuthority               *instance,
-                                                  const gchar                    *session_id,
+                                                  _PolkitSubject                 *real_subject,
                                                   const gchar                    *object_path,
                                                   EggDBusMethodInvocation        *method_invocation)
 {
   Server *server = SERVER (instance);
   PolkitSubject *caller;
+  PolkitSubject *subject;
   GError *error;
 
   caller = polkit_system_bus_name_new (egg_dbus_method_invocation_get_caller (method_invocation));
+  subject = polkit_subject_new_for_real (real_subject);
+  g_object_set_data_full (G_OBJECT (method_invocation), "subject", subject, (GDestroyNotify) g_object_unref);
 
   error = NULL;
   if (!polkit_backend_authority_unregister_authentication_agent (server->authority,
                                                                  caller,
-                                                                 session_id,
+                                                                 subject,
                                                                  object_path,
                                                                  &error))
     {
@@ -741,14 +821,112 @@ authority_handle_authentication_agent_response (_PolkitAuthority               *
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
+authority_handle_enumerate_temporary_authorizations (_PolkitAuthority        *instance,
+                                                     _PolkitSubject          *real_subject,
+                                                     EggDBusMethodInvocation *method_invocation)
+{
+  Server *server = SERVER (instance);
+  PolkitSubject *caller;
+  EggDBusArraySeq *array;
+  GError *error;
+  GList *temporary_authorizations;
+  GList *l;
+  PolkitSubject *subject;
+
+  error = NULL;
+  caller = NULL;
+  temporary_authorizations = NULL;
+
+  caller = polkit_system_bus_name_new (egg_dbus_method_invocation_get_caller (method_invocation));
+
+  subject = polkit_subject_new_for_real (real_subject);
+  g_object_set_data_full (G_OBJECT (method_invocation), "subject", subject, (GDestroyNotify) g_object_unref);
+
+  temporary_authorizations = polkit_backend_authority_enumerate_temporary_authorizations (server->authority,
+                                                                                          caller,
+                                                                                          subject,
+                                                                                          &error);
+  if (error != NULL)
+    {
+      egg_dbus_method_invocation_return_gerror (method_invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
+  array = egg_dbus_array_seq_new (G_TYPE_OBJECT, //_POLKIT_TYPE_TEMPORARY_AUTHORIZATION,
+                                  (GDestroyNotify) g_object_unref,
+                                  NULL,
+                                  NULL);
+
+  for (l = temporary_authorizations; l != NULL; l = l->next)
+    {
+      PolkitTemporaryAuthorization *ta = POLKIT_TEMPORARY_AUTHORIZATION (l->data);
+      _PolkitTemporaryAuthorization *real;
+
+      real = polkit_temporary_authorization_get_real (ta);
+      egg_dbus_array_seq_add (array, real);
+    }
+
+  _polkit_authority_handle_enumerate_temporary_authorizations_finish (method_invocation, array);
+
+  g_object_unref (array);
+
+ out:
+  g_list_foreach (temporary_authorizations, (GFunc) g_object_unref, NULL);
+  g_list_free (temporary_authorizations);
+  g_object_unref (caller);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+authority_handle_revoke_temporary_authorizations (_PolkitAuthority        *instance,
+                                                  _PolkitSubject          *real_subject,
+                                                  EggDBusMethodInvocation *method_invocation)
+{
+  Server *server = SERVER (instance);
+  PolkitSubject *caller;
+  GError *error;
+  PolkitSubject *subject;
+
+  error = NULL;
+  caller = NULL;
+
+  caller = polkit_system_bus_name_new (egg_dbus_method_invocation_get_caller (method_invocation));
+
+  subject = polkit_subject_new_for_real (real_subject);
+  g_object_set_data_full (G_OBJECT (method_invocation), "subject", subject, (GDestroyNotify) g_object_unref);
+
+  polkit_backend_authority_revoke_temporary_authorizations (server->authority,
+                                                            caller,
+                                                            subject,
+                                                            &error);
+  if (error != NULL)
+    {
+      egg_dbus_method_invocation_return_gerror (method_invocation, error);
+      g_error_free (error);
+      goto out;
+    }
+
+  _polkit_authority_handle_revoke_temporary_authorizations_finish (method_invocation);
+
+ out:
+  g_object_unref (caller);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
 authority_iface_init (_PolkitAuthorityIface *authority_iface)
 {
-  authority_iface->handle_enumerate_actions               = authority_handle_enumerate_actions;
-  authority_iface->handle_check_authorization             = authority_handle_check_authorization;
-  authority_iface->handle_cancel_check_authorization      = authority_handle_cancel_check_authorization;
-  authority_iface->handle_register_authentication_agent   = authority_handle_register_authentication_agent;
-  authority_iface->handle_unregister_authentication_agent = authority_handle_unregister_authentication_agent;
-  authority_iface->handle_authentication_agent_response   = authority_handle_authentication_agent_response;
+  authority_iface->handle_enumerate_actions                  = authority_handle_enumerate_actions;
+  authority_iface->handle_check_authorization                = authority_handle_check_authorization;
+  authority_iface->handle_cancel_check_authorization         = authority_handle_cancel_check_authorization;
+  authority_iface->handle_register_authentication_agent      = authority_handle_register_authentication_agent;
+  authority_iface->handle_unregister_authentication_agent    = authority_handle_unregister_authentication_agent;
+  authority_iface->handle_authentication_agent_response      = authority_handle_authentication_agent_response;
+  authority_iface->handle_enumerate_temporary_authorizations = authority_handle_enumerate_temporary_authorizations;
+  authority_iface->handle_revoke_temporary_authorizations    = authority_handle_revoke_temporary_authorizations;
 }
 
 static void
diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h
index 679ae4c..ca784ef 100644
--- a/src/polkitbackend/polkitbackendauthority.h
+++ b/src/polkitbackend/polkitbackendauthority.h
@@ -86,6 +86,14 @@ struct _PolkitBackendAuthority
  * doesn't support the operation. See
  * polkit_backend_authority_authentication_agent_response() for
  * details.
+ * @enumerate_temporary_authorizations: Called to enumerate temporary
+ * authorizations or %NULL if the backend doesn't support the operation.
+ * See polkit_backend_authority_enumerate_temporary_authorizations()
+ * for details.
+ * @revoke_temporary_authorizations: Called to revoke temporary
+ * authorizations or %NULL if the backend doesn't support the operation.
+ * See polkit_backend_authority_revoke_temporary_authorizations()
+ * for details.
  * @system_bus_name_owner_changed: temporary VFunc, to be removed before 1.0.
  *
  * VFuncs that authority backends need to implement.
@@ -121,14 +129,14 @@ struct _PolkitBackendAuthorityClass
 
   gboolean (*register_authentication_agent) (PolkitBackendAuthority   *authority,
                                              PolkitSubject            *caller,
-                                             const gchar              *session_id,
+                                             PolkitSubject            *subject,
                                              const gchar              *locale,
                                              const gchar              *object_path,
                                              GError                  **error);
 
   gboolean (*unregister_authentication_agent) (PolkitBackendAuthority   *authority,
                                                PolkitSubject            *caller,
-                                               const gchar              *session_id,
+                                               PolkitSubject            *subject,
                                                const gchar              *object_path,
                                                GError                  **error);
 
@@ -138,6 +146,16 @@ struct _PolkitBackendAuthorityClass
                                              PolkitIdentity           *identity,
                                              GError                  **error);
 
+  GList *(*enumerate_temporary_authorizations) (PolkitBackendAuthority   *authority,
+                                                PolkitSubject            *caller,
+                                                PolkitSubject            *subject,
+                                                GError                  **error);
+
+  gboolean (*revoke_temporary_authorizations) (PolkitBackendAuthority   *authority,
+                                               PolkitSubject            *caller,
+                                               PolkitSubject            *subject,
+                                               GError                  **error);
+
   /* TODO: need something more efficient such that we don't watch all name changes */
   void (*system_bus_name_owner_changed)  (PolkitBackendAuthority   *authority,
                                           const gchar              *name,
@@ -210,14 +228,14 @@ PolkitAuthorizationResult *polkit_backend_authority_check_authorization_finish (
 
 gboolean polkit_backend_authority_register_authentication_agent (PolkitBackendAuthority    *authority,
                                                                  PolkitSubject             *caller,
-                                                                 const gchar               *session_id,
+                                                                 PolkitSubject             *subject,
                                                                  const gchar               *locale,
                                                                  const gchar               *object_path,
                                                                  GError                   **error);
 
 gboolean polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority    *authority,
                                                                    PolkitSubject             *caller,
-                                                                   const gchar               *session_id,
+                                                                   PolkitSubject             *subject,
                                                                    const gchar               *object_path,
                                                                    GError                   **error);
 
@@ -227,6 +245,16 @@ gboolean polkit_backend_authority_authentication_agent_response (PolkitBackendAu
                                                                  PolkitIdentity            *identity,
                                                                  GError                   **error);
 
+GList *polkit_backend_authority_enumerate_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                    PolkitSubject            *caller,
+                                                                    PolkitSubject            *subject,
+                                                                    GError                  **error);
+
+gboolean polkit_backend_authority_revoke_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                   PolkitSubject            *caller,
+                                                                   PolkitSubject            *subject,
+                                                                   GError                  **error);
+
 /* --- */
 
 PolkitBackendAuthority *polkit_backend_authority_get (void);
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
index 5cecc85..1677404 100644
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -50,7 +50,7 @@
 
 typedef struct TemporaryAuthorizationStore TemporaryAuthorizationStore;
 
-static TemporaryAuthorizationStore *temporary_authorization_store_new (void);
+static TemporaryAuthorizationStore *temporary_authorization_store_new (PolkitBackendInteractiveAuthority *authority);
 static void                         temporary_authorization_store_free (TemporaryAuthorizationStore *store);
 
 static gboolean temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
@@ -59,6 +59,7 @@ static gboolean temporary_authorization_store_has_authorization (TemporaryAuthor
 
 static void     temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
                                                                  PolkitSubject               *subject,
+                                                                 PolkitSubject               *session,
                                                                  const gchar                 *action_id);
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -92,9 +93,12 @@ static void                authentication_agent_initiate_challenge (Authenticati
                                                                     AuthenticationAgentCallback  callback,
                                                                     gpointer                     user_data);
 
+static PolkitSubject *authentication_agent_get_session (AuthenticationAgent *agent);
+
 static AuthenticationAgent *get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authority,
                                                                   PolkitSubject *subject);
 
+
 static AuthenticationSession *get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *authority,
                                                                      const gchar *cookie);
 
@@ -140,17 +144,17 @@ static PolkitAuthorizationResult *check_authorization_sync (PolkitBackendAuthori
                                                             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);
+                                                                                    PolkitSubject            *caller,
+                                                                                    PolkitSubject            *subject,
+                                                                                    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);
+                                                                                      PolkitSubject            *caller,
+                                                                                      PolkitSubject            *subject,
+                                                                                      const gchar              *object_path,
+                                                                                      GError                  **error);
 
 static gboolean polkit_backend_interactive_authority_authentication_agent_response (PolkitBackendAuthority   *authority,
                                                                               PolkitSubject            *caller,
@@ -158,6 +162,17 @@ static gboolean polkit_backend_interactive_authority_authentication_agent_respon
                                                                               PolkitIdentity           *identity,
                                                                               GError                  **error);
 
+static GList *polkit_backend_interactive_authority_enumerate_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                                       PolkitSubject            *caller,
+                                                                                       PolkitSubject            *subject,
+                                                                                       GError                  **error);
+
+
+static gboolean polkit_backend_interactive_authority_revoke_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                                      PolkitSubject            *caller,
+                                                                                      PolkitSubject            *subject,
+                                                                                      GError                  **error);
+
 
 /* ---------------------------------------------------------------------------------------------------- */
 
@@ -208,7 +223,7 @@ polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *au
                     (GCallback) action_pool_changed,
                     authority);
 
-  priv->temporary_authorization_store = temporary_authorization_store_new ();
+  priv->temporary_authorization_store = temporary_authorization_store_new (authority);
 
   priv->hash_session_to_authentication_agent = g_hash_table_new_full ((GHashFunc) polkit_subject_hash,
                                                                       (GEqualFunc) polkit_subject_equal,
@@ -258,6 +273,9 @@ polkit_backend_interactive_authority_class_init (PolkitBackendInteractiveAuthori
   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;
+  authority_class->enumerate_temporary_authorizations = polkit_backend_interactive_authority_enumerate_temporary_authorizations;
+  authority_class->revoke_temporary_authorizations = polkit_backend_interactive_authority_revoke_temporary_authorizations;
+
 
 
   g_type_class_add_private (klass, sizeof (PolkitBackendInteractiveAuthorityPrivate));
@@ -323,7 +341,10 @@ check_authorization_challenge_cb (AuthenticationAgent         *agent,
         {
           temporary_authorization_store_add_authorization (priv->temporary_authorization_store,
                                                            subject,
+                                                           authentication_agent_get_session (agent),
                                                            action_id);
+          /* we've added a temporary authorization, let the user know */
+          g_signal_emit_by_name (authority, "changed");
         }
     }
   else
@@ -948,6 +969,12 @@ authentication_agent_new_cookie (AuthenticationAgent *agent)
   return g_strdup_printf ("cookie%d", counter++);
 }
 
+static PolkitSubject *
+authentication_agent_get_session (AuthenticationAgent *agent)
+{
+  return agent->session;
+}
+
 static void
 authentication_agent_free (AuthenticationAgent *agent)
 {
@@ -1489,11 +1516,11 @@ authentication_session_cancel (AuthenticationSession *session)
 
 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)
+                                                                    PolkitSubject            *caller,
+                                                                    PolkitSubject            *subject,
+                                                                    const gchar              *locale,
+                                                                    const gchar              *object_path,
+                                                                    GError                  **error)
 {
   PolkitBackendInteractiveAuthority *interactive_authority;
   PolkitBackendInteractiveAuthorityPrivate *priv;
@@ -1507,12 +1534,12 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
   interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
   priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
 
-  if (session_id != NULL && strlen (session_id) > 0)
+  if (!POLKIT_IS_UNIX_SESSION (subject))
     {
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "The session_id parameter must be blank for now.");
+                   "Can only register PolkitUnixSession objects for now.");
       goto out;
     }
 
@@ -1524,7 +1551,16 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "Cannot determine session");
+                   "Cannot determine session the caller is in");
+      goto out;
+    }
+
+  if (!polkit_subject_equal (session_for_caller, subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Passed session and the session the caller is in differs. They must be equal for now.");
       goto out;
     }
 
@@ -1566,10 +1602,10 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
 
 static gboolean
 polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBackendAuthority   *authority,
-                                                                PolkitSubject            *caller,
-                                                                const gchar              *session_id,
-                                                                const gchar              *object_path,
-                                                                GError                  **error)
+                                                                      PolkitSubject            *caller,
+                                                                      PolkitSubject            *subject,
+                                                                      const gchar              *object_path,
+                                                                      GError                  **error)
 {
   PolkitBackendInteractiveAuthority *interactive_authority;
   PolkitBackendInteractiveAuthorityPrivate *priv;
@@ -1583,12 +1619,12 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack
   ret = FALSE;
   session_for_caller = NULL;
 
-  if (session_id != NULL && strlen (session_id) > 0)
+  if (!POLKIT_IS_UNIX_SESSION (subject))
     {
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "The session_id parameter must be blank for now.");
+                   "Can only unregister PolkitUnixSession objects for now.");
       goto out;
     }
 
@@ -1600,7 +1636,16 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "Cannot determine session");
+                   "Cannot determine session the caller is in");
+      goto out;
+    }
+
+  if (!polkit_subject_equal (session_for_caller, subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Passed session and the session the caller is in differs. They must be equal for now.");
       goto out;
     }
 
@@ -1804,43 +1849,41 @@ typedef struct TemporaryAuthorization TemporaryAuthorization;
 struct TemporaryAuthorizationStore
 {
   GList *authorizations;
+  PolkitBackendInteractiveAuthority *authority;
+  guint64 serial;
 };
 
 struct TemporaryAuthorization
 {
+  TemporaryAuthorizationStore *store;
   PolkitSubject *subject;
+  PolkitSubject *session;
+  gchar *id;
   gchar *action_id;
   guint64 time_granted;
+  guint64 time_expires;
+  guint expiration_timeout_id;
 };
 
 static void
 temporary_authorization_free (TemporaryAuthorization *authorization)
 {
+  g_free (authorization->id);
   g_object_unref (authorization->subject);
+  g_object_unref (authorization->session);
   g_free (authorization->action_id);
+  if (authorization->expiration_timeout_id > 0)
+    g_source_remove (authorization->expiration_timeout_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)
+temporary_authorization_store_new (PolkitBackendInteractiveAuthority *authority)
 {
   TemporaryAuthorizationStore *store;
 
   store = g_new0 (TemporaryAuthorizationStore, 1);
+  store->authority = authority;
   store->authorizations = NULL;
 
   return store;
@@ -1883,16 +1926,208 @@ temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *st
   return ret;
 }
 
+static gboolean
+on_expiration_timeout (gpointer user_data)
+{
+  TemporaryAuthorization *authorization = user_data;
+
+  authorization->store->authorizations = g_list_remove (authorization->store->authorizations,
+                                                        authorization);
+  authorization->expiration_timeout_id = 0;
+  g_signal_emit_by_name (authorization->store->authority, "changed");
+  temporary_authorization_free (authorization);
+
+  /* remove source */
+  return FALSE;
+}
+
 static void
 temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
                                                  PolkitSubject               *subject,
+                                                 PolkitSubject               *session,
                                                  const gchar                 *action_id)
 {
+  TemporaryAuthorization *authorization;
+  guint expiration_seconds;
+
   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));
+  /* TODO: right now this is hard-coded - we could make it a propery on the
+   *       PolkitBackendInteractiveAuthority class. Or we could even read
+   *       it per action from an annotation.
+   */
+  expiration_seconds = 5 * 60;
+
+  authorization = g_new0 (TemporaryAuthorization, 1);
+  authorization->id = g_strdup_printf ("tmpauthz%" G_GUINT64_FORMAT, store->serial++);
+  authorization->store = store;
+  authorization->subject = g_object_ref (subject);
+  authorization->session = g_object_ref (session);
+  authorization->action_id = g_strdup (action_id);
+  authorization->time_granted = time (NULL);
+  authorization->time_expires = authorization->time_granted + expiration_seconds;
+  authorization->expiration_timeout_id = g_timeout_add (expiration_seconds * 1000,
+                                                        on_expiration_timeout,
+                                                        authorization);
+
+  store->authorizations = g_list_prepend (store->authorizations, authorization);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static GList *
+polkit_backend_interactive_authority_enumerate_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                         PolkitSubject            *caller,
+                                                                         PolkitSubject            *subject,
+                                                                         GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitSubject *session_for_caller;
+  GList *ret;
+  GList *l;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  ret = NULL;
+  session_for_caller = NULL;
+
+  if (!POLKIT_IS_UNIX_SESSION (subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Can only handle PolkitUnixSession objects 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 the caller is in");
+      goto out;
+    }
+
+  if (!polkit_subject_equal (session_for_caller, subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Passed session and the session the caller is in differs. They must be equal for now.");
+      goto out;
+    }
+
+  for (l = priv->temporary_authorization_store->authorizations; l != NULL; l = l->next)
+    {
+      TemporaryAuthorization *ta = l->data;
+      PolkitTemporaryAuthorization *tmp_authz;
+
+      if (!polkit_subject_equal (ta->session, subject))
+        continue;
+
+      tmp_authz = polkit_temporary_authorization_new (ta->id,
+                                                      ta->action_id,
+                                                      ta->subject,
+                                                      ta->time_granted,
+                                                      ta->time_expires);
+
+      ret = g_list_prepend (ret, tmp_authz);
+    }
+
+ out:
+  if (session_for_caller != NULL)
+    g_object_unref (session_for_caller);
+
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+polkit_backend_interactive_authority_revoke_temporary_authorizations (PolkitBackendAuthority   *authority,
+                                                                      PolkitSubject            *caller,
+                                                                      PolkitSubject            *subject,
+                                                                      GError                  **error)
+{
+  PolkitBackendInteractiveAuthority *interactive_authority;
+  PolkitBackendInteractiveAuthorityPrivate *priv;
+  PolkitSubject *session_for_caller;
+  gboolean ret;
+  GList *l;
+  GList *ll;
+  guint num_removed;
+
+  interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
+  priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
+
+  ret = FALSE;
+  session_for_caller = NULL;
+
+  if (!POLKIT_IS_UNIX_SESSION (subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Can only handle PolkitUnixSession objects 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 the caller is in");
+      goto out;
+    }
+
+  if (!polkit_subject_equal (session_for_caller, subject))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Passed session and the session the caller is in differs. They must be equal for now.");
+      goto out;
+    }
+
+  num_removed = 0;
+  for (l = priv->temporary_authorization_store->authorizations; l != NULL; l = ll)
+    {
+      TemporaryAuthorization *ta = l->data;
+
+      ll = l->next;
+
+      if (!polkit_subject_equal (ta->session, subject))
+        continue;
+
+      priv->temporary_authorization_store->authorizations = g_list_remove (priv->temporary_authorization_store->authorizations, ta);
+      temporary_authorization_free (ta);
+
+      num_removed++;
+    }
+
+  if (num_removed > 0)
+    g_signal_emit_by_name (authority, "changed");
+
+  ret = TRUE;
+
+ out:
+  if (session_for_caller != NULL)
+    g_object_unref (session_for_caller);
+
+  return ret;
 }
+
+/* ---------------------------------------------------------------------------------------------------- */


More information about the hal-commit mailing list