Commit 31761822 authored by David Zeuthen's avatar David Zeuthen

Add polkit.retains_authorization_after_challenge to authz result

Also make this and other details available via methods on the
PolkitAuthorizationResult object.

See this and surrounding messages

 http://lists.freedesktop.org/archives/polkit-devel/2009-July/000189.html

for more information.
parent 01cee08d
......@@ -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. 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 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) and <literal>polkit.retains_authorization_after_challenge</literal> (Set to a non-empty string if the authorization will be retained after authentication (if is_challenge is TRUE))."/>
</annotation>
</annotation>
......
......@@ -108,13 +108,15 @@ KEY3=VALUE3
<para>
If the specificied process is not
authorized, <command>pkcheck</command> exits with a return value
of 1 and a diagnostic message is printed on standard error.
of 1 and a diagnostic message is printed on standard error. Details
are printed on standard output.
</para>
<para>
If the specificied process is not
authorized because no suitable authentication agent is available or if the
<option>--allow-user-interaction</option> wasn't passed, <command>pkcheck</command>
exits with a return value of 2 and a diagnostic message is printed on standard error.
Details are printed on standard output.
</para>
<para>
If an error occured while checking for authorization, <command>pkcheck</command> exits
......
......@@ -62,6 +62,8 @@ PolkitAuthorizationResult
polkit_authorization_result_new
polkit_authorization_result_get_is_authorized
polkit_authorization_result_get_is_challenge
polkit_authorization_result_get_retains_authorization
polkit_authorization_result_get_temporary_authorization_id
polkit_authorization_result_get_details
<SUBSECTION Standard>
PolkitAuthorizationResultClass
......
......@@ -24,6 +24,7 @@
#endif
#include "polkitauthorizationresult.h"
#include "polkitdetails.h"
#include "polkitprivate.h"
/**
......@@ -159,6 +160,9 @@ polkit_authorization_result_new (gboolean is_authorized,
*
* Gets whether the subject is authorized.
*
* If the authorization is temporary, use polkit_authorization_result_get_temporary_authorization_id()
* to get the opaque identifier for the temporary authorization.
*
* Returns: Whether the subject is authorized.
*/
gboolean
......@@ -187,12 +191,6 @@ 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.
*/
......@@ -211,3 +209,70 @@ polkit_authorization_result_get_details (PolkitAuthorizationResult *result)
out:
return result->details;
}
/**
* polkit_authorization_result_get_retains_authorization:
* @result: A #PolkitAuthorizationResult.
*
* Gets whether authorization is retained if obtained via authentication. This can only be the case
* if @result indicates that the subject can obtain authorization after challenge (cf.
* polkit_authorization_result_get_is_challenge()), e.g. when the subject is not already authorized (cf.
* polkit_authorization_result_get_is_authorized()).
*
* If the subject is already authorized, use polkit_authorization_result_get_temporary_authorization_id()
* to check if the authorization is temporary.
*
* This method simply reads the value of the key/value pair in @details with the
* key <literal>polkit.retains_authorization_after_challenge</literal>.
*
* Returns: %TRUE if the authorization is or will be temporary.
*/
gboolean
polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result)
{
gboolean ret;
PolkitDetails *details;
ret = FALSE;
details = polkit_authorization_result_get_details (result);
if (details != NULL && polkit_details_lookup (details, "polkit.retains_authorization_after_challenge") != NULL)
ret = TRUE;
return ret;
}
/**
* polkit_authorization_result_get_temporary_authorization_id:
* @result: A #PolkitAuthorizationResult.
*
* Gets the opaque temporary authorization id for @result if @result indicates the
* subject is authorized and the authorization is temporary rather than one-shot or
* permanent.
*
* You can use this string together with the result from
* polkit_authority_enumerate_temporary_authorizations() to get more details
* about the temporary authorization or polkit_authority_revoke_temporary_authorization_by_id()
* to revoke the temporary authorization.
*
* If the subject is not authorized, use polkit_authorization_result_get_retains_authorization()
* to check if the authorization will be retained if obtained via authentication.
*
* This method simply reads the value of the key/value pair in @details with the
* key <literal>polkit.temporary_authorization_id</literal>.
*
* Returns: The opaque temporary authorization id for @result or %NULL if not
* available. Do not free this string, it is owned by @result.
*/
const gchar *
polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result)
{
const gchar *ret;
PolkitDetails *details;
ret = NULL;
details = polkit_authorization_result_get_details (result);
if (details != NULL)
ret = polkit_details_lookup (details, "polkit.temporary_authorization_id");
return ret;
}
......@@ -43,13 +43,15 @@ typedef struct _PolkitAuthorizationResult PolkitAuthorizationResult;
#endif
typedef struct _PolkitAuthorizationResultClass PolkitAuthorizationResultClass;
GType polkit_authorization_result_get_type (void) G_GNUC_CONST;
PolkitAuthorizationResult *polkit_authorization_result_new (gboolean is_authorized,
gboolean is_challenge,
PolkitDetails *details);
gboolean polkit_authorization_result_get_is_authorized (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result);
PolkitDetails *polkit_authorization_result_get_details (PolkitAuthorizationResult *result);
GType polkit_authorization_result_get_type (void) G_GNUC_CONST;
PolkitAuthorizationResult *polkit_authorization_result_new (gboolean is_authorized,
gboolean is_challenge,
PolkitDetails *details);
PolkitDetails *polkit_authorization_result_get_details (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_is_authorized (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_is_challenge (PolkitAuthorizationResult *result);
gboolean polkit_authorization_result_get_retains_authorization (PolkitAuthorizationResult *result);
const gchar *polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationResult *result);
/* ---------------------------------------------------------------------------------------------------- */
......
......@@ -609,6 +609,7 @@ check_authorization_sync (PolkitBackendAuthority *authority,
gboolean session_is_active;
PolkitImplicitAuthorization implicit_authorization;
const gchar *tmp_authz_id;
PolkitDetails *result_details;
interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority);
priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority);
......@@ -619,6 +620,7 @@ check_authorization_sync (PolkitBackendAuthority *authority,
groups_of_user = NULL;
subject_str = NULL;
session_for_subject = NULL;
result_details = NULL;
session_is_local = FALSE;
session_is_active = FALSE;
......@@ -687,6 +689,8 @@ check_authorization_sync (PolkitBackendAuthority *authority,
implicit_authorization = polkit_action_description_get_implicit_any (action_desc);
}
result_details = polkit_details_new ();
/* allow subclasses to rewrite implicit_authorization */
implicit_authorization = polkit_backend_interactive_authority_check_authorization_sync (interactive_authority,
caller,
......@@ -704,7 +708,7 @@ check_authorization_sync (PolkitBackendAuthority *authority,
g_debug (" is authorized (has implicit authorization local=%d active=%d)",
session_is_local,
session_is_active);
result = polkit_authorization_result_new (TRUE, FALSE, NULL);
result = polkit_authorization_result_new (TRUE, FALSE, result_details);
goto out;
}
......@@ -714,19 +718,22 @@ check_authorization_sync (PolkitBackendAuthority *authority,
action_id,
&tmp_authz_id))
{
PolkitDetails *details;
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);
polkit_details_insert (result_details, "polkit.temporary_authorization_id", tmp_authz_id);
result = polkit_authorization_result_new (TRUE, FALSE, result_details);
goto out;
}
if (implicit_authorization != POLKIT_IMPLICIT_AUTHORIZATION_NOT_AUTHORIZED)
{
result = polkit_authorization_result_new (FALSE, TRUE, NULL);
if (implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_AUTHENTICATION_REQUIRED_RETAINED ||
implicit_authorization == POLKIT_IMPLICIT_AUTHORIZATION_ADMINISTRATOR_AUTHENTICATION_REQUIRED_RETAINED)
{
polkit_details_insert (result_details, "polkit.retains_authorization_after_challenge", "1");
}
result = polkit_authorization_result_new (FALSE, TRUE, result_details);
/* return implicit_authorization so the caller can use an authentication agent if applicable */
if (out_implicit_authorization != NULL)
......@@ -737,7 +744,7 @@ check_authorization_sync (PolkitBackendAuthority *authority,
}
else
{
result = polkit_authorization_result_new (FALSE, FALSE, NULL);
result = polkit_authorization_result_new (FALSE, FALSE, result_details);
g_debug (" not authorized");
}
out:
......@@ -755,6 +762,9 @@ check_authorization_sync (PolkitBackendAuthority *authority,
if (action_desc != NULL)
g_object_unref (action_desc);
if (result_details != NULL)
g_object_unref (result_details);
g_debug (" ");
return result;
......
......@@ -82,6 +82,7 @@ main (int argc, char *argv[])
PolkitSubject *subject;
PolkitDetails *details;
PolkitCheckAuthorizationFlags flags;
PolkitDetails *result_details;
GError *error;
subject = NULL;
......@@ -230,38 +231,36 @@ main (int argc, char *argv[])
goto out;
}
if (polkit_authorization_result_get_is_authorized (result))
result_details = polkit_authorization_result_get_details (result);
if (result_details != NULL)
{
PolkitDetails *result_details;
gchar **keys;
result_details = polkit_authorization_result_get_details (result);
if (result_details != NULL)
keys = polkit_details_get_keys (result_details);
for (n = 0; keys != NULL && keys[n] != NULL; n++)
{
gchar **keys;
keys = polkit_details_get_keys (result_details);
for (n = 0; keys != NULL && keys[n] != NULL; n++)
{
const gchar *key;
const gchar *value;
gchar *s;
key = keys[n];
value = polkit_details_lookup (result_details, key);
s = escape_str (key);
g_print ("%s", s);
g_free (s);
g_print ("=");
s = escape_str (value);
g_print ("%s", s);
g_free (s);
g_print ("\n");
}
g_strfreev (keys);
const gchar *key;
const gchar *value;
gchar *s;
key = keys[n];
value = polkit_details_lookup (result_details, key);
s = escape_str (key);
g_print ("%s", s);
g_free (s);
g_print ("=");
s = escape_str (value);
g_print ("%s", s);
g_free (s);
g_print ("\n");
}
g_strfreev (keys);
}
if (polkit_authorization_result_get_is_authorized (result))
{
ret = 0;
}
else if (polkit_authorization_result_get_is_challenge (result))
......
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