summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2010-08-20 11:00:05 -0400
committerDavid Zeuthen <davidz@redhat.com>2010-08-20 11:00:05 -0400
commitf550b0532058cc5da689d37de13523758c12ad9d (patch)
treeedb6dc9a20075f125b3811f38f18ef7375e819d1
parentf071d4561dfe8dd9cfd4e29fddec7bc82fd658aa (diff)
pkcheck: add --enable-internal-agent option
We don't want this on by default because things like system daemons (such as libvirtd) are using pkcheck(1) and in some unfortunate cases these may have a tty attached. Signed-off-by: David Zeuthen <davidz@redhat.com>
-rw-r--r--docs/man/pkcheck.xml17
-rw-r--r--src/programs/Makefile.am1
-rw-r--r--src/programs/pkcheck.c55
3 files changed, 71 insertions, 2 deletions
diff --git a/docs/man/pkcheck.xml b/docs/man/pkcheck.xml
index d8da949..4b3ed03 100644
--- a/docs/man/pkcheck.xml
+++ b/docs/man/pkcheck.xml
@@ -59,6 +59,12 @@
</arg>
</group>
+ <group>
+ <arg choice="plain">
+ <option>--enable-internal-agent</option>
+ </arg>
+ </group>
+
<group rep="repeat">
<arg choice="plain">
<option>--detail</option>
@@ -145,6 +151,17 @@ KEY3=VALUE3
</para>
</refsect1>
+ <refsect1 id="pkcheck-auth-agent"><title>AUTHENTICATION AGENT</title>
+ <para>
+ <command>pkcheck</command>, like any other PolicyKit
+ application, will use the authentication agent registered for
+ the process in question. However, if no authentication agent is
+ available, then <command>pkcheck</command> can register its own
+ textual authentication agent if the option
+ <option>--enable-internal-agent</option> is passed.
+ </para>
+ </refsect1>
+
<refsect1 id="pkcheck-author"><title>AUTHOR</title>
<para>
Written by David Zeuthen <email>davidz@redhat.com</email> with
diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am
index 99bd299..943df31 100644
--- a/src/programs/Makefile.am
+++ b/src/programs/Makefile.am
@@ -67,6 +67,7 @@ pkcheck_CFLAGS = \
pkcheck_LDADD = \
$(GLIB_LIBS) \
$(top_builddir)/src/polkit/libpolkit-gobject-1.la \
+ $(top_builddir)/src/polkitagent/libpolkit-agent-1.la \
$(NULL)
# ----------------------------------------------------------------------------------------------------
diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c
index cda9e8e..f6af3be 100644
--- a/src/programs/pkcheck.c
+++ b/src/programs/pkcheck.c
@@ -25,6 +25,8 @@
#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[])
@@ -77,6 +79,7 @@ main (int argc, char *argv[])
gboolean opt_show_help;
gboolean opt_show_version;
gboolean allow_user_interaction;
+ gboolean enable_internal_agent;
PolkitAuthority *authority;
PolkitAuthorizationResult *result;
PolkitSubject *subject;
@@ -84,6 +87,7 @@ main (int argc, char *argv[])
PolkitCheckAuthorizationFlags flags;
PolkitDetails *result_details;
GError *error;
+ gpointer local_agent_handle;
subject = NULL;
action_id = NULL;
@@ -91,6 +95,8 @@ main (int argc, char *argv[])
authority = NULL;
result = NULL;
allow_user_interaction = FALSE;
+ enable_internal_agent = FALSE;
+ local_agent_handle = NULL;
ret = 126;
g_type_init ();
@@ -184,6 +190,10 @@ main (int argc, char *argv[])
{
allow_user_interaction = TRUE;
}
+ else if (g_strcmp0 (argv[n], "--enable-internal-agent") == 0)
+ {
+ enable_internal_agent = TRUE;
+ }
else
{
break;
@@ -218,6 +228,7 @@ main (int argc, char *argv[])
goto out;
}
+ try_again:
error = NULL;
flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE;
if (allow_user_interaction)
@@ -273,9 +284,45 @@ main (int argc, char *argv[])
else if (polkit_authorization_result_get_is_challenge (result))
{
if (allow_user_interaction)
- g_printerr ("Authorization requires authentication but no agent is available.\n");
+ {
+ if (local_agent_handle == NULL && enable_internal_agent)
+ {
+ PolkitAgentListener *listener;
+ 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\n", error->message);
+ g_error_free (error);
+ 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 local authentication agent: %s\n", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ g_object_unref (result);
+ result = NULL;
+ goto try_again;
+ }
+ else
+ {
+ g_printerr ("Authorization requires authentication but no agent is available.\n");
+ }
+ }
else
- g_printerr ("Authorization requires authentication and -u wasn't passed.\n");
+ {
+ g_printerr ("Authorization requires authentication and -u wasn't passed.\n");
+ }
ret = 2;
}
else
@@ -285,6 +332,10 @@ main (int argc, char *argv[])
}
out:
+ /* if applicable, nuke the local authentication agent */
+ if (local_agent_handle != NULL)
+ polkit_agent_listener_unregister (local_agent_handle);
+
if (result != NULL)
g_object_unref (result);