summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2009-07-20 18:49:25 -0400
committerDavid Zeuthen <davidz@redhat.com>2009-07-20 18:49:25 -0400
commit36fc7a6d358c1d373c181191da6265a538a71dae (patch)
tree166630eadb8a659fb9ea988f93d3ff7120d8dd64
parentae8ea087928b7a1bc34b2380872da8867563bec1 (diff)
downloadpolkit-36fc7a6d358c1d373c181191da6265a538a71dae.tar.gz
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).
-rw-r--r--data/org.freedesktop.PolicyKit1.Authority.xml70
-rw-r--r--docs/polkit/polkit-1-docs.xml1
-rw-r--r--docs/polkit/polkit-1-sections.txt34
-rw-r--r--docs/polkit/polkit-1.types1
-rw-r--r--src/polkit/Makefile.am4
-rw-r--r--src/polkit/polkit.h1
-rw-r--r--src/polkit/polkitactiondescription.c2
-rw-r--r--src/polkit/polkitauthority.c235
-rw-r--r--src/polkit/polkitauthority.h38
-rw-r--r--src/polkit/polkitprivate.h3
-rw-r--r--src/polkit/polkitsubject.c68
-rw-r--r--src/polkit/polkitsubject.h48
-rw-r--r--src/polkit/polkitsystembusname.c154
-rw-r--r--src/polkit/polkittemporaryauthorization.c211
-rw-r--r--src/polkit/polkittemporaryauthorization.h61
-rw-r--r--src/polkit/polkittypes.h3
-rw-r--r--src/polkit/polkitunixprocess.c189
-rw-r--r--src/polkit/polkitunixsession.c432
-rw-r--r--src/polkit/polkitunixsession.h19
-rw-r--r--src/polkitagent/polkitagentlistener.c18
-rw-r--r--src/polkitagent/polkitagentlistener.h10
-rw-r--r--src/polkitbackend/polkitbackendauthority.c210
-rw-r--r--src/polkitbackend/polkitbackendauthority.h36
-rw-r--r--src/polkitbackend/polkitbackendinteractiveauthority.c321
24 files changed, 1958 insertions, 211 deletions
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@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@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;
}
+
+/* ---------------------------------------------------------------------------------------------------- */