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/pkexec.c | |
parent | 17f0600529dc926ae4a0c85dc56c393cc09e4011 (diff) |
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/pkexec.c')
-rw-r--r-- | src/programs/pkexec.c | 46 |
1 files changed, 44 insertions, 2 deletions
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); |