PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Tue Nov 20 13:39:03 PST 2007


 data/Makefile.am                                       |    5 
 data/org.freedesktop.PolicyKit.AuthenticationAgent.xml |   24 ++
 doc/man/polkit-auth.xml                                |   20 +-
 doc/spec/polkit-spec-model.xml                         |   35 +++-
 src/kit/kit-spawn.c                                    |   67 +++++--
 src/kit/kit-spawn.h                                    |   30 ++-
 src/polkit-dbus/polkit-simple.c                        |  147 +++++++++++++++++
 src/polkit-dbus/polkit-simple.h                        |    2 
 src/polkit-grant/polkit-grant-helper.c                 |    1 
 src/polkit/polkit-authorization-db.c                   |    2 
 src/polkit/polkit-policy-file-entry.c                  |    1 
 src/polkit/polkit-sysdeps.c                            |    4 
 tools/polkit-auth.c                                    |   35 +++-
 13 files changed, 331 insertions(+), 42 deletions(-)

New commits:
commit ff9f8745cd9d7f22c80a6c6967d5f4014bac537e
Author: David Zeuthen <davidz at redhat.com>
Date:   Tue Nov 20 16:38:44 2007 -0500

    define abstract Authentication Agent interface and make polkit-auth(1) use it
    
    Also provide a convenience function to access it: polkit_auth_obtain().

diff --git a/data/Makefile.am b/data/Makefile.am
index 59d24e3..36bd7c0 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -16,9 +16,12 @@ conf_DATA = PolicyKit.conf
 dtddir = $(datadir)/PolicyKit
 dtd_DATA = config.dtd
 
+dbusifdir = $(datadir)/dbus-1/interfaces
+dbusif_DATA = org.freedesktop.PolicyKit.AuthenticationAgent.xml
+
 DISTCLEANFILES = polkit.pc polkit-dbus.pc polkit-grant.pc PolicyKit.conf
 
-EXTRA_DIST = polkit.in polkit.pc.in polkit-dbus.pc.in polkit-grant.pc.in PolicyKit.conf.in config.dtd
+EXTRA_DIST = polkit.in polkit.pc.in polkit-dbus.pc.in polkit-grant.pc.in PolicyKit.conf.in config.dtd org.freedesktop.PolicyKit.AuthenticationAgent.xml
 
 clean-local :
 	rm -f *~
diff --git a/data/org.freedesktop.PolicyKit.AuthenticationAgent.xml b/data/org.freedesktop.PolicyKit.AuthenticationAgent.xml
new file mode 100644
index 0000000..9101d19
--- /dev/null
+++ b/data/org.freedesktop.PolicyKit.AuthenticationAgent.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" 
+         "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+
+<!-- This file is provided by the PolicyKit project -->
+
+<node>
+  <interface name="org.freedesktop.PolicyKit.AuthenticationAgent">
+
+    <method name="ObtainAuthorization">
+      <!-- IN: PolicyKit action identifier; see PolKitAction -->
+      <arg name="action_id" direction="in" type="s"/>
+
+      <!-- IN: X11 window ID for the top-level X11 window the dialog will be transient for (pass zero if no window) -->
+      <arg name="xid" direction="in" type="u"/>
+
+      <!-- IN: Process ID to grant authorization to -->
+      <arg name="pid" direction="in" type="u"/>
+
+      <!-- OUT: whether the user gained the authorization -->
+      <arg name="gained_authorization" direction="out" type="b"/>
+    </method>
+
+  </interface>
+</node>
diff --git a/doc/man/polkit-auth.xml b/doc/man/polkit-auth.xml
index 638f3bb..f10b8e5 100644
--- a/doc/man/polkit-auth.xml
+++ b/doc/man/polkit-auth.xml
@@ -47,12 +47,20 @@
         <term><option>--obtain <replaceable>action</replaceable></option></term>
         <listitem>
           <para>
-            Attempt to obtain the authorization to do an action.  This
-            is only useful for implicit authorizations requiring
-            authentication; e.g. when an appropriate stanza in the
-            defaults section of the .policy file for the action
-            specifies
-            <literal>auth_*</literal>.
+            Attempt to obtain an authorization through authentication
+            for the given action. This is only useful for implicit
+            authorizations requiring authentication; e.g. when an
+            appropriate stanza in the defaults section of the .policy
+            file for the action specifies
+            <literal>auth_*</literal>. 
+          </para><para> 
+            If an Authentication Agent (such as the one from
+            PolicyKit-gnome) is available in the session, it will used
+            for authentication unless the environment variable
+            POLKIT_AUTH_FORCE_TEXT is set. If the environment variable
+            POLKIT_AUTH_GRANT_TO_PID is set, the authorization will be
+            granted to that process id instead of the invoking process
+            (e.g. the shell from which polkit-auth is launched).
           </para>
         </listitem>
       </varlistentry>
diff --git a/doc/spec/polkit-spec-model.xml b/doc/spec/polkit-spec-model.xml
index ccc4173..4d3b885 100644
--- a/doc/spec/polkit-spec-model.xml
+++ b/doc/spec/polkit-spec-model.xml
@@ -350,8 +350,12 @@
             trivial) and security reasons (it is typically a good idea
             to have password handling in as few processes as possible)
             it is preferable to have this done in a separate
-            process. For details on the Authentication Agent for the
-            GNOME desktop, please see the <ulink type="http"
+            process. PolicyKit defines an abstract interface to
+            interact with the an Authentication Agent, see the
+            <link linkend="model-authentication-agent">Authentication
+            Agent section</link> for details. For details on the
+            Authentication Agent for the GNOME desktop, please see
+            the <ulink type="http"
             url="http://hal.freedesktop.org/docs/PolicyKit-gnome/ref-auth-daemon.html">PolicyKit-gnome</ulink>
             documentation.
           </para>
@@ -532,7 +536,34 @@
       active sessions and always require authentication for the Action
       <literal>dialup-connect-untrusted</literal>.
     </para>
+  </sect1>
 
+  <sect1 id="model-authentication-agent">
+    <title>Authentication Agent</title>
+    <para>
+      To gain authorizations through authentication, an Authentication
+      Agent is used. The section defines an abstract interface that
+      applications can use to interact with such an agent. This allows
+      different desktop environments to implement different agents
+      with native look and feel.
+    </para>
+    <para>
+      The interface is quite simple. Basically, a PolicyKit
+      Authentication Agent must provide the D-Bus session service with
+      the unique
+      name <literal>org.freedesktop.PolicyKit.AuthenticationAgent</literal>
+      that exposes a single object with the path <literal>/</literal> that exports the 
+      <literal>org.freedesktop.PolicyKit.AuthenticationAgent</literal>
+      D-Bus interface. The interface is defined by the following D-Bus
+      introspection data:
+
+<programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../../data/org.freedesktop.PolicyKit.AuthenticationAgent.xml" parse="text"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting>
+
+      This file is available
+      as <literal>/usr/share/dbus-1/interfaces/org.freedesktop.PolicyKit.AuthenticationAgent.xml</literal>
+      on a system with PolicyKit development packages installed. It
+      can be used to generating client glue code.
+    </para>
   </sect1>
   
 </chapter>
diff --git a/src/kit/kit-spawn.c b/src/kit/kit-spawn.c
index 9fe7739..6fb803a 100644
--- a/src/kit/kit-spawn.c
+++ b/src/kit/kit-spawn.c
@@ -166,13 +166,14 @@ out:
  * occured and errno will be set.
  */
 kit_bool_t
-kit_spawn_sync (const char  *working_directory,
-                char       **argv,
-                char       **envp,
-                char        *stdin,
-                char       **stdout,
-                char       **stderr,
-                int         *out_exit_status)
+kit_spawn_sync (const char     *working_directory,
+                KitSpawnFlags   flags,
+                char          **argv,
+                char          **envp,
+                char           *stdin,
+                char          **stdout,
+                char          **stderr,
+                int            *out_exit_status)
 {
         kit_bool_t ret;
         pid_t pid;
@@ -186,6 +187,9 @@ kit_spawn_sync (const char  *working_directory,
 
         kit_return_val_if_fail (argv != NULL, FALSE);
         kit_return_val_if_fail (out_exit_status != NULL, FALSE);
+        kit_return_val_if_fail (! ((flags & KIT_SPAWN_CHILD_INHERITS_STDIN) && stdin != NULL), FALSE);
+        kit_return_val_if_fail (! ((flags & KIT_SPAWN_STDOUT_TO_DEV_NULL) && stdout != NULL), FALSE);
+        kit_return_val_if_fail (! ((flags & KIT_SPAWN_STDERR_TO_DEV_NULL) && stderr != NULL), FALSE);
 
         if (stdout != NULL)
                 *stdout = NULL;
@@ -221,8 +225,19 @@ kit_spawn_sync (const char  *working_directory,
         }
 
         if (pid == 0) {
+                int fd_null = -1;
+
                 /* child */
 
+                if ( (!(flags & KIT_SPAWN_CHILD_INHERITS_STDIN)) ||
+                     (flags & KIT_SPAWN_STDOUT_TO_DEV_NULL) ||
+                     (flags & KIT_SPAWN_STDERR_TO_DEV_NULL)) {
+                        fd_null = open ("/dev/null", O_RDONLY);
+                        if (fd_null < 0) {
+                                exit (128 + errno);
+                        }
+                }
+
                 signal (SIGPIPE, SIG_DFL);
 
                 /* close unused ends */
@@ -248,32 +263,39 @@ kit_spawn_sync (const char  *working_directory,
 
                 /* set stdin, stdout and stderr */
 
-                if (stdin == NULL) {
-                        int fd_null;
-                        fd_null = open ("/dev/null", O_RDONLY);
-                        if (fd_null < 0) {
+                if (stdin != NULL) {
+                        if (_sane_dup2 (stdin_pipe[0], 0) < 0) {
                                 exit (128 + errno);
                         }
+                } else if (! (flags & KIT_SPAWN_CHILD_INHERITS_STDIN)) {
                         if (_sane_dup2 (fd_null, 0) < 0) {
                                 exit (128 + errno);
                         }
-                } else {
-                        if (_sane_dup2 (stdin_pipe[0], 0) < 0) {
-                                exit (128 + errno);
-                        }
                 }
+
                 if (stdout != NULL) {
                         if (_sane_dup2 (stdout_pipe[1], 1) < 0) {
                                 exit (128 + errno);
                         }
+                } else if (flags & KIT_SPAWN_STDOUT_TO_DEV_NULL) {
+                        if (_sane_dup2 (fd_null, 1) < 0) {
+                                exit (128 + errno);
+                        }
                 }
 
                 if (stderr != NULL) {
                         if (_sane_dup2 (stderr_pipe[1], 2) < 0) {
                                 exit (128 + errno);
                         }
+                } else if (flags & KIT_SPAWN_STDERR_TO_DEV_NULL) {
+                        if (_sane_dup2 (fd_null, 2) < 0) {
+                                exit (128 + errno);
+                        }
                 }
 
+                if (fd_null != -1)
+                        close (fd_null);
+
                 /* finally, execute the child */
                 if (execve (argv[0], argv, envp_to_use) == -1) {
                         exit (128 + errno);
@@ -330,7 +352,6 @@ kit_spawn_sync (const char  *working_directory,
                                       NULL);
                         
                         if (ret < 0 && errno != EINTR) {
-                                kit_warning ("4");
                                 goto out;
                         }
                         
@@ -338,7 +359,6 @@ kit_spawn_sync (const char  *working_directory,
                                 num_written = _write_to (stdin_pipe[1], wp);
                                 
                                 if (num_written == -1)  {
-                                        kit_warning ("3");
                                         goto out;
                                 }
                                 
@@ -355,7 +375,6 @@ kit_spawn_sync (const char  *working_directory,
                                         close (stdout_pipe[0]);
                                         stdout_pipe[0] = -1;
                                 } else if (num_read == -1)  {
-                                        kit_warning ("2");
                                         goto out;
                                 }
                         }
@@ -366,14 +385,12 @@ kit_spawn_sync (const char  *working_directory,
                                         close (stderr_pipe[0]);
                                         stderr_pipe[0] = -1;
                                 } else if (num_read == -1)  {
-                                        kit_warning ("1");
                                         goto out;
                                 }
                         }
                 }
 
                 if (waitpid (pid, out_exit_status, 0) == -1) {
-                        kit_warning ("0");
                         goto out;
                 }
                 pid = -1;
@@ -386,7 +403,6 @@ kit_spawn_sync (const char  *working_directory,
         } else {
                 ret = FALSE;
                 errno = WEXITSTATUS (*out_exit_status) - 128;
-                kit_warning ("kiddo died with errno %d: %m!", errno);
         }
 
 out:
@@ -463,6 +479,7 @@ _run_test (void)
         /* script echoing to stdout and stderr */
         if (kit_file_set_contents (path, 0700, script1, strlen (script1))) {
                 if (kit_spawn_sync ("/",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -477,6 +494,7 @@ _run_test (void)
                 }
 
                 if (kit_spawn_sync ("/",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -492,6 +510,7 @@ _run_test (void)
         /* silent script */
         if (kit_file_set_contents (path, 0700, script2, strlen (script2))) {
                 if (kit_spawn_sync ("/",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -511,6 +530,7 @@ _run_test (void)
                 char *envp[] = {"KIT_TEST_VAR=some_value", NULL};
 
                 if (kit_spawn_sync ("/",
+                                    0,
                                     argv,
                                     envp,
                                     NULL,
@@ -532,6 +552,7 @@ _run_test (void)
                 kit_assert (setenv ("KIT_TEST_VAR", "foobar", 1) == 0);
 
                 if (kit_spawn_sync ("/",
+                                    0,
                                     argv,
                                     envp,
                                     NULL,
@@ -549,6 +570,7 @@ _run_test (void)
         if (kit_file_set_contents (path, 0700, script5, strlen (script5))) {
                 kit_assert (stat ("/tmp", &statbuf) == 0 && S_ISDIR (statbuf.st_mode));
                 if (kit_spawn_sync ("/tmp",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -562,6 +584,7 @@ _run_test (void)
 
                 kit_assert (stat ("/usr", &statbuf) == 0 && S_ISDIR (statbuf.st_mode));
                 if (kit_spawn_sync ("/usr",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -579,6 +602,7 @@ _run_test (void)
         /* check bogus working directory */
         kit_assert (stat ("/org/freedesktop/PolicyKit/bogus-fs-path", &statbuf) != 0);
         kit_assert (kit_spawn_sync ("/org/freedesktop/PolicyKit/bogus-fs-path",
+                                    0,
                                     argv,
                                     NULL,
                                     NULL,
@@ -590,6 +614,7 @@ _run_test (void)
         /* check for writing to stdin */
         if (kit_file_set_contents (path, 0700, script6, strlen (script6))) {
                 if (kit_spawn_sync (NULL,
+                                    0,
                                     argv,
                                     NULL,
                                     "foobar0\nfoobar1",
diff --git a/src/kit/kit-spawn.h b/src/kit/kit-spawn.h
index 72b76f7..9a680c5 100644
--- a/src/kit/kit-spawn.h
+++ b/src/kit/kit-spawn.h
@@ -34,13 +34,29 @@
 
 KIT_BEGIN_DECLS
 
-kit_bool_t kit_spawn_sync (const char  *working_directory,
-                           char       **argv,
-                           char       **envp,
-                           char        *stdin,
-                           char       **stdout,
-                           char       **stderr,
-                           int         *out_exit_status);
+/**
+ * KitSpawnFlags:
+ * @KIT_SPAWN_CHILD_INHERITS_STDIN: If not set, child's stdin will be attached to <literal>/dev/null</literal>
+ * @KIT_SPAWN_STDOUT_TO_DEV_NULL: If set childs output will be sent to <literal>/dev/null</literal>
+ * @KIT_SPAWN_STDERR_TO_DEV_NULL: If set childs error output will be sent to <literal>/dev/null</literal>
+ *
+ * Flags passed to kit_spawn_sync().
+ */
+typedef enum {
+        KIT_SPAWN_CHILD_INHERITS_STDIN = 1 << 0,
+        KIT_SPAWN_STDOUT_TO_DEV_NULL   = 1 << 1,
+        KIT_SPAWN_STDERR_TO_DEV_NULL   = 1 << 2,
+} KitSpawnFlags;
+
+
+kit_bool_t kit_spawn_sync (const char     *working_directory,
+                           KitSpawnFlags   flags,
+                           char          **argv,
+                           char          **envp,
+                           char           *stdin,
+                           char          **stdout,
+                           char          **stderr,
+                           int            *out_exit_status);
 
 KIT_END_DECLS
 
diff --git a/src/polkit-dbus/polkit-simple.c b/src/polkit-dbus/polkit-simple.c
index af1c3c9..d6160dc 100644
--- a/src/polkit-dbus/polkit-simple.c
+++ b/src/polkit-dbus/polkit-simple.c
@@ -40,6 +40,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <pwd.h>
 #include <grp.h>
 #include <unistd.h>
@@ -47,6 +48,7 @@
 
 #include <polkit/polkit-private.h>
 #include "polkit-simple.h"
+#include "polkit-dbus.h"
 
 
 /**
@@ -231,6 +233,151 @@ out:
         return ret;
 }
 
+extern char **environ;
+
+static polkit_bool_t
+_auth_show_dialog_text (const char *action_id, pid_t pid, DBusError *error)
+{
+        unsigned int n;
+        polkit_bool_t ret;
+        int exit_status;
+        char *helper_argv[] = {PACKAGE_BIN_DIR "/polkit-auth", "--obtain", NULL, NULL};
+        char **envp;
+        size_t envsize;
+        char buf[256];
+
+        ret = FALSE;
+
+        if (isatty (STDOUT_FILENO) != 1 || isatty (STDIN_FILENO) != 1) {
+                dbus_set_error (error, 
+                                "org.freedesktop.PolicyKit.LocalError",
+                                "stdout and/or stdin is not a tty");
+                goto out;
+        }
+
+        envsize = kit_strv_length (environ);
+        envp = kit_new0 (char *, envsize + 3);
+        if (envp == NULL)
+                goto out;
+        for (n = 0; n < envsize; n++)
+                envp[n] = environ[n];
+        envp[envsize] = "POLKIT_AUTH_FORCE_TEXT=1";
+        snprintf (buf, sizeof (buf), "POLKIT_AUTH_GRANT_TO_PID=%d", pid);
+        envp[envsize+1] = buf;
+
+        helper_argv[2] = (char *) action_id;
+
+        if (!kit_spawn_sync (NULL,                           /* const char  *working_directory */
+                             KIT_SPAWN_CHILD_INHERITS_STDIN, /* flags */
+                             helper_argv,                    /* char       **argv */
+                             envp,                           /* char       **envp */
+                             NULL,                           /* char        *stdin */
+                             NULL,                           /* char       **stdout */
+                             NULL,                           /* char       **stderr */
+                             &exit_status)) {                /* int         *exit_status */
+                dbus_set_error (error, 
+                                "org.freedesktop.PolicyKit.LocalError",
+                                "Error spawning polkit-auth: %m");
+                goto out;
+        }
+
+        if (!WIFEXITED (exit_status)) {
+                dbus_set_error (error, 
+                                "org.freedesktop.PolicyKit.LocalError",
+                                "polkit-auth crashed!");
+                goto out;
+        } else if (WEXITSTATUS(exit_status) != 0) {
+                goto out;
+        }
+
+        ret = TRUE;
+
+out:
+        return ret;
+}
+
+/**
+ * polkit_auth_obtain: 
+ * @action_id: The action_id for the #PolKitAction to make the user
+ * authenticate for
+ * @xid: X11 window ID for the window that the dialog will be
+ * transient for. If there is no window, pass 0.
+ * @pid: Process ID of process to grant authorization to. Normally one wants to pass result of getpid().
+ * @error: return location for error; cannot be %NULL
+ *
+ * Convenience function to prompt the user to authenticate to gain an
+ * authorization for the given action. First, an attempt to reach an
+ * Authentication Agent on the session message bus is made. If that
+ * doesn't work and stdout/stdin are both tty's, polkit-auth(1) is
+ * invoked.
+ *
+ * This is a blocking call. If you're using GTK+ see
+ * polkit_gnome_auth_obtain() for a non-blocking version.
+ *
+ * Returns: %TRUE if, and only if, the user successfully
+ * authenticated. %FALSE if the user failed to authenticate or if
+ * error is set
+ *
+ * Since: 0.7
+ */
+polkit_bool_t
+polkit_auth_obtain (const char *action_id, polkit_uint32_t xid, pid_t pid, DBusError *error)
+{
+        polkit_bool_t ret;
+        DBusConnection *bus;
+        DBusMessage *message;
+        DBusMessage *reply;
+
+        kit_return_val_if_fail (action_id != NULL, FALSE);
+        kit_return_val_if_fail (error != NULL, FALSE);
+        kit_return_val_if_fail (!dbus_error_is_set (error), FALSE);
+
+        bus = NULL;
+        message = NULL;
+        reply = NULL;
+        ret = FALSE;
+
+        bus = dbus_bus_get (DBUS_BUS_SESSION, error);
+        if (bus == NULL) {
+                dbus_error_init (error);
+                ret = _auth_show_dialog_text (action_id, pid, error);
+                goto out;
+        }
+
+	message = dbus_message_new_method_call ("org.freedesktop.PolicyKit.AuthenticationAgent", /* service */
+						"/",                                             /* object path */
+						"org.freedesktop.PolicyKit.AuthenticationAgent", /* interface */
+						"ObtainAuthorization");
+	dbus_message_append_args (message, 
+                                  DBUS_TYPE_STRING, &action_id, 
+                                  DBUS_TYPE_UINT32, &xid, 
+                                  DBUS_TYPE_UINT32, &pid,
+                                  DBUS_TYPE_INVALID);
+	reply = dbus_connection_send_with_reply_and_block (bus, message, -1, error);
+	if (reply == NULL || dbus_error_is_set (error)) {
+                ret = _auth_show_dialog_text (action_id, pid, error);
+		goto out;
+	}
+	if (!dbus_message_get_args (reply, NULL,
+				    DBUS_TYPE_BOOLEAN, &ret,
+                                    DBUS_TYPE_INVALID)) {
+                dbus_error_init (error);
+                ret = _auth_show_dialog_text (action_id, pid, error);
+		goto out;
+	}
+
+out:
+        if (bus != NULL)
+                dbus_connection_unref (bus);
+        if (message != NULL)
+                dbus_message_unref (message);
+        if (reply != NULL)
+                dbus_message_unref (reply);
+
+        return ret;
+}
+
+
 #ifdef POLKIT_BUILD_TESTS
 
 static polkit_bool_t
diff --git a/src/polkit-dbus/polkit-simple.h b/src/polkit-dbus/polkit-simple.h
index c982621..7d8b938 100644
--- a/src/polkit-dbus/polkit-simple.h
+++ b/src/polkit-dbus/polkit-simple.h
@@ -37,6 +37,8 @@ POLKIT_BEGIN_DECLS
 polkit_uint64_t polkit_check_auth (pid_t pid, ...);
 polkit_uint64_t polkit_check_authv (pid_t pid, const char **action_ids);
 
+polkit_bool_t   polkit_auth_obtain (const char *action_id, polkit_uint32_t xid, pid_t pid, DBusError *error);
+
 POLKIT_END_DECLS
 
 #endif /* POLKIT_SIMPLE_H */
diff --git a/src/polkit-grant/polkit-grant-helper.c b/src/polkit-grant/polkit-grant-helper.c
index d1694b1..e3b904f 100644
--- a/src/polkit-grant/polkit-grant-helper.c
+++ b/src/polkit-grant/polkit-grant-helper.c
@@ -52,7 +52,6 @@
  */
 #undef PGH_DEBUG
 /* #define PGH_DEBUG */
-#define PGH_DEBUG
 
 /* synopsis: polkit-grant-helper <pid> <action-name>
  *
diff --git a/src/polkit/polkit-authorization-db.c b/src/polkit/polkit-authorization-db.c
index 7322355..c3b5c1b 100644
--- a/src/polkit/polkit-authorization-db.c
+++ b/src/polkit/polkit-authorization-db.c
@@ -278,6 +278,7 @@ _authdb_get_auths_for_uid (PolKitAuthorizationDB *authdb,
          * polkituser.
          */
         if (!kit_spawn_sync (NULL,             /* const char  *working_directory */
+                             0,                /* flags */
                              helper_argv,      /* char       **argv */
                              NULL,             /* char       **envp */
                              NULL,             /* char        *stdin */
@@ -882,6 +883,7 @@ polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
         helper_argv[3] = kit_strdup_printf ("%d", polkit_authorization_get_uid (auth));
 
         if (!kit_spawn_sync (NULL,             /* const char  *working_directory */
+                             0,                /* flags */
                              helper_argv,      /* char       **argv */
                              NULL,             /* char       **envp */
                              NULL,             /* char        *stdin */
diff --git a/src/polkit/polkit-policy-file-entry.c b/src/polkit/polkit-policy-file-entry.c
index 5ef3702..6c23c2a 100644
--- a/src/polkit/polkit-policy-file-entry.c
+++ b/src/polkit/polkit-policy-file-entry.c
@@ -514,6 +514,7 @@ polkit_policy_file_entry_set_default (PolKitPolicyFileEntry  *policy_file_entry,
         }
 
         if (!kit_spawn_sync (NULL,             /* const char  *working_directory */
+                             0,                /* flags */
                              helper_argv,      /* char       **argv */
                              NULL,             /* char       **envp */
                              NULL,             /* char        *stdin */
diff --git a/src/polkit/polkit-sysdeps.c b/src/polkit/polkit-sysdeps.c
index 5d923d7..5a34ee9 100644
--- a/src/polkit/polkit-sysdeps.c
+++ b/src/polkit/polkit-sysdeps.c
@@ -129,7 +129,8 @@ out:
  *
  * Get the name of the binary a given process was started from. Note
  * that this is not reliable information; it should not be part of any
- * security decision.
+ * security decision. If the information could not be obtained 0 is
+ * returned and out_buf will be set to "(unknown)".
  *
  * Returns: Number of characters written (not including trailing
  * '\0'). If the output was truncated due to the buffer being too
@@ -151,6 +152,7 @@ polkit_sysdeps_get_exe_for_pid (pid_t pid, char *out_buf, size_t buf_size)
         snprintf (proc_name, sizeof (proc_name), "/proc/%d/exe", pid);
         ret = readlink (proc_name, out_buf, buf_size - 1);
         if (ret == -1) {
+                strncpy (out_buf, "(unknown)", buf_size);
                 goto out;
         }
         kit_assert (ret >= 0 && ret < (int) buf_size - 1);
diff --git a/tools/polkit-auth.c b/tools/polkit-auth.c
index 4d73c0a..772b31a 100644
--- a/tools/polkit-auth.c
+++ b/tools/polkit-auth.c
@@ -652,6 +652,8 @@ main (int argc, char *argv[])
 	DBusError dbus_error;
         struct passwd *pw;
         uid_t uid;
+        pid_t pid;
+        char *s;
 
         ret = 1;
 
@@ -672,6 +674,12 @@ main (int argc, char *argv[])
          * we need to be able to run even when D-Bus and/or ConsoleKit aren't available...
          */
 
+        if ((s = getenv ("POLKIT_AUTH_GRANT_TO_PID")) != NULL) {
+                pid = atoi (s);
+        } else {
+                pid = getppid ();
+        }
+
         dbus_error_init (&dbus_error);
         system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
         if (system_bus != NULL) {
@@ -679,7 +687,7 @@ main (int argc, char *argv[])
                 polkit_tracker_set_system_bus_connection (pk_tracker, system_bus);
                 polkit_tracker_init (pk_tracker);
                 
-                pk_caller = polkit_caller_new_from_pid (system_bus, getppid (), &dbus_error);
+                pk_caller = polkit_caller_new_from_pid (system_bus, pid, &dbus_error);
                 if (pk_caller == NULL) {
                         if (dbus_error_is_set (&dbus_error)) {
                                 fprintf (stderr, "polkit-auth: polkit_caller_new_from_dbus_name(): %s: %s\n", 
@@ -782,8 +790,29 @@ main (int argc, char *argv[])
                 if (!ensure_dbus_and_ck ())
                         goto out;
 
-                if (!obtain_authorization (opt_obtain_action_id))
-                        goto out;                
+                if (getenv ("POLKIT_AUTH_FORCE_TEXT") != NULL) {
+                        if (!obtain_authorization (opt_obtain_action_id))
+                                goto out;                
+                } else {
+                        DBusError dbus_error;
+
+                        dbus_error_init (&dbus_error);
+                        if (!polkit_auth_obtain (opt_obtain_action_id, 0, pid, &dbus_error)) {
+                                if (dbus_error_is_set (&dbus_error)) {
+                                        
+                                        /* fall back to text mode */
+                                        if (!obtain_authorization (opt_obtain_action_id))
+                                                goto out;
+                                        
+                                        //fprintf (stderr, 
+                                        //         "polkit-auth: failed to use session service: %s: %s\n", 
+                                        //         dbus_error.name, dbus_error.message);
+                                } else {
+                                        goto out;
+                                }
+                        }
+                }
+
                 ret = 0;
         } else if (opt_grant_action_id != NULL ||
                    opt_block_action_id != NULL) {


More information about the hal-commit mailing list