su.c: implement --exec
It's now possible to run commands as other users without shell interpolation by using "--exec": Read /etc/shadow as root without specifying user: ``` su --exec /bin/cat -- /etc/shadow ``` Or specify user: ``` su --exec /bin/cat root -- /etc/shadow ```
This commit is contained in:
parent
6f38f43fdd
commit
4047d1fe8e
36
src/su.c
36
src/su.c
@ -94,6 +94,7 @@ static bool do_interactive_shell = false;
|
|||||||
static bool fakelogin = false;
|
static bool fakelogin = false;
|
||||||
static /*@observer@*/const char *shellstr;
|
static /*@observer@*/const char *shellstr;
|
||||||
static /*@null@*/char *command = NULL;
|
static /*@null@*/char *command = NULL;
|
||||||
|
static /*@null@*/char *exec_command = NULL;
|
||||||
static int optidx;
|
static int optidx;
|
||||||
|
|
||||||
|
|
||||||
@ -440,12 +441,14 @@ static void usage (int status)
|
|||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -c, --command COMMAND pass COMMAND to the invoked shell\n"
|
" -c, --command COMMAND pass COMMAND to the invoked shell\n"
|
||||||
|
" -e, --exec PATH run PATH without shell, follow -- with args\n"
|
||||||
" -h, --help display this help message and exit\n"
|
" -h, --help display this help message and exit\n"
|
||||||
" -, -l, --login make the shell a login shell\n"
|
" -, -l, --login make the shell a login shell\n"
|
||||||
" -m, -p,\n"
|
" -m, -p,\n"
|
||||||
" --preserve-environment do not reset environment variables, and\n"
|
" --preserve-environment do not reset environment variables, and\n"
|
||||||
" keep the same shell\n"
|
" keep the same shell\n"
|
||||||
" -s, --shell SHELL use SHELL instead of the default in passwd\n"
|
" -s, --shell SHELL use SHELL instead of the default in passwd\n"
|
||||||
|
" -- pass all subsequent arguments on as-is\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If no username is given, assume root.\n"), (E_SUCCESS != status) ? stderr : stdout);
|
"If no username is given, assume root.\n"), (E_SUCCESS != status) ? stderr : stdout);
|
||||||
exit (status);
|
exit (status);
|
||||||
@ -820,6 +823,12 @@ static void process_flags (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
command = argv[++optidx];
|
command = argv[++optidx];
|
||||||
|
} else if (flags_match (arg, "--exec", "-e", NULL)) {
|
||||||
|
if (optidx == argc - 1) {
|
||||||
|
flag_arg_required (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
exec_command = argv[++optidx];
|
||||||
} else if (flags_match (arg, "--help", "-h", NULL)) {
|
} else if (flags_match (arg, "--help", "-h", NULL)) {
|
||||||
usage (E_SUCCESS);
|
usage (E_SUCCESS);
|
||||||
} else if (flags_match (arg, "--login", "-l", "-")) {
|
} else if (flags_match (arg, "--login", "-l", "-")) {
|
||||||
@ -843,6 +852,17 @@ static void process_flags (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != exec_command && NULL != command) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: COMMAND and PATH are mutually exclusive\n"),
|
||||||
|
argv[0]);
|
||||||
|
usage (E_USAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != exec_command) {
|
||||||
|
command = exec_command;
|
||||||
|
}
|
||||||
|
|
||||||
/* if next arg is not "--", treat as USER */
|
/* if next arg is not "--", treat as USER */
|
||||||
if (optidx < argc && strcmp (argv[optidx], "--")) {
|
if (optidx < argc && strcmp (argv[optidx], "--")) {
|
||||||
STRFCPY (name, argv[optidx++]); /* use this login id */
|
STRFCPY (name, argv[optidx++]); /* use this login id */
|
||||||
@ -1226,10 +1246,18 @@ int main (int argc, char **argv)
|
|||||||
* with the rest of the command line included.
|
* with the rest of the command line included.
|
||||||
*/
|
*/
|
||||||
argv[-1] = cp;
|
argv[-1] = cp;
|
||||||
execve_shell (shellstr, &argv[-1], environ);
|
|
||||||
err = errno;
|
if (NULL != exec_command) {
|
||||||
(void) fprintf (stderr,
|
(void) execve (command, &argv[1], environ);
|
||||||
_("Cannot execute %s\n"), shellstr);
|
err = errno;
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
_("Cannot execute \'%s\'\n"), command);
|
||||||
|
} else {
|
||||||
|
execve_shell (shellstr, &argv[-1], environ);
|
||||||
|
err = errno;
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
_("Cannot execute \'%s\'\n"), shellstr);
|
||||||
|
}
|
||||||
errno = err;
|
errno = err;
|
||||||
} else {
|
} else {
|
||||||
(void) shell (shellstr, cp, environ);
|
(void) shell (shellstr, cp, environ);
|
||||||
|
Loading…
Reference in New Issue
Block a user