PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Wed Apr 11 13:35:20 PDT 2012


 docs/man/Makefile.am                                  |    2 
 docs/man/pkaction.xml                                 |    3 
 docs/man/pkcheck.xml                                  |    3 
 docs/man/pkexec.xml                                   |    3 
 docs/man/pkttyagent.xml                               |  154 +++++++++++
 docs/man/polkit.xml                                   |   15 +
 docs/polkit/Makefile.am                               |    1 
 docs/polkit/polkit-1-docs.xml                         |    1 
 src/polkitbackend/polkitbackendinteractiveauthority.c |    7 
 src/programs/Makefile.am                              |   16 +
 src/programs/pkttyagent.c                             |  235 ++++++++++++++++++
 11 files changed, 439 insertions(+), 1 deletion(-)

New commits:
commit bda0fc1de3361fc6f377d041ce2088118048fdf7
Author: David Zeuthen <davidz at redhat.com>
Date:   Wed Apr 11 13:15:48 2012 -0400

    Add pkttyagent(1) helper
    
    This came up while working on
    
     https://bugzilla.redhat.com/show_bug.cgi?id=804088
    
    and is useful for example if it's not suitable or appropriate to link
    against the polkit libraries.
    
    Signed-off-by: David Zeuthen <davidz at redhat.com>

diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index 076608b..b71c1d2 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -10,6 +10,7 @@ man_MANS = 				\
 	pkexec.1			\
 	pkcheck.1			\
 	pkaction.1			\
+	pkttyagent.1			\
 	$(NULL)
 
 %.8 %.1 : %.xml
@@ -24,6 +25,7 @@ EXTRA_DIST = 				\
 	pkexec.xml			\
 	pkcheck.xml			\
 	pkaction.xml			\
+	pkttyagent.xml			\
 	$(NULL)
 
 clean-local:
diff --git a/docs/man/pkaction.xml b/docs/man/pkaction.xml
index ba91e9a..24c156f 100644
--- a/docs/man/pkaction.xml
+++ b/docs/man/pkaction.xml
@@ -100,6 +100,9 @@
       </citerefentry>,
       <citerefentry>
         <refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkttyagent</refentrytitle><manvolnum>1</manvolnum>
       </citerefentry>
     </para>
   </refsect1>
diff --git a/docs/man/pkcheck.xml b/docs/man/pkcheck.xml
index bb5866d..6b8a874 100644
--- a/docs/man/pkcheck.xml
+++ b/docs/man/pkcheck.xml
@@ -213,6 +213,9 @@ KEY3=VALUE3
       </citerefentry>,
       <citerefentry>
         <refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkttyagent</refentrytitle><manvolnum>1</manvolnum>
       </citerefentry>
     </para>
   </refsect1>
diff --git a/docs/man/pkexec.xml b/docs/man/pkexec.xml
index 8196511..1734033 100644
--- a/docs/man/pkexec.xml
+++ b/docs/man/pkexec.xml
@@ -283,6 +283,9 @@
       </citerefentry>,
       <citerefentry>
         <refentrytitle>pkcheck</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkttyagent</refentrytitle><manvolnum>1</manvolnum>
       </citerefentry>
     </para>
   </refsect1>
diff --git a/docs/man/pkttyagent.xml b/docs/man/pkttyagent.xml
new file mode 100644
index 0000000..f0f328e
--- /dev/null
+++ b/docs/man/pkttyagent.xml
@@ -0,0 +1,154 @@
+<?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="pkttyagent.1" xmlns:xi="http://www.w3.org/2003/XInclude">
+  <refentryinfo>
+    <title>pkttyagent</title>
+    <date>May 2009</date>
+    <productname>polkit</productname>
+  </refentryinfo>
+
+  <refmeta>
+    <refentrytitle>pkttyagent</refentrytitle>
+    <manvolnum>1</manvolnum>
+    <refmiscinfo class="version"></refmiscinfo>
+  </refmeta>
+
+  <refnamediv>
+    <refname>pkttyagent</refname>
+    <refpurpose>Textual authentication helper</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <cmdsynopsis>
+      <command>pkttyagent</command>
+      <arg><option>--version</option></arg>
+      <arg><option>--help</option></arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>pkttyagent</command>
+
+      <group>
+        <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>--notify-fd</option>
+          <replaceable>fd</replaceable>
+        </arg>
+      </group>
+
+    </cmdsynopsis>
+
+  </refsynopsisdiv>
+
+  <refsect1 id="pkttyagent-descsription">
+    <title>DESCRIPTION</title>
+    <para>
+      <command>pkttyagent</command> is used to start a textual
+      authentication agent for the subject specified by either
+      <option>--process</option> or
+      <option>--system-bus-name</option>. If neither of these options
+      are given, the parent process is used.
+    </para>
+    <para>
+      To get notified when the authentication agent has been
+      registered either listen to the <link
+      linkend="eggdbus-signal-org.freedesktop.PolicyKit1.Authority::Changed">Changed</link>
+      D-Bus signal or use <option>--notify-fd</option> to pass the
+      number of a file descriptor that has been passed to the
+      program. This file descriptor will then be closed when the
+      authentication agent has been successfully registered.
+    </para>
+  </refsect1>
+
+  <refsect1 id="pkttyagent-return-value">
+    <title>RETURN VALUE</title>
+    <para>
+      If the authentication agent could not be registered,
+      <command>pkttyagent</command> exits with an exit code of
+      127. Diagnostic messages are printed on standard error.
+    </para>
+    <para>
+      If one or more of the options passed are malformed,
+      <command>pkttyagent</command> exits with an exit code of 126. If
+      stdin is a tty, then this manual page is also shown.
+    </para>
+    <para>
+      If the authentication agent was successfully registered,
+      <command>pkttyagent</command> will keep running, interacting
+      with the user as needed. When its services are no longer needed,
+      the process can be killed.
+    </para>
+  </refsect1>
+
+  <refsect1 id="pkttyagent-notes">
+    <title>NOTES</title>
+    <para>
+      Since process identifiers can be recycled, the caller should
+      always use <replaceable>pid,pid-start-time</replaceable> 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>pkttyagent</command>
+      will look up the start time itself but note that this may be racy.
+    </para>
+  </refsect1>
+
+  <refsect1 id="pkttyagent-author"><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 id="pkttyagent-bugs">
+    <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 id="pkttyagent-see-also">
+    <title>SEE ALSO</title>
+    <para>
+      <citerefentry>
+        <refentrytitle>polkit</refentrytitle><manvolnum>8</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkaction</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkcheck</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>
+    </para>
+  </refsect1>
+</refentry>
diff --git a/docs/man/polkit.xml b/docs/man/polkit.xml
index ae67f7c..188c514 100644
--- a/docs/man/polkit.xml
+++ b/docs/man/polkit.xml
@@ -223,6 +223,18 @@ System Context         |                        |
       implemention for systems without a <literal>root</literal>
       account.
     </para>
+
+    <para>
+      Applications that do not run under a desktop environment (for
+      example, if launched from a
+      <citerefentry><refentrytitle>ssh</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+      login) may not have have an authentication agent associated with
+      them. Such applications may use the <link
+      linkend="PolkitAgentTextListener-struct">PolkitAgentTextListener</link>
+      type or the
+      <citerefentry><refentrytitle>pkttyagent</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+      helper so the user can authenticate using a textual interface.
+    </para>
   </refsect1>
 
   <refsect1 id="polkit-declaring-actions"><title>DECLARING ACTIONS</title>
@@ -469,6 +481,9 @@ System Context         |                        |
       <citerefentry>
         <refentrytitle>pkexec</refentrytitle><manvolnum>1</manvolnum>
       </citerefentry>,
+      <citerefentry>
+        <refentrytitle>pkttyagent</refentrytitle><manvolnum>1</manvolnum>
+      </citerefentry>
     </para>
   </refsect1>
 </refentry>
diff --git a/docs/polkit/Makefile.am b/docs/polkit/Makefile.am
index 370fb56..fd7123f 100644
--- a/docs/polkit/Makefile.am
+++ b/docs/polkit/Makefile.am
@@ -65,6 +65,7 @@ content_files =  			    								\
 	../man/pkcheck.xml										\
 	../man/pkaction.xml										\
 	../man/pkexec.xml										\
+	../man/pkttyagent.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 38a69a4..4fc8a99 100644
--- a/docs/polkit/polkit-1-docs.xml
+++ b/docs/polkit/polkit-1-docs.xml
@@ -112,6 +112,7 @@
     <xi:include href="../man/pkaction.xml"/>
     <xi:include href="../man/pkexec.xml"/>
     <xi:include href="../man/pklocalauthority.xml"/>
+    <xi:include href="../man/pkttyagent.xml"/>
   </part>
 
   <chapter id="polkit-hierarchy">
diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
index 99c4782..f523782 100644
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -2329,6 +2329,9 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
                                 caller_cmdline,
                                 object_path,
                                 locale);
+
+  g_signal_emit_by_name (authority, "changed");
+
   ret = TRUE;
 
  out:
@@ -2487,6 +2490,8 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack
   /* this frees agent... */
   g_hash_table_remove (priv->hash_scope_to_authentication_agent, agent->scope);
 
+  g_signal_emit_by_name (authority, "changed");
+
   ret = TRUE;
 
  out:
@@ -2635,6 +2640,8 @@ polkit_backend_interactive_authority_system_bus_name_owner_changed (PolkitBacken
           /* this works because we have exactly one agent per session */
           /* this frees agent... */
           g_hash_table_remove (priv->hash_scope_to_authentication_agent, agent->scope);
+
+          g_signal_emit_by_name (authority, "changed");
         }
 
       /* cancel all authentication sessions initiated by the process owning the vanished name */
diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am
index c260dee..bc1b5a8 100644
--- a/src/programs/Makefile.am
+++ b/src/programs/Makefile.am
@@ -17,7 +17,7 @@ INCLUDES =                                              	\
 
 # ----------------------------------------------------------------------------------------------------
 
-bin_PROGRAMS = pkexec pkcheck pkaction
+bin_PROGRAMS = pkexec pkcheck pkaction pkttyagent
 
 # ----------------------------------------------------------------------------------------------------
 
@@ -50,6 +50,20 @@ pkcheck_LDADD =  	                      				\
 
 # ----------------------------------------------------------------------------------------------------
 
+pkttyagent_SOURCES = pkttyagent.c
+
+pkttyagent_CFLAGS =                             			\
+	$(GLIB_CFLAGS)							\
+	$(NULL)
+
+pkttyagent_LDADD =  	                      				\
+	$(GLIB_LIBS)							\
+	$(top_builddir)/src/polkit/libpolkit-gobject-1.la		\
+	$(top_builddir)/src/polkitagent/libpolkit-agent-1.la		\
+	$(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
 pkaction_SOURCES = pkaction.c
 
 pkaction_CFLAGS =                             				\
diff --git a/src/programs/pkttyagent.c b/src/programs/pkttyagent.c
new file mode 100644
index 0000000..1c170f4
--- /dev/null
+++ b/src/programs/pkttyagent.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2009-2012 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>
+#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
+#include <polkitagent/polkitagent.h>
+
+static void
+usage (int argc, char *argv[])
+{
+  GError *error;
+
+  error = NULL;
+  if (!g_spawn_command_line_sync ("man pkttyagent",
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  &error))
+    {
+      g_printerr ("Cannot show manual page: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+    }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  gboolean opt_show_help = FALSE;
+  gboolean opt_show_version = FALSE;
+  PolkitAuthority *authority = NULL;
+  PolkitSubject *subject = NULL;
+  gpointer local_agent_handle = NULL;
+  PolkitAgentListener *listener = NULL;
+  GError *error;
+  GMainLoop *loop = NULL;
+  guint n;
+  guint ret = 126;
+  gint notify_fd = -1;
+
+  g_type_init ();
+
+  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], "--notify-fd") == 0)
+        {
+          n++;
+          if (n >= (guint) argc)
+            {
+              usage (argc, argv);
+              goto out;
+            }
+
+          if (sscanf (argv[n], "%i", &notify_fd) != 1)
+            {
+              usage (argc, argv);
+              goto out;
+            }
+        }
+      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
+        {
+          break;
+        }
+    }
+
+  if (opt_show_help)
+    {
+      usage (argc, argv);
+      ret = 0;
+      goto out;
+    }
+  else if (opt_show_version)
+    {
+      g_print ("pkttyagent version %s\n", PACKAGE_VERSION);
+      ret = 0;
+      goto out;
+    }
+
+  /* Use parent process, if no subject has been specified */
+  if (subject == NULL)
+    {
+      pid_t pid_of_caller;
+      pid_of_caller = getppid ();
+      if (pid_of_caller == 1)
+        {
+          /* getppid() can return 1 if the parent died (meaning that we are reaped
+           * by /sbin/init); In that case we simpy bail.
+           */
+          g_printerr ("Refusing to render service to dead parents.\n");
+          goto out;
+        }
+
+      subject = polkit_unix_process_new_for_owner (pid_of_caller,
+                                                   0, /* 0 means "look up start-time in /proc" */
+                                                   getuid ());
+      /* really double-check the invariants guaranteed by the PolkitUnixProcess class */
+      g_assert (subject != NULL);
+      g_assert (polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)) == pid_of_caller);
+      g_assert (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0);
+      g_assert (polkit_unix_process_get_start_time (POLKIT_UNIX_PROCESS (subject)) > 0);
+    }
+
+  error = NULL;
+  authority = polkit_authority_get_sync (NULL /* GCancellable* */, &error);
+  if (authority == NULL)
+    {
+      g_printerr ("Error getting authority: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      ret = 127;
+      goto out;
+    }
+
+  error = NULL;
+  /* this will fail if we can't find a controlling terminal */
+  listener = polkit_agent_text_listener_new (NULL, &error);
+  if (listener == NULL)
+    {
+      g_printerr ("Error creating textual authentication agent: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      ret = 127;
+      goto out;
+    }
+  local_agent_handle = polkit_agent_listener_register (listener,
+                                                       POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD,
+                                                       subject,
+                                                       NULL, /* object_path */
+                                                       NULL, /* GCancellable */
+                                                       &error);
+  g_object_unref (listener);
+  if (local_agent_handle == NULL)
+    {
+      g_printerr ("Error registering authentication agent: %s (%s, %d)\n",
+                  error->message, g_quark_to_string (error->domain), error->code);
+      g_error_free (error);
+      goto out;
+    }
+
+  if (notify_fd != -1)
+    {
+      if (close (notify_fd) != 0)
+        {
+          g_printerr ("Error closing notify-fd %d: %m\n", notify_fd);
+          goto out;
+        }
+    }
+
+  loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (loop);
+
+ out:
+  if (loop != NULL)
+    g_main_loop_unref (loop);
+
+  if (local_agent_handle != NULL)
+    polkit_agent_listener_unregister (local_agent_handle);
+
+  if (subject != NULL)
+    g_object_unref (subject);
+
+  if (authority != NULL)
+    g_object_unref (authority);
+
+  return ret;
+}


More information about the hal-commit mailing list