summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/man/pkexec.xml5
-rw-r--r--docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml20
-rw-r--r--docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml2
-rw-r--r--docs/polkit/polkit-1-sections.txt1
-rw-r--r--src/polkit/polkitauthorizationresult.c29
-rw-r--r--src/polkit/polkitauthorizationresult.h1
-rw-r--r--src/polkit/polkitpermission.c29
-rw-r--r--src/polkitbackend/polkitbackendinteractiveauthority.c30
-rw-r--r--src/programs/pkexec.c17
9 files changed, 118 insertions, 16 deletions
diff --git a/docs/man/pkexec.xml b/docs/man/pkexec.xml
index 6f5dc9c..97ab315 100644
--- a/docs/man/pkexec.xml
+++ b/docs/man/pkexec.xml
@@ -61,7 +61,10 @@
of <replaceable>PROGRAM</replaceable>. If the calling process is
not authorized or an authorization could not be obtained through
authentication or an error occured, <command>pkexec</command>
- exits with a return value of 127.
+ exits with a return value of 127. If the authorization could not
+ be obtained because the user dismissed the authentication
+ dialog, <command>pkexec</command> exits with a return value of
+ 126.
</para>
</refsect1>
diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml
index 663169e..b01fceb 100644
--- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml
+++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml
@@ -40,8 +40,24 @@ BeginAuthentication (IN String action_id,
IN Array&lt;<link linkend="eggdbus-struct-Identity">Identity</link>&gt; identities)
</programlisting>
<para>
-<para>Called by the PolicyKit daemon when the authentication agent needs the user to authenticate as one of the identities in <parameter>identities</parameter> for the action with the identifier <parameter>action_id</parameter>.</para><para>Upon succesful authentication, the authentication agent must invoke the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link> method on the <link linkend="eggdbus-interface-org.freedesktop.PolicyKit1.Authority">org.freedesktop.PolicyKit1.Authority</link> interface of the PolicyKit daemon before returning.</para><para>If the user dismisses the authentication dialog, the authentication agent should return an error.</para>
+ <para>
+ Called by the PolicyKit daemon when the authentication agent
+ needs the user to authenticate as one of the identities in
+ <parameter>identities</parameter> for the action with the
+ identifier <parameter>action_id</parameter>.</para><para>Upon
+ succesful authentication, the authentication agent must invoke
+ the <link
+ linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link>
+ method on the <link
+ linkend="eggdbus-interface-org.freedesktop.PolicyKit1.Authority">org.freedesktop.PolicyKit1.Authority</link>
+ interface of the PolicyKit daemon before returning.
+ </para>
+ <para>
+ The authentication agent should not return until after authentication is complete.
+ If the user dismisses the authentication dialog, the authentication agent should return the <link linkend="eggdbus-constant-Error.org.freedesktop.PolicyKit1.Error.Cancelled">org.freedesktop.PolicyKit1.Error.Cancelled</link> error.
+ </para>
</para>
+
<variablelist role="params">
<varlistentry>
<term><literal>IN String <parameter>action_id</parameter></literal>:</term>
@@ -71,7 +87,7 @@ The themed icon describing the action or the empty string if no icon is set.
<term><literal>IN Dict&lt;String,String&gt; <parameter>details</parameter></literal>:</term>
<listitem>
<para>
-Details about the authentication request. This is a dictionary of key/value pairs where both key and value are strings. These strings are translated into the locale passed when registering the authentication agent using <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent().</link>.
+Details about the authentication request. This is a dictionary of key/value pairs where both key and value are strings. These strings are translated into the locale passed when registering the authentication agent using <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent()</link>.
Keys starting with <literal>polkit.</literal> are reserved for internal use and should never be displayed in the UI.
Known key/value-pairs include <literal>polkit.caller-pid</literal> (the process id of the mechanism making the authorization check) and <literal>polkit.subject-pid</literal> (the process id of the subject the check is for).
</para>
diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
index cb9da6b..93f8cfa 100644
--- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
+++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
@@ -461,7 +461,7 @@ TRUE if the given <link linkend="eggdbus-struct-Subject">Subject</link> could be
<term><literal>Dict&lt;String,String&gt; <structfield>details</structfield></literal></term>
<listitem>
<para>
-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), <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)).
+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), <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)), <literal>polkit.dismissed</literal> (Set to a non-empty string if the authentication dialog was dismissed by the user).
</para>
</listitem>
</varlistentry>
diff --git a/docs/polkit/polkit-1-sections.txt b/docs/polkit/polkit-1-sections.txt
index 78248dc..12141e3 100644
--- a/docs/polkit/polkit-1-sections.txt
+++ b/docs/polkit/polkit-1-sections.txt
@@ -71,6 +71,7 @@ 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_dismissed
polkit_authorization_result_get_details
<SUBSECTION Standard>
PolkitAuthorizationResultClass
diff --git a/src/polkit/polkitauthorizationresult.c b/src/polkit/polkitauthorizationresult.c
index 7390a9d..dd3d761 100644
--- a/src/polkit/polkitauthorizationresult.c
+++ b/src/polkit/polkitauthorizationresult.c
@@ -238,6 +238,35 @@ polkit_authorization_result_get_temporary_authorization_id (PolkitAuthorizationR
return ret;
}
+/**
+ * polkit_authorization_result_get_dismissed:
+ * @result: A #PolkitAuthorizationResult.
+ *
+ * Gets whether the authentication request was dismissed / canceled by the user.
+ *
+ * This method simply reads the value of the key/value pair in @details with the
+ * key <literal>polkit.dismissed</literal>.
+ *
+ * Returns: %TRUE if the authentication request was dismissed, %FALSE otherwise.
+ *
+ * Since: 0.101
+ */
+gboolean
+polkit_authorization_result_get_dismissed (PolkitAuthorizationResult *result)
+{
+ gboolean ret;
+ PolkitDetails *details;
+
+ g_return_val_if_fail (POLKIT_IS_AUTHORIZATION_RESULT (result), FALSE);
+
+ ret = FALSE;
+ details = polkit_authorization_result_get_details (result);
+ if (details != NULL && polkit_details_lookup (details, "polkit.dismissed") != NULL)
+ ret = TRUE;
+
+ return ret;
+}
+
PolkitAuthorizationResult *
polkit_authorization_result_new_for_gvariant (GVariant *value)
{
diff --git a/src/polkit/polkitauthorizationresult.h b/src/polkit/polkitauthorizationresult.h
index ea479fe..7f93bee 100644
--- a/src/polkit/polkitauthorizationresult.h
+++ b/src/polkit/polkitauthorizationresult.h
@@ -52,6 +52,7 @@ gboolean polkit_authorization_result_get_is_authorized (P
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);
+gboolean polkit_authorization_result_get_dismissed (PolkitAuthorizationResult *result);
/* ---------------------------------------------------------------------------------------------------- */
diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c
index 996ee11..c855f2d 100644
--- a/src/polkit/polkitpermission.c
+++ b/src/polkit/polkitpermission.c
@@ -552,11 +552,22 @@ acquire_cb (GObject *source_object,
process_result (data->permission, result);
if (!polkit_authorization_result_get_is_authorized (result))
{
- g_simple_async_result_set_error (data->simple,
- POLKIT_ERROR,
- POLKIT_ERROR_FAILED,
- "Failed to acquire permission for action-id %s",
- data->permission->action_id);
+ if (polkit_authorization_result_get_dismissed (result))
+ {
+ g_simple_async_result_set_error (data->simple,
+ G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "User dismissed authentication dialog while trying to acquire permission for action-id %s",
+ data->permission->action_id);
+ }
+ else
+ {
+ g_simple_async_result_set_error (data->simple,
+ POLKIT_ERROR,
+ POLKIT_ERROR_FAILED,
+ "Failed to acquire permission for action-id %s",
+ data->permission->action_id);
+ }
}
g_object_unref (result);
}
@@ -640,6 +651,14 @@ acquire (GPermission *gpermission,
{
ret = TRUE;
}
+ else if (polkit_authorization_result_get_dismissed (result))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_CANCELLED,
+ "User dismissed authentication dialog while trying to acquire permission for action-id %s",
+ permission->action_id);
+ }
else
{
g_set_error (error,
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
index ae1a1bf..4107e2d 100644
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -82,6 +82,7 @@ typedef void (*AuthenticationAgentCallback) (AuthenticationAgent *agent,
const gchar *action_id,
PolkitImplicitAuthorization implicit_authorization,
gboolean authentication_success,
+ gboolean was_dismissed,
PolkitIdentity *authenticated_identity,
gpointer user_data);
@@ -274,6 +275,10 @@ polkit_backend_interactive_authority_init (PolkitBackendInteractiveAuthority *au
PolkitBackendInteractiveAuthorityPrivate *priv;
GFile *directory;
GError *error;
+ static volatile GQuark domain = 0;
+
+ /* Force registering error domain */
+ domain = POLKIT_ERROR;
priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
@@ -582,6 +587,7 @@ check_authorization_challenge_cb (AuthenticationAgent *agent,
const gchar *action_id,
PolkitImplicitAuthorization implicit_authorization,
gboolean authentication_success,
+ gboolean was_dismissed,
PolkitIdentity *authenticated_identity,
gpointer user_data)
{
@@ -613,9 +619,11 @@ check_authorization_challenge_cb (AuthenticationAgent *agent,
g_debug ("In check_authorization_challenge_cb\n"
" subject %s\n"
" action_id %s\n"
+ " was_dismissed %d\n"
" authentication_success %d\n",
subject_str,
action_id,
+ was_dismissed,
authentication_success);
is_temp = FALSE;
@@ -649,8 +657,15 @@ check_authorization_challenge_cb (AuthenticationAgent *agent,
}
else
{
+ PolkitDetails *details;
+
/* TODO: maybe return set is_challenge? */
- result = polkit_authorization_result_new (FALSE, FALSE, NULL);
+
+ details = polkit_details_new ();
+ if (was_dismissed)
+ polkit_details_insert (details, "polkit.dismissed", "true");
+ result = polkit_authorization_result_new (FALSE, FALSE, details);
+ g_object_unref (details);
}
/* Log the event */
@@ -1633,16 +1648,24 @@ authentication_agent_begin_cb (GDBusProxy *proxy,
{
AuthenticationSession *session = user_data;
gboolean gained_authorization;
+ gboolean was_dismissed;
GError *error;
+ was_dismissed = FALSE;
+ gained_authorization = FALSE;
+
error = NULL;
if (!g_dbus_proxy_call_finish (proxy,
res,
&error))
{
- g_printerr ("Error performing authentication: %s\n", error->message);
+ g_printerr ("Error performing authentication: %s (%s %d)\n",
+ error->message,
+ g_quark_to_string (error->domain),
+ error->code);
+ if (error->domain == POLKIT_ERROR && error->code == POLKIT_ERROR_CANCELLED)
+ was_dismissed = TRUE;
g_error_free (error);
- gained_authorization = FALSE;
}
else
{
@@ -1660,6 +1683,7 @@ authentication_agent_begin_cb (GDBusProxy *proxy,
session->action_id,
session->implicit_authorization,
gained_authorization,
+ was_dismissed,
session->authenticated_identity,
session->user_data);
diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
index fbd700d..40042e4 100644
--- a/src/programs/pkexec.c
+++ b/src/programs/pkexec.c
@@ -714,10 +714,19 @@ main (int argc, char *argv[])
}
else
{
- log_message (LOG_WARNING, TRUE,
- "Error executing command as another user: Not authorized");
- g_printerr ("\n"
- "This incident has been reported.\n");
+ if (polkit_authorization_result_get_dismissed (result))
+ {
+ log_message (LOG_WARNING, TRUE,
+ "Error executing command as another user: Request dismissed");
+ ret = 126;
+ }
+ else
+ {
+ log_message (LOG_WARNING, TRUE,
+ "Error executing command as another user: Not authorized");
+ g_printerr ("\n"
+ "This incident has been reported.\n");
+ }
goto out;
}