PolicyKit: Branch 'master'
David Zeuthen
david at kemper.freedesktop.org
Sun Jul 26 19:09:38 PDT 2009
data/org.freedesktop.PolicyKit1.Authority.xml | 12
docs/polkit/polkit-1-sections.txt | 4
src/polkit/polkitauthority.c | 197 ++++++++++++++-
src/polkit/polkitauthority.h | 15 +
src/polkit/polkitauthorizationresult.c | 6
src/polkitbackend/polkitbackendauthority.c | 86 +++++-
src/polkitbackend/polkitbackendauthority.h | 14 +
src/polkitbackend/polkitbackendinteractiveauthority.c | 235 +++++++++++++-----
src/polkitbackend/polkitbackendlocalauthority.c | 14 +
9 files changed, 505 insertions(+), 78 deletions(-)
New commits:
commit de0985aaeb9a44090f3cb37e4ea6308c0152797a
Author: David Zeuthen <davidz at redhat.com>
Date: Sun Jul 26 22:05:38 2009 -0400
Allow unprivileged callers to check authorizations
But only allow this if
- the caller and the subject being checked is the same user
- no details are passed (otherwise dialogs can be spoofed)
Also add a RevokeTemporaryAuthorizationById() method.
diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
index 6b29e8e..9b49334 100644
--- a/data/org.freedesktop.PolicyKit1.Authority.xml
+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
@@ -129,7 +129,7 @@
</annotation>
<annotation name="org.gtk.EggDBus.Struct.Member" value="Dict<String,String>:details">
- <annotation name="org.gtk.EggDBus.DocString" value="Details for the result or empty if not authorized."/>
+ <annotation name="org.gtk.EggDBus.DocString" value="Details for the result or empty if not authorized. Known key/value-pairs include <literal>polkit.temporary_authorization_id</literal> (if the authorization is temporary, this is set to the opaque temporary authorization id)."/>
</annotation>
</annotation>
@@ -223,7 +223,7 @@
</arg>
<arg name="details" direction="in" type="a{ss}">
- <annotation name="org.gtk.EggDBus.DocString" value="Details describing the action."/>
+ <annotation name="org.gtk.EggDBus.DocString" value="Details describing the action. Keys starting with <literal>polkit.</literal> are reserved for internal use and cannot be used."/>
</arg>
<arg name="flags" direction="in" type="u">
@@ -348,6 +348,14 @@
</arg>
</method>
+ <method name="RevokeTemporaryAuthorizationById">
+ <annotation name="org.gtk.EggDBus.DocString" value="Revokes all temporary authorizations that applies to @subject."/>
+
+ <arg name="id" direction="in" type="s">
+ <annotation name="org.gtk.EggDBus.DocString" value="The opaque identifier of the temporary authorization."/>
+ </arg>
+ </method>
+
<!-- ---------------------------------------------------------------------------------------------------- -->
<signal name="Changed">
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
index f096d2d..c06a55a 100644
--- a/docs/polkit/polkit-1-sections.txt
+++ b/docs/polkit/polkit-1-sections.txt
@@ -35,6 +35,8 @@ polkit_authority_enumerate_temporary_authorizations
polkit_authority_enumerate_temporary_authorizations_finish
polkit_authority_revoke_temporary_authorizations
polkit_authority_revoke_temporary_authorizations_finish
+polkit_authority_revoke_temporary_authorization_by_id
+polkit_authority_revoke_temporary_authorization_by_id_finish
polkit_authority_check_authorization_sync
polkit_authority_enumerate_actions_sync
polkit_authority_register_authentication_agent_sync
@@ -42,6 +44,7 @@ polkit_authority_unregister_authentication_agent_sync
polkit_authority_authentication_agent_response_sync
polkit_authority_enumerate_temporary_authorizations_sync
polkit_authority_revoke_temporary_authorizations_sync
+polkit_authority_revoke_temporary_authorization_by_id_sync
<SUBSECTION Standard>
PolkitAuthorityClass
POLKIT_AUTHORITY
@@ -439,7 +442,6 @@ POLKIT_AGENT_LISTENER_GET_CLASS
<FILE>polkittemporaryauthorization</FILE>
<TITLE>PolkitTemporaryAuthorization</TITLE>
PolkitTemporaryAuthorization
-PolkitTemporaryAuthorizationClass
polkit_temporary_authorization_get_id
polkit_temporary_authorization_get_action_id
polkit_temporary_authorization_get_subject
diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
index 4d34b16..7d2c235 100644
--- a/src/polkit/polkitauthority.c
+++ b/src/polkit/polkitauthority.c
@@ -396,7 +396,8 @@ polkit_authority_check_authorization_async (PolkitAuthority *autho
* @authority: A #PolkitAuthority.
* @subject: A #PolkitSubject.
* @action_id: The action to check for.
- * @details: Details about the action or %NULL.
+ * @details: Details about the action or %NULL. Keys starting with <literal>polkit.</literal> are reserved
+ * for internal use and cannot be used.
* @flags: A set of #PolkitCheckAuthorizationFlags.
* @cancellable: A #GCancellable or %NULL.
* @callback: A #GAsyncReadyCallback to call when the request is satisfied.
@@ -528,7 +529,8 @@ polkit_authority_check_authorization_finish (PolkitAuthority *authority
* @authority: A #PolkitAuthority.
* @subject: A #PolkitSubject.
* @action_id: The action to check for.
- * @details: Details about the action or %NULL.
+ * @details: Details about the action or %NULL. Keys starting with <literal>polkit.</literal> are reserved
+ * for internal use and cannot be used.
* @flags: A set of #PolkitCheckAuthorizationFlags.
* @cancellable: A #GCancellable or %NULL.
* @error: Return location for error or %NULL.
@@ -1035,6 +1037,20 @@ polkit_authority_enumerate_temporary_authorizations_async (PolkitAuthority *
return call_id;
}
+/**
+ * polkit_authority_enumerate_temporary_authorizations:
+ * @authority: A #PolkitAuthority.
+ * @subject: A #PolkitSubject, typically a #PolkitUnixSession.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: The data to pass to @callback.
+ *
+ * Asynchronously gets all temporary authorizations for @subject.
+ *
+ * When the operation is finished, @callback will be invoked. You can then
+ * call polkit_authority_enumerate_temporary_authorizations_finish() to get the result of
+ * the operation.
+ **/
void
polkit_authority_enumerate_temporary_authorizations (PolkitAuthority *authority,
PolkitSubject *subject,
@@ -1045,6 +1061,17 @@ polkit_authority_enumerate_temporary_authorizations (PolkitAuthority *author
polkit_authority_enumerate_temporary_authorizations_async (authority, subject, cancellable, callback, user_data);
}
+/**
+ * polkit_authority_enumerate_temporary_authorizations_finish:
+ * @authority: A #PolkitAuthority.
+ * @res: A #GAsyncResult obtained from the callback.
+ * @error: Return location for error or %NULL.
+ *
+ * Finishes retrieving all registered actions.
+ *
+ * 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_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *authority,
GAsyncResult *res,
@@ -1087,6 +1114,18 @@ polkit_authority_enumerate_temporary_authorizations_finish (PolkitAuthority *aut
return result;
}
+/**
+ * polkit_authority_enumerate_temporary_authorizations_sync:
+ * @authority: A #PolkitAuthority.
+ * @subject: A #PolkitSubject, typically a #PolkitUnixSession.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronousky gets all 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_authority_enumerate_temporary_authorizations_sync (PolkitAuthority *authority,
PolkitSubject *subject,
@@ -1140,6 +1179,20 @@ polkit_authority_revoke_temporary_authorizations_async (PolkitAuthority *aut
return call_id;
}
+/**
+ * polkit_authority_revoke_temporary_authorizations:
+ * @authority: A #PolkitAuthority.
+ * @subject: The subject to revoke authorizations from, typically a #PolkitUnixSession.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: The data to pass to @callback.
+ *
+ * Asynchronously revokes all temporary authorizations for @subject.
+ *
+ * When the operation is finished, @callback will be invoked. You can then
+ * call polkit_authority_revoke_temporary_authorizations_finish() to get the result of
+ * the operation.
+ **/
void
polkit_authority_revoke_temporary_authorizations (PolkitAuthority *authority,
PolkitSubject *subject,
@@ -1150,6 +1203,16 @@ polkit_authority_revoke_temporary_authorizations (PolkitAuthority *authority
polkit_authority_revoke_temporary_authorizations_async (authority, subject, cancellable, callback, user_data);
}
+/**
+ * polkit_authority_revoke_temporary_authorizations_finish:
+ * @authority: A #PolkitAuthority.
+ * @res: A #GAsyncResult obtained from the callback.
+ * @error: Return location for error or %NULL.
+ *
+ * Finished revoking temporary authorizations.
+ *
+ * Returns: %TRUE if all the temporary authorizations was revoked, %FALSE if error is set.
+ **/
gboolean
polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *authority,
GAsyncResult *res,
@@ -1176,6 +1239,17 @@ polkit_authority_revoke_temporary_authorizations_finish (PolkitAuthority *author
return ret;
}
+/**
+ * polkit_authority_revoke_temporary_authorizations_sync:
+ * @authority: A #PolkitAuthority.
+ * @subject: The subject to revoke authorizations from, typically a #PolkitUnixSession.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronously revokes all temporary authorization from @subject.
+ *
+ * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
+ **/
gboolean
polkit_authority_revoke_temporary_authorizations_sync (PolkitAuthority *authority,
PolkitSubject *subject,
@@ -1198,3 +1272,122 @@ polkit_authority_revoke_temporary_authorizations_sync (PolkitAuthority *auth
}
/* ---------------------------------------------------------------------------------------------------- */
+
+static guint
+polkit_authority_revoke_temporary_authorization_by_id_async (PolkitAuthority *authority,
+ const gchar *id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ guint call_id;
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (G_OBJECT (authority),
+ callback,
+ user_data,
+ polkit_authority_revoke_temporary_authorizations_async);
+
+ call_id = _polkit_authority_revoke_temporary_authorization_by_id (authority->real,
+ EGG_DBUS_CALL_FLAGS_NONE,
+ id,
+ cancellable,
+ generic_async_cb,
+ simple);
+
+ return call_id;
+}
+
+/**
+ * polkit_authority_revoke_temporary_authorization_by_id:
+ * @authority: A #PolkitAuthority.
+ * @id: The opaque identifier for the temporary authorization.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
+ * @user_data: The data to pass to @callback.
+ *
+ * Asynchronously revoke a temporary authorization.
+ *
+ * When the operation is finished, @callback will be invoked. You can then
+ * call polkit_authority_revoke_temporary_authorization_by_id_finish() to get the result of
+ * the operation.
+ */
+void
+polkit_authority_revoke_temporary_authorization_by_id (PolkitAuthority *authority,
+ const gchar *id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ polkit_authority_revoke_temporary_authorization_by_id_async (authority, id, cancellable, callback, user_data);
+}
+
+/**
+ * polkit_authority_revoke_temporary_authorization_by_id_finish:
+ * @authority: A #PolkitAuthority.
+ * @res: A #GAsyncResult obtained from the callback.
+ * @error: Return location for error or %NULL.
+ *
+ * Finished revoking a temporary authorization by id.
+ *
+ * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
+ **/
+gboolean
+polkit_authority_revoke_temporary_authorization_by_id_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_authorization_by_id_finish (authority->real,
+ real_res,
+ error);
+
+ if (!ret)
+ goto out;
+
+ out:
+ g_object_unref (real_res);
+ return ret;
+}
+
+/**
+ * polkit_authority_revoke_temporary_authorization_by_id_sync:
+ * @authority: A #PolkitAuthority.
+ * @id: The opaque identifier for the temporary authorization.
+ * @cancellable: A #GCancellable or %NULL.
+ * @error: Return location for error or %NULL.
+ *
+ * Synchronously revokes a temporary authorization.
+ *
+ * Returns: %TRUE if the temporary authorization was revoked, %FALSE if error is set.
+ **/
+gboolean
+polkit_authority_revoke_temporary_authorization_by_id_sync (PolkitAuthority *authority,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error)
+{
+ guint call_id;
+ GAsyncResult *res;
+ gboolean result;
+
+ call_id = polkit_authority_revoke_temporary_authorization_by_id_async (authority, id, cancellable, generic_cb, &res);
+
+ egg_dbus_connection_pending_call_block (authority->system_bus, call_id);
+
+ result = polkit_authority_revoke_temporary_authorization_by_id_finish (authority, res, error);
+
+ g_object_unref (res);
+
+ return result;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkit/polkitauthority.h b/src/polkit/polkitauthority.h
index 61a6e7c..e45b3a1 100644
--- a/src/polkit/polkitauthority.h
+++ b/src/polkit/polkitauthority.h
@@ -99,6 +99,11 @@ gboolean polkit_authority_revoke_temporary_authorizations_sync
GCancellable *cancellable,
GError **error);
+gboolean polkit_authority_revoke_temporary_authorization_by_id_sync (PolkitAuthority *authority,
+ const gchar *id,
+ GCancellable *cancellable,
+ GError **error);
+
/* ---------------------------------------------------------------------------------------------------- */
void polkit_authority_enumerate_actions (PolkitAuthority *authority,
@@ -177,6 +182,16 @@ gboolean polkit_authority_revoke_temporary_authorizations_fini
GAsyncResult *res,
GError **error);
+void polkit_authority_revoke_temporary_authorization_by_id (PolkitAuthority *authority,
+ const gchar *id,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean polkit_authority_revoke_temporary_authorization_by_id_finish (PolkitAuthority *authority,
+ GAsyncResult *res,
+ GError **error);
+
/* ---------------------------------------------------------------------------------------------------- */
G_END_DECLS
diff --git a/src/polkit/polkitauthorizationresult.c b/src/polkit/polkitauthorizationresult.c
index 6786a5a..08911ef 100644
--- a/src/polkit/polkitauthorizationresult.c
+++ b/src/polkit/polkitauthorizationresult.c
@@ -187,6 +187,12 @@ polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result)
*
* Gets the details about the result.
*
+ * If the authorization is temporary the opaque identifier for the
+ * temporary authorization
+ * (cf. polkit_temporary_authorization_get_id()) is set available as
+ * the value for the
+ * <literal>polkit.temporary_authorization_id</literal> key.
+ *
* Returns: A #PolkitDetails object. This object is owned by @result
* and should not be freed by the caller.
*/
diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
index eec0664..63caf0f 100644
--- a/src/polkitbackend/polkitbackendauthority.c
+++ b/src/polkitbackend/polkitbackendauthority.c
@@ -381,7 +381,7 @@ polkit_backend_authority_enumerate_temporary_authorizations (PolkitBackendAuthor
*
* Revokes temporary authorizations for @subject.
*
- * Returns: %TRUE if the operatoin succeeded, %FALSE if @error is set.
+ * Returns: %TRUE if the operation succeeded, %FALSE if @error is set.
**/
gboolean
polkit_backend_authority_revoke_temporary_authorizations (PolkitBackendAuthority *authority,
@@ -407,6 +407,41 @@ polkit_backend_authority_revoke_temporary_authorizations (PolkitBackendAuthority
}
}
+/**
+ * polkit_backend_authority_revoke_temporary_authorization_by_id:
+ * @authority: A #PolkitBackendAuthority.
+ * @caller: The system bus name that initiated the query.
+ * @id: The opaque identifier of the temporary authorization.
+ * @error: Return location for error.
+ *
+ * Revokes a temporary authorizations with opaque identifier @id.
+ *
+ * Returns: %TRUE if the operatoin succeeded, %FALSE if @error is set.
+ **/
+gboolean
+polkit_backend_authority_revoke_temporary_authorization_by_id (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *id,
+ GError **error)
+{
+ PolkitBackendAuthorityClass *klass;
+
+ klass = POLKIT_BACKEND_AUTHORITY_GET_CLASS (authority);
+
+ if (klass->revoke_temporary_authorization_by_id == NULL)
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_SUPPORTED,
+ "Operation not supported");
+ return FALSE;
+ }
+ else
+ {
+ return klass->revoke_temporary_authorization_by_id (authority, caller, id, error);
+ }
+}
+
/* ---------------------------------------------------------------------------------------------------- */
@@ -917,16 +952,49 @@ authority_handle_revoke_temporary_authorizations (_PolkitAuthority *insta
/* ---------------------------------------------------------------------------------------------------- */
static void
+authority_handle_revoke_temporary_authorization_by_id (_PolkitAuthority *instance,
+ const gchar *id,
+ EggDBusMethodInvocation *method_invocation)
+{
+ Server *server = SERVER (instance);
+ GError *error;
+ PolkitSubject *caller;
+
+ error = NULL;
+
+ caller = polkit_system_bus_name_new (egg_dbus_method_invocation_get_caller (method_invocation));
+
+ polkit_backend_authority_revoke_temporary_authorization_by_id (server->authority,
+ caller,
+ id,
+ &error);
+ if (error != NULL)
+ {
+ egg_dbus_method_invocation_return_gerror (method_invocation, error);
+ g_error_free (error);
+ goto out;
+ }
+
+ _polkit_authority_handle_revoke_temporary_authorization_by_id_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_temporary_authorizations = authority_handle_enumerate_temporary_authorizations;
- authority_iface->handle_revoke_temporary_authorizations = authority_handle_revoke_temporary_authorizations;
+ 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;
+ authority_iface->handle_revoke_temporary_authorization_by_id = authority_handle_revoke_temporary_authorization_by_id;
}
static void
diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h
index ca784ef..56d46be 100644
--- a/src/polkitbackend/polkitbackendauthority.h
+++ b/src/polkitbackend/polkitbackendauthority.h
@@ -94,6 +94,10 @@ struct _PolkitBackendAuthority
* authorizations or %NULL if the backend doesn't support the operation.
* See polkit_backend_authority_revoke_temporary_authorizations()
* for details.
+ * @revoke_temporary_authorization_by_id: Called to revoke a temporary
+ * authorization identified by id or %NULL if the backend doesn't support
+ * the operation. See polkit_backend_authority_revoke_temporary_authorization_by_id()
+ * for details.
* @system_bus_name_owner_changed: temporary VFunc, to be removed before 1.0.
*
* VFuncs that authority backends need to implement.
@@ -156,6 +160,11 @@ struct _PolkitBackendAuthorityClass
PolkitSubject *subject,
GError **error);
+ gboolean (*revoke_temporary_authorization_by_id) (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *id,
+ 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,
@@ -255,6 +264,11 @@ gboolean polkit_backend_authority_revoke_temporary_authorizations (PolkitBackend
PolkitSubject *subject,
GError **error);
+gboolean polkit_backend_authority_revoke_temporary_authorization_by_id (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *id,
+ GError **error);
+
/* --- */
PolkitBackendAuthority *polkit_backend_authority_get (void);
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
index 1677404..af58ed3 100644
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -55,12 +55,13 @@ static void temporary_authorization_store_free (Temporar
static gboolean temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
PolkitSubject *subject,
- const gchar *action_id);
+ const gchar *action_id,
+ const gchar **out_tmp_authz_id);
-static void temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
- PolkitSubject *subject,
- PolkitSubject *session,
- const gchar *action_id);
+static const gchar *temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
+ PolkitSubject *subject,
+ PolkitSubject *session,
+ const gchar *action_id);
/* ---------------------------------------------------------------------------------------------------- */
@@ -173,6 +174,11 @@ static gboolean polkit_backend_interactive_authority_revoke_temporary_authorizat
PolkitSubject *subject,
GError **error);
+static gboolean polkit_backend_interactive_authority_revoke_temporary_authorization_by_id (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *id,
+ GError **error);
+
/* ---------------------------------------------------------------------------------------------------- */
@@ -275,6 +281,7 @@ polkit_backend_interactive_authority_class_init (PolkitBackendInteractiveAuthori
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;
+ authority_class->revoke_temporary_authorization_by_id = polkit_backend_interactive_authority_revoke_temporary_authorization_by_id;
@@ -333,19 +340,29 @@ check_authorization_challenge_cb (AuthenticationAgent *agent,
if (authentication_success)
{
- result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+ PolkitDetails *details;
+
+ details = polkit_details_new ();
/* store temporary authorization depending on value of implicit_authorization */
if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED ||
implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
{
- temporary_authorization_store_add_authorization (priv->temporary_authorization_store,
- subject,
- authentication_agent_get_session (agent),
- action_id);
+ const gchar *id;
+
+ id = temporary_authorization_store_add_authorization (priv->temporary_authorization_store,
+ subject,
+ authentication_agent_get_session (agent),
+ action_id);
+
+ polkit_details_insert (details, "polkit.temporary_authorization_id", id);
+
/* we've added a temporary authorization, let the user know */
g_signal_emit_by_name (authority, "changed");
}
+
+ result = polkit_authorization_result_new (TRUE, FALSE, details);
+ g_object_unref (details);
}
else
{
@@ -387,14 +404,14 @@ polkit_backend_interactive_authority_check_authorization_finish (PolkitBackendAu
static void
polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
- PolkitSubject *subject,
- const gchar *action_id,
- PolkitDetails *details,
- PolkitCheckAuthorizationFlags flags,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ PolkitSubject *caller,
+ PolkitSubject *subject,
+ const gchar *action_id,
+ PolkitDetails *details,
+ PolkitCheckAuthorizationFlags flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
PolkitBackendInteractiveAuthority *interactive_authority;
PolkitBackendInteractiveAuthorityPrivate *priv;
@@ -408,6 +425,8 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
PolkitImplicitAuthorization implicit_authorization;
GError *error;
GSimpleAsyncResult *simple;
+ gboolean has_details;
+ gchar **detail_keys;
interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
@@ -449,20 +468,6 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
user_of_caller_str = polkit_identity_to_string (user_of_caller);
g_debug (" user of caller is %s", user_of_caller_str);
- /* we only allow trusted callers (uid 0 + others) to check authorizations */
- if (!POLKIT_IS_UNIX_USER (user_of_caller) ||
- polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0) /* TODO: allow other uids like 'haldaemon'? */
- {
- g_simple_async_result_set_error (simple,
- POLKIT_ERROR,
- POLKIT_ERROR_NOT_AUTHORIZED,
- "Only trusted callers can use CheckAuthorization(), %s is not trusted",
- user_of_caller_str);
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
-
user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor,
subject,
&error);
@@ -478,6 +483,38 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority
user_of_subject_str = polkit_identity_to_string (user_of_subject);
g_debug (" user of subject is %s", user_of_subject_str);
+ has_details = FALSE;
+ if (details != NULL)
+ {
+ detail_keys = polkit_details_get_keys (details);
+ if (detail_keys != NULL)
+ {
+ if (g_strv_length (detail_keys) > 0)
+ has_details = TRUE;
+ g_strfreev (detail_keys);
+ }
+ }
+ if (!polkit_identity_equal (user_of_caller, user_of_subject) || has_details)
+ {
+ /* we only allow trusted callers (uid 0 + others) to check authorizations for subjects
+ * they don't own - and only if there are no details passed (to avoid spoofing dialogs).
+ *
+ * TODO: allow other uids like 'haldaemon'?
+ */
+ if (!POLKIT_IS_UNIX_USER (user_of_caller) ||
+ polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) != 0)
+ {
+ g_simple_async_result_set_error (simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_NOT_AUTHORIZED,
+ "Only trusted callers can use CheckAuthorization() for subjects "
+ "belonging to other identities and/or pass details");
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+ goto out;
+ }
+ }
+
implicit_authorization = POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED;
result = check_authorization_sync (authority,
caller,
@@ -571,6 +608,7 @@ check_authorization_sync (PolkitBackendAuthority *authority,
gboolean session_is_local;
gboolean session_is_active;
PolkitImplicitAuthorization implicit_authorization;
+ const gchar *tmp_authz_id;
interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
@@ -673,37 +711,19 @@ check_authorization_sync (PolkitBackendAuthority *authority,
/* then see if there's a temporary authorization for the subject */
if (temporary_authorization_store_has_authorization (priv->temporary_authorization_store,
subject,
- action_id))
+ action_id,
+ &tmp_authz_id))
{
- g_debug (" is authorized (has temporary authorization)");
- result = polkit_authorization_result_new (TRUE, FALSE, NULL);
- goto out;
- }
+ PolkitDetails *details;
-#if 0
- /* then see if we have an authorization for the user */
- if (check_authorization_for_identity (interactive_authority, user_of_subject, action_id))
- {
- g_debug (" is authorized (user identity has authorization)");
- result = polkit_authorization_result_new (TRUE, FALSE, NULL);
+ g_debug (" is authorized (has temporary authorization)");
+ details = polkit_details_new ();
+ polkit_details_insert (details, "polkit.temporary_authorization_id", tmp_authz_id);
+ result = polkit_authorization_result_new (TRUE, FALSE, details);
+ g_object_unref (details);
goto out;
}
- /* then see if we have a permanent authorization for any of the groups the user is in */
- groups_of_user = get_groups_for_user (interactive_authority, user_of_subject);
- for (l = groups_of_user; l != NULL; l = l->next)
- {
- PolkitIdentity *group = POLKIT_IDENTITY (l->data);
-
- if (check_authorization_for_identity (interactive_authority, group, action_id))
- {
- g_debug (" is authorized (group identity has authorization)");
- result = polkit_authorization_result_new (TRUE, FALSE, NULL);
- goto out;
- }
- }
-#endif
-
if (implicit_authorization != POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED)
{
result = polkit_authorization_result_new (FALSE, TRUE, NULL);
@@ -1900,7 +1920,8 @@ temporary_authorization_store_free (TemporaryAuthorizationStore *store)
static gboolean
temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store,
PolkitSubject *subject,
- const gchar *action_id)
+ const gchar *action_id,
+ const gchar **out_tmp_authz_id)
{
GList *l;
gboolean ret;
@@ -1918,6 +1939,8 @@ temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *st
polkit_subject_equal (subject, authorization->subject))
{
ret = TRUE;
+ if (out_tmp_authz_id != NULL)
+ *out_tmp_authz_id = authorization->id;
goto out;
}
}
@@ -1941,7 +1964,7 @@ on_expiration_timeout (gpointer user_data)
return FALSE;
}
-static void
+static const gchar *
temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *store,
PolkitSubject *subject,
PolkitSubject *session,
@@ -1950,10 +1973,10 @@ temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *st
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));
+ g_return_val_if_fail (store != NULL, NULL);
+ g_return_val_if_fail (POLKIT_IS_SUBJECT (subject), NULL);
+ g_return_val_if_fail (action_id != NULL, NULL);
+ g_return_val_if_fail (!temporary_authorization_store_has_authorization (store, subject, action_id, NULL), NULL);
/* TODO: right now this is hard-coded - we could make it a propery on the
* PolkitBackendInteractiveAuthority class. Or we could even read
@@ -1974,6 +1997,8 @@ temporary_authorization_store_add_authorization (TemporaryAuthorizationStore *st
authorization);
store->authorizations = g_list_prepend (store->authorizations, authorization);
+
+ return authorization->id;
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -2131,3 +2156,85 @@ polkit_backend_interactive_authority_revoke_temporary_authorizations (PolkitBack
}
/* ---------------------------------------------------------------------------------------------------- */
+
+static gboolean
+polkit_backend_interactive_authority_revoke_temporary_authorization_by_id (PolkitBackendAuthority *authority,
+ PolkitSubject *caller,
+ const gchar *id,
+ 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;
+
+ 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;
+ }
+
+ num_removed = 0;
+ for (l = priv->temporary_authorization_store->authorizations; l != NULL; l = ll)
+ {
+ TemporaryAuthorization *ta = l->data;
+
+ ll = l->next;
+
+ if (strcmp (ta->id, id) != 0)
+ continue;
+
+ if (!polkit_subject_equal (session_for_caller, ta->session))
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Cannot remove a temporary authorization belonging to another subject.");
+ goto out;
+ }
+
+ 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");
+ }
+ else
+ {
+ g_set_error (error,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "No such authorization with id `%s'",
+ id);
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ if (session_for_caller != NULL)
+ g_object_unref (session_for_caller);
+
+ return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index 06073cf..e100c56 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -95,6 +95,15 @@ G_DEFINE_TYPE_WITH_CODE (PolkitBackendLocalAuthority,
/* ---------------------------------------------------------------------------------------------------- */
static void
+on_store_changed (PolkitBackendLocalAuthorizationStore *store,
+ gpointer user_data)
+{
+ PolkitBackendLocalAuthority *authority = POLKIT_BACKEND_LOCAL_AUTHORITY (user_data);
+
+ g_signal_emit_by_name (authority, "changed");
+}
+
+static void
polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
{
PolkitBackendLocalAuthorityPrivate *priv;
@@ -124,6 +133,11 @@ polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
store = polkit_backend_local_authorization_store_new (directory, ".pkla");
priv->authorization_stores = g_list_prepend (priv->authorization_stores, store);
g_object_unref (directory);
+
+ g_signal_connect (store,
+ "changed",
+ G_CALLBACK (on_store_changed),
+ authority);
}
priv->authorization_stores = g_list_reverse (priv->authorization_stores);
}
More information about the hal-commit
mailing list