PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Tue Feb 22 13:51:58 PST 2011


 docs/man/pkexec.xml                                                              |    5 +
 docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml |   20 ++++++
 docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml           |    2 
 docs/polkit/polkit-1-sections.txt                                                |    1 
 src/polkit/polkitauthorizationresult.c                                           |   29 +++++++++
 src/polkit/polkitauthorizationresult.h                                           |    1 
 src/polkit/polkitpermission.c                                                    |   29 ++++++++-
 src/polkitbackend/polkitbackendinteractiveauthority.c                            |   30 +++++++++-
 src/programs/pkexec.c                                                            |   17 ++++-
 9 files changed, 118 insertions(+), 16 deletions(-)

New commits:
commit 986d7c293c6b35899a1e7bc6437f18775220dc47
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Feb 22 16:49:44 2011 -0500

    Bug 30653 – No way to detect cancellation in pkexec
    
    https://bugs.freedesktop.org/show_bug.cgi?id=30653
    
    Signed-off-by: David Zeuthen <davidz at redhat.com>

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;
     }
 


More information about the hal-commit mailing list