pkexec: add support for argv1 annotation and mention shebang-wrappers
authorDavid Zeuthen <zeuthen@gmail.com>
Wed, 11 Jul 2012 16:58:06 +0000 (12:58 -0400)
committerDavid Zeuthen <zeuthen@gmail.com>
Wed, 11 Jul 2012 17:09:50 +0000 (13:09 -0400)
Signed-off-by: David Zeuthen <zeuthen@gmail.com>
docs/man/pkexec.xml
src/programs/pkexec.c

index a8868b2799bfc9b1799b0e09289cc5e5ad6c7eac..fffcea4aabf2a5652db809c3697bdb950fa8cc5a 100644 (file)
       annotation on an action with the value set to the full path of
       the program. In addition to specifying the program, the
       authentication message, description, icon and defaults can be
-      specified.
+      specified. If the <emphasis>org.freedesktop.policykit.exec.argv1</emphasis>
+      annotation is present, the action will only be picked if the
+      first argument to the program matches the value of the annotation.
     </para>
     <para>
       Note that authentication messages may reference variables (see
     </para>
   </refsect1>
 
+  <refsect1 id="pkexec-wrapper"><title>WRAPPER USAGE</title>
+    <para>
+      To avoid modifying existing software to prefix their
+      command-line invocations with <command>pkexec</command>,
+      it's possible to use <command>pkexec</command> in a
+      <ulink url="http://en.wikipedia.org/wiki/Shebang_(Unix)">she-bang wrapper</ulink>
+      like this:
+    </para>
+    <programlisting><![CDATA[
+#!/usr/bin/pkexec /usr/bin/python
+
+import os
+import sys
+
+print "Hello, I'm running as uid %d"%(os.getuid())
+
+for n in range(len(sys.argv)):
+    print "arg[%d]=`%s'"%(n, sys.argv[n])
+]]></programlisting>
+    <para>
+      If this script is installed into <filename>/usr/bin/my-pk-test</filename>,
+      then the following annotations
+    </para>
+    <programlisting><![CDATA[
+  [...]
+  <annotate key="org.freedesktop.policykit.exec.path">/usr/bin/python</annotate>
+  <annotate key="org.freedesktop.policykit.exec.argv1">/usr/bin/my-pk-test</annotate>
+  [...]
+]]></programlisting>
+    <para>
+      can be used to select the appropriate polkit action. Be careful
+      to get the latter annotation right, otherwise it will match any
+      <command>pkexec</command> invocation of
+      <filename>/usr/bin/python</filename> scripts.
+    </para>
+  </refsect1>
+
   <refsect1 id="pkexec-variables"><title>VARIABLES</title>
     <para>
       The following variables are set by
index d87825c7cda2fba6e8692963fc1e690bf60848f7..840eb3c1bd5e9f36c12db103bf5cdaf4bc9f2dd4 100644 (file)
@@ -230,6 +230,7 @@ fdwalk (FdCallback callback,
 static gchar *
 find_action_for_path (PolkitAuthority *authority,
                       const gchar     *path,
+                      const gchar     *argv1,
                       gboolean        *allow_gui)
 {
   GList *l;
@@ -255,6 +256,7 @@ find_action_for_path (PolkitAuthority *authority,
   for (l = actions; l != NULL; l = l->next)
     {
       PolkitActionDescription *action_desc = POLKIT_ACTION_DESCRIPTION (l->data);
+      const gchar *argv1_for_action;
       const gchar *path_for_action;
       const gchar *allow_gui_annotation;
 
@@ -262,8 +264,17 @@ find_action_for_path (PolkitAuthority *authority,
       if (path_for_action == NULL)
         continue;
 
+      argv1_for_action = polkit_action_description_get_annotation (action_desc, "org.freedesktop.policykit.exec.argv1");
+
       if (g_strcmp0 (path_for_action, path) == 0)
         {
+          /* check against org.freedesktop.policykit.exec.argv1 but only if set */
+          if (argv1_for_action != NULL)
+            {
+              if (g_strcmp0 (argv1, argv1_for_action) != 0)
+                continue;
+            }
+
           action_id = g_strdup (polkit_action_description_get_action_id (action_desc));
 
           allow_gui_annotation = polkit_action_description_get_annotation (action_desc, "org.freedesktop.policykit.exec.allow_gui");
@@ -664,7 +675,10 @@ main (int argc, char *argv[])
       goto out;
     }
 
-  action_id = find_action_for_path (authority, path, &allow_gui);
+  action_id = find_action_for_path (authority,
+                                    path,
+                                    exec_argv[1],
+                                    &allow_gui);
   g_assert (action_id != NULL);
 
   details = polkit_details_new ();