summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2014-02-13 10:05:21 -0500
committerColin Walters <walters@verbum.org>2014-02-18 13:40:48 -0500
commitfb0d00225c401a521430ddf232a11965cdc5dd44 (patch)
tree9e6b6cd1d76d90ea5c11d13be8d9d9f216a78947
parent7650ad1e08ab13bdb461783c4995d186d9392840 (diff)
pkexec: Support just plain "pkexec" to run shell
I use "pkexec bash" a lot, and it'd be nice to be able to just type "pkexec" and have it do what I want. Like how "su" will run the shell by default. https://bugs.freedesktop.org/show_bug.cgi?id=74933
-rw-r--r--docs/man/pkexec.xml11
-rw-r--r--src/programs/pkexec.c56
2 files changed, 45 insertions, 22 deletions
diff --git a/docs/man/pkexec.xml b/docs/man/pkexec.xml
index fffcea4..eda9841 100644
--- a/docs/man/pkexec.xml
+++ b/docs/man/pkexec.xml
@@ -47,11 +47,12 @@
<refsect1 id="pkexec-description"><title>DESCRIPTION</title>
<para>
- <command>pkexec</command> allows an authorized user to
- execute <replaceable>PROGRAM</replaceable> as another
- user. If <replaceable>username</replaceable> is not specified,
- then the program will be executed as the administrative super
- user, <emphasis>root</emphasis>.
+ <command>pkexec</command> allows an authorized user to execute
+ <replaceable>PROGRAM</replaceable> as another user. If
+ <replaceable>PROGRAM</replaceable> is not specified, the default
+ shell will be run. If <replaceable>username</replaceable> is
+ not specified, then the program will be executed as the
+ administrative super user, <emphasis>root</emphasis>.
</para>
</refsect1>
diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
index a7ca8e0..96b1def 100644
--- a/src/programs/pkexec.c
+++ b/src/programs/pkexec.c
@@ -75,7 +75,7 @@ usage (int argc, char *argv[])
g_printerr ("pkexec --version |\n"
" --help |\n"
" --disable-internal-agent |\n"
- " [--user username] PROGRAM [ARGUMENTS...]\n"
+ " [--user username] [PROGRAM] [ARGUMENTS...]\n"
"\n"
"See the pkexec manual page for more details.\n"
"\n"
@@ -498,6 +498,7 @@ main (int argc, char *argv[])
action_id = NULL;
saved_env = NULL;
path = NULL;
+ exec_argv = NULL;
command_line = NULL;
opt_user = NULL;
local_agent_handle = NULL;
@@ -576,6 +577,21 @@ main (int argc, char *argv[])
if (opt_user == NULL)
opt_user = g_strdup ("root");
+ /* Look up information about the user we care about - yes, the return
+ * value of this function is a bit funky
+ */
+ rc = getpwnam_r (opt_user, &pwstruct, pwbuf, sizeof pwbuf, &pw);
+ if (rc == 0 && pw == NULL)
+ {
+ g_printerr ("User `%s' does not exist.\n", opt_user);
+ goto out;
+ }
+ else if (pw == NULL)
+ {
+ g_printerr ("Error getting information for user `%s': %s\n", opt_user, g_strerror (rc));
+ goto out;
+ }
+
/* Now figure out the command-line to run - argv is guaranteed to be NULL-terminated, see
*
* http://lkml.indiana.edu/hypermail/linux/kernel/0409.2/0287.html
@@ -588,8 +604,21 @@ main (int argc, char *argv[])
path = g_strdup (argv[n]);
if (path == NULL)
{
- usage (argc, argv);
- goto out;
+ GPtrArray *shell_argv;
+
+ path = g_strdup (pwstruct.pw_shell);
+ if (!path)
+ {
+ g_printerr ("No shell configured or error retrieving pw_shell\n");
+ goto out;
+ }
+ /* If you change this, be sure to change the if (!command_line)
+ case below too */
+ command_line = g_strdup (path);
+ shell_argv = g_ptr_array_new ();
+ g_ptr_array_add (shell_argv, path);
+ g_ptr_array_add (shell_argv, NULL);
+ exec_argv = (char**)g_ptr_array_free (shell_argv, FALSE);
}
if (path[0] != '/')
{
@@ -608,22 +637,13 @@ main (int argc, char *argv[])
g_printerr ("Error accessing %s: %s\n", path, g_strerror (errno));
goto out;
}
- command_line = g_strjoinv (" ", argv + n);
- exec_argv = argv + n;
- /* Look up information about the user we care about - yes, the return
- * value of this function is a bit funky
- */
- rc = getpwnam_r (opt_user, &pwstruct, pwbuf, sizeof pwbuf, &pw);
- if (rc == 0 && pw == NULL)
- {
- g_printerr ("User `%s' does not exist.\n", opt_user);
- goto out;
- }
- else if (pw == NULL)
+ if (!command_line)
{
- g_printerr ("Error getting information for user `%s': %s\n", opt_user, g_strerror (rc));
- goto out;
+ /* If you change this, be sure to change the path == NULL case
+ above too */
+ command_line = g_strjoinv (" ", argv + n);
+ exec_argv = argv + n;
}
/* now save the environment variables we care about */
@@ -737,6 +757,8 @@ main (int argc, char *argv[])
goto out;
}
+ g_assert (path != NULL);
+ g_assert (exec_argv != NULL);
action_id = find_action_for_path (authority,
path,
exec_argv[1],