diff options
author | David Zeuthen <davidz@redhat.com> | 2010-08-12 16:51:51 -0400 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2010-08-12 16:51:51 -0400 |
commit | 42177383585e1e01cd6150f891176afcd4538a82 (patch) | |
tree | 924bcbd61405b7c0c504718f02791aefa7bcfaf6 /src/programs | |
parent | 17f0600529dc926ae4a0c85dc56c393cc09e4011 (diff) | |
download | polkit-42177383585e1e01cd6150f891176afcd4538a82.tar.gz |
Add textual authentication agent and use it in pkexec(1)
This makes pkexec(1) work when e.g. logging in via ssh(1) or the linux
console but also when using `su -'. Example:
[davidz@x61 ~]$ su - bateman
Password:
[bateman@x61 ~]$ pkexec bash
==== AUTHENTICATING FOR org.freedesktop.policykit.exec ===
Authentication is needed to run `/bin/bash' as the super user
Authenticating as: root
Password:
==== AUTHENTICATION COMPLETE ===
[root@x61 ~]#
Summary of changes
- Added a PolkitAgentTextListener class
- Add new polkit_agent_listener_register() (and _unregister()) API
- Deprecate polkit_agent_register_listener API
- Allow registering authentication agents for PolkitUnixProcess subjects
and prefer such agents to ones governing the session
- Make PolkitAgentSession use the thread-default GMainContext - otherwise
it won't work in spawned threads
- (finally) use PolkitAgentTextListener in pkexec(1) if authorization
via authentication is possible but no authentication agent was
found
Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'src/programs')
-rw-r--r-- | src/programs/Makefile.am | 1 | ||||
-rw-r--r-- | src/programs/pkcheck.c | 2 | ||||
-rw-r--r-- | src/programs/pkexec.c | 46 |
3 files changed, 46 insertions, 3 deletions
diff --git a/src/programs/Makefile.am b/src/programs/Makefile.am index 5c8a26f..99bd299 100644 --- a/src/programs/Makefile.am +++ b/src/programs/Makefile.am @@ -31,6 +31,7 @@ pkexec_CFLAGS = \ pkexec_LDADD = \ $(GLIB_LIBS) \ $(top_builddir)/src/polkit/libpolkit-gobject-1.la \ + $(top_builddir)/src/polkitagent/libpolkit-agent-1.la \ $(NULL) polkitmodulesdir = $(libdir)/polkit-1/extensions diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c index fb61b33..cda9e8e 100644 --- a/src/programs/pkcheck.c +++ b/src/programs/pkcheck.c @@ -198,7 +198,7 @@ main (int argc, char *argv[]) } else if (opt_show_version) { - g_print ("pkexec version %s\n", PACKAGE_VERSION); + g_print ("pkcheck version %s\n", PACKAGE_VERSION); ret = 0; goto out; } diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c index 4a3d55d..f4480ff 100644 --- a/src/programs/pkexec.c +++ b/src/programs/pkexec.c @@ -43,6 +43,8 @@ #include <stdarg.h> #include <polkit/polkit.h> +#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE +#include <polkitagent/polkitagent.h> static gchar *original_user_name = NULL; static gchar *original_cwd = NULL; @@ -361,6 +363,7 @@ validate_environment_variable (const gchar *key, return ret; } + /* ---------------------------------------------------------------------------------------------------- */ int @@ -417,6 +420,7 @@ main (int argc, char *argv[]) gchar *opt_user; pid_t pid_of_caller; uid_t uid_of_caller; + gpointer local_agent_handle; ret = 127; authority = NULL; @@ -428,6 +432,7 @@ main (int argc, char *argv[]) path = NULL; command_line = NULL; opt_user = NULL; + local_agent_handle = NULL; /* check for correct invocation */ if (geteuid () != 0) @@ -642,6 +647,7 @@ main (int argc, char *argv[]) action_id = find_action_for_path (authority, path); g_assert (action_id != NULL); + try_again: error = NULL; result = polkit_authority_check_authorization_sync (authority, subject, @@ -664,8 +670,40 @@ main (int argc, char *argv[]) } else if (polkit_authorization_result_get_is_challenge (result)) { - g_printerr ("Error executing command as another user: No authentication agent was found.\n"); - goto out; + if (local_agent_handle == NULL) + { + 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 ("Error executing command as another user.\n"); + goto out; + } } else { @@ -802,6 +840,10 @@ main (int argc, char *argv[]) g_assert_not_reached (); 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); |