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