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