Commit b891d8a3 authored by David Zeuthen's avatar David Zeuthen

add the ObtainAuthorization() method and use in for the 'polkit-1 run' command

Also add an example for this.
parent 21e21e97
......@@ -6,6 +6,8 @@
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Authority Interface"/>
<annotation name="org.gtk.EggDBus.DocString" value="This D-Bus interface is implemented by the <literal>/org/freedesktop/PoliycKit1/Authority</literal> object on the well-known name <literal>org.freedesktop.PolicyKit1</literal> on the system message bus."/>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- Subject struct -->
<annotation name="org.gtk.EggDBus.DeclareStruct" value="Subject">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Subjects"/>
......@@ -21,6 +23,8 @@
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- Identity struct -->
<annotation name="org.gtk.EggDBus.DeclareStruct" value="Identity">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Subjects"/>
......@@ -38,6 +42,8 @@
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- ActionDescription struct -->
<annotation name="org.gtk.EggDBus.DeclareStruct" value="ActionDescription">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Actions"/>
......@@ -88,6 +94,8 @@
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- Flags used for checking authorizations -->
<annotation name="org.gtk.EggDBus.DeclareFlags" value="CheckAuthorizationFlags">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Flags used when checking authorizations"/>
......@@ -98,6 +106,8 @@
</annotation>
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- An enumeration for results when checking for an authorization -->
<annotation name="org.gtk.EggDBus.DeclareEnum" value="AuthorizationResult">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Possible results for checking authorizations"/>
......@@ -114,6 +124,8 @@
</annotation>
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- An enumeration for implicit authorizations -->
<annotation name="org.gtk.EggDBus.DeclareEnum" value="ImplicitAuthorization">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Implicit authorizations"/>
......@@ -145,6 +157,8 @@
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<!-- The error domain used for reporting errors -->
<annotation name="org.gtk.EggDBus.DeclareErrorDomain" value="Error">
<annotation name="org.gtk.EggDBus.DocString.Summary" value="Errors"/>
......@@ -170,6 +184,8 @@
</annotation>
</annotation>
<!-- ---------------------------------------------------------------------------------------------------- -->
<method name="EnumerateActions">
<annotation name="org.gtk.EggDBus.DocString" value="Enumerates all registered PolicyKit actions."/>
......@@ -183,6 +199,8 @@
</arg>
</method>
<!-- ---------------------------------------------------------------------------------------------------- -->
<method name="CheckAuthorization">
<annotation name="org.gtk.EggDBus.DocString" value="<para>Checks if @subject is authorized to perform the action with identifier @action_id.</para><para>If @cancellation_id is non-empty and already in use for the caller, the %org.freedesktop.PolicyKit1.Error.CancellationIdNotUnique error is returned.</para>"/>
......@@ -218,6 +236,35 @@
</arg>
</method>
<!-- ---------------------------------------------------------------------------------------------------- -->
<method name="ObtainAuthorization">
<annotation name="org.gtk.EggDBus.DocString" value="Obtains a temporary authorization for @subject to perform the action identified by @action_id. If @subject is already authorized, this method returns immediately without error. If the authorization could not be obtained or @action_id doesn't allow temporary authorizations, the %org.freedesktop.PolicyKit1.Error.Failed error is returned."/>
<arg name="subject" direction="in" type="(sa{sv})">
<annotation name="org.gtk.EggDBus.DocString" value="A #Subject struct."/>
<annotation name="org.gtk.EggDBus.Type" value="Subject"/>
</arg>
<arg name="action_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="Identifier for the action that @subject is attempting to do."/>
</arg>
<arg name="cancellation_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="A unique id used to cancel the the authentication check via org.freedesktop.PolicyKit1.Authority.CancelObtainAuthorization() or the empty string if cancellation is not needed."/>
</arg>
</method>
<method name="CancelObtainAuthorization">
<annotation name="org.gtk.EggDBus.DocString" value="Cancels an attempt to obtain an authorization."/>
<arg name="cancellation_id" direction="in" type="s">
<annotation name="org.gtk.EggDBus.DocString" value="The @cancellation_id passed to org.freedesktop.PolicyKit1.Authority.ObtainAuthorization()."/>
</arg>
</method>
<!-- ---------------------------------------------------------------------------------------------------- -->
<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>"/>
......
......@@ -54,6 +54,7 @@ PolkitAuthorizationResult
polkit_authority_get
polkit_authority_enumerate_actions_sync
polkit_authority_check_authorization_sync
polkit_authority_obtain_authorization_sync
polkit_authority_register_authentication_agent_sync
polkit_authority_unregister_authentication_agent_sync
polkit_authority_authentication_agent_response_sync
......@@ -61,6 +62,8 @@ polkit_authority_enumerate_actions
polkit_authority_enumerate_actions_finish
polkit_authority_check_authorization
polkit_authority_check_authorization_finish
polkit_authority_obtain_authorization
polkit_authority_obtain_authorization_finish
polkit_authority_register_authentication_agent
polkit_authority_register_authentication_agent_finish
polkit_authority_unregister_authentication_agent
......
......@@ -6,6 +6,8 @@ PolkitBackendAuthority
PolkitBackendAuthorityClass
polkit_backend_authority_check_authorization
polkit_backend_authority_check_authorization_finish
polkit_backend_authority_obtain_authorization
polkit_backend_authority_obtain_authorization_finish
polkit_backend_authority_register_authentication_agent
polkit_backend_authority_unregister_authentication_agent
polkit_backend_authority_authentication_agent_response
......
......@@ -15,7 +15,7 @@ INCLUDES = \
-D_REENTRANT \
$(NULL)
noinst_PROGRAMS = cancel
noinst_PROGRAMS = cancel cancelobtain
cancel_SOURCES = cancel.c
......@@ -28,5 +28,16 @@ cancel_LDADD = \
$(top_builddir)/src/polkit/libpolkit-gobject-1.la \
$(NULL)
cancelobtain_SOURCES = cancelobtain.c
cancelobtain_CFLAGS = \
$(GLIB_CFLAGS) \
$(NULL)
cancelobtain_LDADD = \
$(GLIB_LDADD) \
$(top_builddir)/src/polkit/libpolkit-gobject-1.la \
$(NULL)
clean-local :
rm -f *~
/*
* Copyright (C) 2009 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>
*/
/* Simple example that shows how to obtain an authorization including
* cancelling the request.
*/
#include <polkit/polkit.h>
static void
obtain_authorization_cb (PolkitAuthority *authority,
GAsyncResult *res,
GMainLoop *loop)
{
GError *error;
error = NULL;
if (!polkit_authority_obtain_authorization_finish (authority, res, &error))
{
g_print ("Error obtaining authorization: %s\n", error->message);
g_error_free (error);
}
g_main_loop_quit (loop);
}
static gboolean
do_cancel (GCancellable *cancellable)
{
g_print ("Timer has expired; cancelling request\n");
g_cancellable_cancel (cancellable);
return FALSE;
}
int
main (int argc, char *argv[])
{
int ret;
GMainLoop *loop;
PolkitSubject *calling_process;
PolkitAuthority *authority;
GCancellable *cancellable;
g_type_init ();
ret = 1;
if (argc != 2)
{
g_printerr ("usage: cancelobtain <actionid>\n");
goto out;
}
loop = g_main_loop_new (NULL, FALSE);
authority = polkit_authority_get ();
calling_process = polkit_unix_process_new (getppid ());
cancellable = g_cancellable_new ();
g_print ("Will cancel request in 10 seconds\n");
g_timeout_add (10 * 1000,
(GSourceFunc) do_cancel,
cancellable);
polkit_authority_obtain_authorization (authority,
calling_process,
argv[1],
cancellable,
(GAsyncReadyCallback) obtain_authorization_cb,
loop);
g_main_loop_run (loop);
g_object_unref (authority);
g_object_unref (calling_process);
g_object_unref (cancellable);
g_main_loop_unref (loop);
ret = 0;
out:
return ret;
}
......@@ -325,6 +325,7 @@ polkit_authority_enumerate_actions_sync (PolkitAuthority *authority,
}
/* ---------------------------------------------------------------------------------------------------- */
static guint
polkit_authority_check_authorization_async (PolkitAuthority *authority,
PolkitSubject *subject,
......@@ -490,7 +491,7 @@ polkit_authority_check_authorization_finish (PolkitAuthority *authority
}
/**
* polkit_authority_check_authorization:
* polkit_authority_check_authorization_sync:
* @authority: A #PolkitAuthority.
* @subject: A #PolkitSubject.
* @action_id: The action to check for.
......@@ -534,6 +535,208 @@ polkit_authority_check_authorization_sync (PolkitAuthority *author
/* ---------------------------------------------------------------------------------------------------- */
static guint
polkit_authority_obtain_authorization_async (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
_PolkitSubject *real_subject;
guint call_id;
GSimpleAsyncResult *simple;
gchar *cancellation_id;
real_subject = polkit_subject_get_real (subject);
simple = g_simple_async_result_new (G_OBJECT (authority),
callback,
user_data,
polkit_authority_obtain_authorization_async);
cancellation_id = NULL;
if (cancellable != NULL)
{
cancellation_id = g_strdup_printf ("cancellation-id-%d", authority->cancellation_id_counter++);
g_object_set_data_full (G_OBJECT (simple), "polkit-1-cancellation-id", cancellation_id, g_free);
}
call_id = _polkit_authority_obtain_authorization (authority->real,
EGG_DBUS_CALL_FLAGS_TIMEOUT_NONE,
real_subject,
action_id,
cancellation_id,
cancellable,
generic_async_cb,
simple);
g_object_unref (real_subject);
return call_id;
}
/**
* polkit_authority_obtain_authorization:
* @authority: A #PolkitAuthority.
* @subject: A #PolkitSubject.
* @action_id: The action to obtain an authorization 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 obtains a temporary authorization for @subject to
* perform the action represented by @action_id.
*
* When the operation is finished, @callback will be invoked. You can
* then call polkit_authority_obtain_authorization_finish() to get the
* result of the operation.
**/
void
polkit_authority_obtain_authorization (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
polkit_authority_obtain_authorization_async (authority,
subject,
action_id,
cancellable,
callback,
user_data);
}
static void
authorization_obtain_cancelled_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
GError *error;
error = NULL;
if (!_polkit_authority_cancel_obtain_authorization_finish (_POLKIT_AUTHORITY (source_object),
res,
&error))
{
g_warning ("Error cancelling obtain authorization call: %s", error->message);
g_error_free (error);
}
}
/**
* polkit_authority_obtain_authorization_finish:
* @authority: A #PolkitAuthority.
* @res: A #GAsyncResult obtained from the callback.
* @error: Return location for error or %NULL.
*
* Finishes obtaining an authorization.
*
* Returns: %TRUE if the authorization was obtained, %FALSE if @error is set.
**/
gboolean
polkit_authority_obtain_authorization_finish (PolkitAuthority *authority,
GAsyncResult *res,
GError **error)
{
gboolean result;
GSimpleAsyncResult *simple;
GAsyncResult *real_res;
GError *local_error;
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_obtain_authorization_async);
result = _POLKIT_AUTHORIZATION_RESULT_NOT_AUTHORIZED;
local_error = NULL;
result = _polkit_authority_obtain_authorization_finish (authority->real,
real_res,
&local_error);
if (local_error != NULL)
{
if (local_error->domain == EGG_DBUS_ERROR && local_error->code == EGG_DBUS_ERROR_CANCELLED)
{
const gchar *cancellation_id;
/* if the operation was cancelled locally, make sure to tell the daemon so the authentication
* dialog etc. can be removed
*/
cancellation_id = g_object_get_data (G_OBJECT (simple), "polkit-1-cancellation-id");
if (cancellation_id != NULL)
{
_polkit_authority_cancel_obtain_authorization (authority->real,
EGG_DBUS_CALL_FLAGS_NONE,
cancellation_id,
NULL,
authorization_obtain_cancelled_cb,
NULL);
}
g_set_error (error,
POLKIT_ERROR,
POLKIT_ERROR_CANCELLED,
"The operation was cancelled");
g_error_free (local_error);
}
else
{
g_propagate_error (error, local_error);
}
}
g_object_unref (real_res);
return result;
}
/**
* polkit_authority_obtain_authorization_sync:
* @authority: A #PolkitAuthority.
* @subject: A #PolkitSubject.
* @action_id: The action to obtain for.
* @flags: A set of #PolkitObtainAuthorizationFlags.
* @cancellable: A #GCancellable or %NULL.
* @callback: A #GAsyncReadyCallback to call when the request is satisfied.
* @user_data: The data to pass to @callback.
*
* Obtains a temporary authorization for @subject to perform the
* action represented by @action_id.
*
* Returns: %TRUE if the authorization was obtained, %FALSE if @error is set.
*/
gboolean
polkit_authority_obtain_authorization_sync (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GError **error)
{
guint call_id;
GAsyncResult *res;
gboolean result;
call_id = polkit_authority_obtain_authorization_async (authority,
subject,
action_id,
cancellable,
generic_cb,
&res);
egg_dbus_connection_pending_call_block (authority->system_bus, call_id);
result = polkit_authority_obtain_authorization_finish (authority, res, error);
g_object_unref (res);
return result;
}
/* ---------------------------------------------------------------------------------------------------- */
static guint
polkit_authority_register_authentication_agent_async (PolkitAuthority *authority,
const gchar *session_id,
......
......@@ -65,6 +65,12 @@ PolkitAuthorizationResult polkit_authority_check_authorization_sync (PolkitAuth
GCancellable *cancellable,
GError **error);
gboolean polkit_authority_obtain_authorization_sync (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GError **error);
gboolean polkit_authority_register_authentication_agent_sync (PolkitAuthority *authority,
const gchar *session_id,
const gchar *object_path,
......@@ -106,6 +112,16 @@ PolkitAuthorizationResult polkit_authority_check_authorization_finish (PolkitAu
GAsyncResult *res,
GError **error);
void polkit_authority_obtain_authorization (PolkitAuthority *authority,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean polkit_authority_obtain_authorization_finish (PolkitAuthority *authority,
GAsyncResult *res,
GError **error);
void polkit_authority_register_authentication_agent (PolkitAuthority *authority,
const gchar *session_id,
......
This diff is collapsed.
......@@ -70,6 +70,13 @@ struct _PolkitBackendAuthority
* @check_authorization_finish: Called when finishing an authorization
* check. See polkit_backend_authority_check_authorization_finish()
* for details.
* @obtain_authorization: Called to obtain an authorization or %NULL
* if the backend doesn't support the operation. See
* polkit_backend_authority_obtain_authorization() for details.
* @obtain_authorization_finish: Called when finishing obtaining
* an authorization or %NULL if the backend doesn't support the
* operation. See polkit_backend_authority_obtain_authorization_finish()
* for details.
* @register_authentication_agent: Called when an authentication agent
* is attempting to register or %NULL if the backend doesn't support
* the operation. See
......@@ -132,6 +139,18 @@ struct _PolkitBackendAuthorityClass
GAsyncResult *res,
GError **error);
void (*obtain_authorization) (PolkitBackendAuthority *authority,
PolkitSubject *caller,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*obtain_authorization_finish) (PolkitBackendAuthority *authority,
GAsyncResult *res,
GError **error);
gboolean (*register_authentication_agent) (PolkitBackendAuthority *authority,
PolkitSubject *caller,
const gchar *session_id,
......@@ -228,6 +247,18 @@ PolkitAuthorizationResult polkit_backend_authority_check_authorization_finish (P
GAsyncResult *res,
GError **error);
void polkit_backend_authority_obtain_authorization (PolkitBackendAuthority *authority,
PolkitSubject *caller,
PolkitSubject *subject,
const gchar *action_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean polkit_backend_authority_obtain_authorization_finish (PolkitBackendAuthority *authority,
GAsyncResult *res,
GError **error);
GList *polkit_backend_authority_enumerate_authorizations (PolkitBackendAuthority *authority,
PolkitSubject *caller,
PolkitIdentity *identity,
......
......@@ -632,35 +632,24 @@ list_groups (void)
static gint
do_run (gint argc, gchar *argv[])
{
PolkitAuthorizationResult result;
PolkitSubject *calling_process;
GError *error;
gboolean ret;
ret = FALSE;
error = NULL;
calling_process = polkit_unix_process_new (getpid ());
result = polkit_authority_check_authorization_sync (authority,
calling_process,
action_id,
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
NULL,
&error);
if (error != NULL)
error = NULL;
if (!polkit_authority_obtain_authorization_sync (authority,
calling_process,
action_id,
NULL,
&error))
{
g_printerr ("Error checking authorization for action %s: %s\n", action_id, error->message);
g_printerr ("Error obtaining authorization for action %s: %s\n", action_id, error->message);
g_error_free (error);
goto out;
}
if (result != POLKIT_AUTHORIZATION_RESULT_AUTHORIZED)
{
g_printerr ("Error obtaining authorization for action %s (%d)\n", action_id, result);
goto out;
}
execvp (argv[0], argv);
g_printerr ("Error launching program: %m\n");
......@@ -669,7 +658,7 @@ do_run (gint argc, gchar *argv[])
g_object_unref (calling_process);
return ret;
return FALSE;
}
/* ---------------------------------------------------------------------------------------------------- */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment