PolicyKit: Branch 'master' - 4 commits
David Zeuthen
david at kemper.freedesktop.org
Fri May 29 08:16:45 PDT 2009
data/org.freedesktop.PolicyKit1.Authority.xml | 2
docs/man/Makefile.am | 5
docs/man/pkcheck.xml | 171 +++++++++++++
docs/polkit/Makefile.am | 1
docs/polkit/polkit-1-docs.xml | 1
src/polkit/polkitdetails.c | 3
src/polkitbackend/polkitbackendlocalauthority.c | 12
src/programs/Makefile.am | 15 +
src/programs/pkcheck.c | 298 ++++++++++++++++++++++++
9 files changed, 494 insertions(+), 14 deletions(-)
New commits:
commit 13c5b2ebcdc81c4841e2d455cbb8dd7c58057043
Author: David Zeuthen <davidz at redhat.com>
Date: Fri May 29 11:12:05 2009 -0400
Add pkcheck(1) command to check for authorizations
This is just a simple wrapper for the CheckAuthorization() D-Bus method.
See these messages
https://www.redhat.com/archives/fedora-devel-list/2009-May/msg01364.html
https://www.redhat.com/archives/fedora-devel-list/2009-May/msg01397.html
where this helper was discussed - it may make it a lot easier to use
polkit from code that pretends to care about OOM conditions.
diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index 67522c1..4319d5c 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -7,6 +7,7 @@ man_MANS = \
PolicyKit-1.8 \
polkit-1.1 \
pkexec.1 \
+ pkcheck.1 \
$(NULL)
%-1.8 %-1.1 : %.xml
@@ -15,12 +16,16 @@ man_MANS = \
pkexec.1 : pkexec.xml
$(XSLTPROC) -nonet --xinclude http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+pkcheck.1 : pkcheck.xml
+ $(XSLTPROC) -nonet --xinclude http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
+
endif # MAN_PAGES_ENABLED
EXTRA_DIST = \
PolicyKit.xml \
polkit.xml \
pkexec.xml \
+ pkcheck.xml \
$(NULL)
clean-local:
diff --git a/docs/man/pkcheck.xml b/docs/man/pkcheck.xml
new file mode 100644
index 0000000..d7b5fba
--- /dev/null
+++ b/docs/man/pkcheck.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY version SYSTEM "../version.xml">
+]>
+<refentry id="pkcheck.1" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <refentryinfo>
+ <title>pkcheck</title>
+ <date>May 2009</date>
+ <productname>PolicyKit-1</productname>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>pkcheck</refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo class="version"></refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pkcheck</refname>
+ <refpurpose>Check whether a process is authorized</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pkcheck</command>
+ <arg><option>--version</option></arg>
+ <arg><option>--help</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pkcheck</command>
+ <arg choice="plain">
+ <option>--action-id</option>
+ <replaceable>action</replaceable>
+ </arg>
+
+ <group choice="req">
+ <arg choice="plain">
+ <option>--process</option>
+ <group choice="req">
+ <arg choice="plain">
+ <replaceable>pid</replaceable>
+ </arg>
+ <arg choice="plain">
+ <replaceable>pid,pid-start-time</replaceable>
+ </arg>
+ </group>
+ </arg>
+ <arg choice="plain">
+ <option>--system-bus-name</option>
+ <replaceable>busname</replaceable>
+ </arg>
+ </group>
+
+ <group>
+ <arg choice="plain">
+ <option>--allow-user-interaction</option>
+ </arg>
+ </group>
+
+ <group rep="repeat">
+ <arg choice="plain">
+ <option>--detail</option>
+ <replaceable>key</replaceable>
+ <replaceable>value</replaceable>
+ </arg>
+ </group>
+ </cmdsynopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>DESCRIPTION</title>
+ <para>
+ <command>pkcheck</command> is used to check whether a process, specified by
+ either <option>--process</option> or <option>--system-bus-name</option>,
+ is authorized for <replaceable>action</replaceable>. The <option>--detail</option>
+ option can be used zero or more times to pass details about <replaceable>action</replaceable>.
+ If <option>--allow-user-interaction</option> is passed, <command>pkcheck</command> blocks
+ while waiting for authentication.
+ </para>
+ <para>
+ This command is a simple wrapper around the PolicyKit D-Bus interface; see the
+ D-Bus interface documentation for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>RETURN VALUE</title>
+ <para>
+ If the specified process is
+ authorized, <command>pkcheck</command> exits with a return value
+ of 0. If the authorization result contains any details, these
+ are printed on standard output as key/value pairs using
+ environment style reporting, e.g. first the key followed by a an equal sign, then the
+ value followed by a newline.
+<programlisting>
+KEY1=VALUE1
+KEY2=VALUE2
+KEY3=VALUE3
+...</programlisting>
+ Octects that are not in [a-zA-Z0-9_] are escaped using octal codes prefixed
+ with <emphasis>\</emphasis>.
+ For example, the UTF-8 string <emphasis>føl,ä½ å¥½</emphasis> will be printed
+ as <emphasis>f\303\270l\54\344\275\240\345\245\275</emphasis>.
+ </para>
+ <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.
+ </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.
+ </para>
+ <para>
+ If an error occured while checking for authorization, <command>pkcheck</command> exits
+ with a return value of 127 with a diagnostic message printed on standard error.
+ </para>
+ <para>
+ If one or more of the options passed are malformed, <command>pkcheck</command> exits
+ with a return value of 126. If stdin is a tty, then this manual page is also shown.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>NOTES</title>
+ <para>
+ Since process identifiers can be recycled, the caller should always use
+ <replaceable>pid,pid-start-time</replaceable> to specify the process
+ to check for authorization when using the <option>--process</option> option.
+ The value of <replaceable>pid-start-time</replaceable>
+ can be determined by consulting e.g. the
+ <citerefentry>
+ <refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>
+ file system depending on the operating system. If only <replaceable>pid</replaceable>
+ is passed to the <option>--process</option> option, then <command>pkcheck</command>
+ will look up the start time itself but note that this may be racy.
+ </para>
+ </refsect1>
+
+ <refsect1><title>AUTHOR</title>
+ <para>
+ Written by David Zeuthen <email>davidz at redhat.com</email> with
+ a lot of help from many others.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>BUGS</title>
+ <para>
+ Please send bug reports to either the distribution or the
+ polkit-devel mailing list,
+ see the link <ulink url="http://lists.freedesktop.org/mailman/listinfo/polkit-devel"/>
+ on how to subscribe.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>PolicyKit-1</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/docs/polkit/Makefile.am b/docs/polkit/Makefile.am
index a60dab9..6afa420 100644
--- a/docs/polkit/Makefile.am
+++ b/docs/polkit/Makefile.am
@@ -55,6 +55,7 @@ content_files = \
../man/PolicyKit.xml \
../man/polkit.xml \
../man/pkexec.xml \
+ ../man/pkcheck.xml \
$(NULL)
# Images to copy into HTML directory
diff --git a/docs/polkit/polkit-1-docs.xml b/docs/polkit/polkit-1-docs.xml
index 0f0a103..d3a3624 100644
--- a/docs/polkit/polkit-1-docs.xml
+++ b/docs/polkit/polkit-1-docs.xml
@@ -107,6 +107,7 @@
<xi:include href="../man/PolicyKit.xml"/>
<xi:include href="../man/polkit.xml"/>
<xi:include href="../man/pkexec.xml"/>
+ <xi:include href="../man/pkcheck.xml"/>
</reference>
<index>
diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am
index abb9f87..7a51ade 100644
--- a/src/programs/Makefile.am
+++ b/src/programs/Makefile.am
@@ -17,7 +17,7 @@ INCLUDES = \
# ----------------------------------------------------------------------------------------------------
-bin_PROGRAMS = polkit-1 pkexec
+bin_PROGRAMS = polkit-1 pkexec pkcheck
# ----------------------------------------------------------------------------------------------------
@@ -69,6 +69,19 @@ libpolkit_pkexec_action_lookup_la_LIBADD = \
# ----------------------------------------------------------------------------------------------------
+pkcheck_SOURCES = pkcheck.c
+
+pkcheck_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(NULL)
+
+pkcheck_LDADD = \
+ $(GLIB_LDADD) \
+ $(top_builddir)/src/polkit/libpolkit-gobject-1.la \
+ $(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
clean-local :
rm -f *~
diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c
new file mode 100644
index 0000000..ea17668
--- /dev/null
+++ b/src/programs/pkcheck.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: David Zeuthen <davidz at redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <polkit/polkit.h>
+
+static void
+usage (int argc, char *argv[])
+{
+ GError *error;
+
+ error = NULL;
+ if (!g_spawn_command_line_sync ("man pkcheck",
+ NULL,
+ NULL,
+ NULL,
+ &error))
+ {
+ g_printerr ("Cannot show manual page: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+static gchar *
+escape_str (const gchar *str)
+{
+ GString *s;
+ guint n;
+
+ s = g_string_new (NULL);
+ if (str == NULL)
+ goto out;
+
+ for (n = 0; str[n] != '\0'; n++)
+ {
+ guint c = str[n] & 0xff;
+
+ if (g_ascii_isalnum (c) || c=='_')
+ g_string_append_c (s, c);
+ else
+ g_string_append_printf (s, "\\%o", c);
+ }
+
+ out:
+ return g_string_free (s, FALSE);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ guint n;
+ guint ret;
+ gchar *action_id;
+ gboolean opt_show_help;
+ gboolean opt_show_version;
+ gboolean allow_user_interaction;
+ PolkitAuthority *authority;
+ PolkitAuthorizationResult *result;
+ PolkitSubject *subject;
+ PolkitDetails *details;
+ PolkitCheckAuthorizationFlags flags;
+ GError *error;
+
+ subject = NULL;
+ action_id = NULL;
+ details = NULL;
+ authority = NULL;
+ result = NULL;
+ allow_user_interaction = FALSE;
+ ret = 126;
+
+ g_type_init ();
+
+ details = polkit_details_new ();
+
+ opt_show_help = FALSE;
+ opt_show_version = FALSE;
+ for (n = 1; n < (guint) argc; n++)
+ {
+ if (g_strcmp0 (argv[n], "--help") == 0)
+ {
+ opt_show_help = TRUE;
+ }
+ else if (g_strcmp0 (argv[n], "--version") == 0)
+ {
+ opt_show_version = TRUE;
+ }
+ else if (g_strcmp0 (argv[n], "--process") == 0 || g_strcmp0 (argv[n], "-p") == 0)
+ {
+ gint pid;
+ guint64 pid_start_time;
+
+ n++;
+ if (n >= (guint) argc)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+
+ if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time) == 2)
+ {
+ subject = polkit_unix_process_new_full (pid, pid_start_time);
+ }
+ else if (sscanf (argv[n], "%i", &pid) == 1)
+ {
+ subject = polkit_unix_process_new (pid);
+ }
+ else
+ {
+ usage (argc, argv);
+ goto out;
+ }
+ }
+ else if (g_strcmp0 (argv[n], "--system-bus-name") == 0 || g_strcmp0 (argv[n], "-s") == 0)
+ {
+ n++;
+ if (n >= (guint) argc)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+
+ subject = polkit_system_bus_name_new (argv[n]);
+ }
+ else if (g_strcmp0 (argv[n], "--action-id") == 0 || g_strcmp0 (argv[n], "-a") == 0)
+ {
+ n++;
+ if (n >= (guint) argc)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+
+ action_id = g_strdup (argv[n]);
+ }
+ else if (g_strcmp0 (argv[n], "--detail") == 0 || g_strcmp0 (argv[n], "-d") == 0)
+ {
+ const gchar *key;
+ const gchar *value;
+
+ n++;
+ if (n >= (guint) argc)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+ key = argv[n];
+
+ n++;
+ if (n >= (guint) argc)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+ value = argv[n];
+
+ polkit_details_insert (details, key, value);
+ }
+ else if (g_strcmp0 (argv[n], "--allow-user-interaction") == 0 || g_strcmp0 (argv[n], "-u") == 0)
+ {
+ allow_user_interaction = TRUE;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (opt_show_help)
+ {
+ usage (argc, argv);
+ ret = 0;
+ goto out;
+ }
+ else if (opt_show_version)
+ {
+ g_print ("pkexec version %s\n", PACKAGE_VERSION);
+ ret = 0;
+ goto out;
+ }
+
+ if (subject == NULL)
+ {
+ usage (argc, argv);
+ goto out;
+ }
+
+ authority = polkit_authority_get ();
+
+ error = NULL;
+ flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
+ if (allow_user_interaction)
+ flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION;
+ result = polkit_authority_check_authorization_sync (authority,
+ subject,
+ action_id,
+ details,
+ flags,
+ NULL,
+ &error);
+ if (result == NULL)
+ {
+ g_printerr ("Error checking for authorization %s: %s\n",
+ action_id,
+ error->message);
+ ret = 127;
+ goto out;
+ }
+
+ if (polkit_authorization_result_get_is_authorized (result))
+ {
+ PolkitDetails *result_details;
+
+ result_details = polkit_authorization_result_get_details (result);
+ if (result_details != NULL)
+ {
+ 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);
+ }
+
+ ret = 0;
+ }
+ else if (polkit_authorization_result_get_is_challenge (result))
+ {
+ if (allow_user_interaction)
+ g_printerr ("Authorization requires authentication but no agent is available.\n");
+ else
+ g_printerr ("Authorization requires authentication and -u wasn't passed.\n");
+ ret = 2;
+ }
+ else
+ {
+ g_printerr ("Not authorized.\n");
+ ret = 1;
+ }
+
+ out:
+ if (result != NULL)
+ g_object_unref (result);
+
+ g_free (action_id);
+
+ if (details != NULL)
+ g_object_unref (details);
+
+ if (subject != NULL)
+ g_object_unref (subject);
+
+ if (authority != NULL)
+ g_object_unref (authority);
+
+ return ret;
+}
+
commit b85f0d449e1e35e227c0bf8334bae10ffe3a2ae9
Author: David Zeuthen <davidz at redhat.com>
Date: Fri May 29 11:11:03 2009 -0400
Clarify docs for is_challenge member of the AuthorizationResult struct
diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
index 2347302..84b22f5 100644
--- a/data/org.freedesktop.PolicyKit1.Authority.xml
+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
@@ -118,7 +118,7 @@
</annotation>
<annotation name="org.gtk.EggDBus.Struct.Member" value="Boolean:is_challenge">
- <annotation name="org.gtk.EggDBus.DocString" value="#TRUE if the given #Subject could be authorized if more information was provided, and %CheckAuthorizationFlags.AllowUserInteraction wasn't passed."/>
+ <annotation name="org.gtk.EggDBus.DocString" value="#TRUE if the given #Subject could be authorized if more information was provided, and %CheckAuthorizationFlags.AllowUserInteraction wasn't passed or no suitable authentication agent was available."/>
</annotation>
<annotation name="org.gtk.EggDBus.Struct.Member" value="Dict<String,String>:details">
commit afc4668c7ea6a41823813f442999b32452eb9fba
Author: David Zeuthen <davidz at redhat.com>
Date: Fri May 29 11:09:51 2009 -0400
Avoid returning an error if no authentication agent is available
Instead, just return the PolkitAuthorizationResult that already has
authorized==FALSE and challenge==TRUE.
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index 4c98aa6..28021d6 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -651,17 +651,7 @@ polkit_backend_local_authority_check_authorization (PolkitBackendAuthority
AuthenticationAgent *agent;
agent = get_authentication_agent_for_subject (local_authority, subject);
- if (agent == NULL)
- {
- g_simple_async_result_set_error (simple,
- POLKIT_ERROR,
- POLKIT_ERROR_FAILED,
- "Challenge requested, but no suitable authentication agent is available");
- g_simple_async_result_complete (simple);
- g_object_unref (simple);
- goto out;
- }
- else
+ if (agent != NULL)
{
g_object_unref (result);
result = NULL;
commit 18409fc5c82ad728d5565733af2abed4393e197e
Author: David Zeuthen <davidz at redhat.com>
Date: Fri May 29 11:09:16 2009 -0400
Only free hash table if it's not NULL
diff --git a/src/polkit/polkitdetails.c b/src/polkit/polkitdetails.c
index b263194..bef0704 100644
--- a/src/polkit/polkitdetails.c
+++ b/src/polkit/polkitdetails.c
@@ -63,7 +63,8 @@ polkit_details_finalize (GObject *object)
details = POLKIT_DETAILS (object);
- g_hash_table_unref (details->hash);
+ if (details->hash != NULL)
+ g_hash_table_unref (details->hash);
if (G_OBJECT_CLASS (polkit_details_parent_class)->finalize != NULL)
G_OBJECT_CLASS (polkit_details_parent_class)->finalize (object);
More information about the hal-commit
mailing list