Perform command escaping for "sudo -s" and "sudo -i" after validating
sudoers so the sudoers entries don't need to have all the backslashes.
This commit is contained in:
34
src/sudo.c
34
src/sudo.c
@@ -51,12 +51,13 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <pwd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <time.h>
|
||||
#endif
|
||||
@@ -117,6 +118,7 @@ static int iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||
int argc, char * const argv[], char * const user_env[]);
|
||||
static void iolog_close(struct plugin_container *plugin, int exit_status,
|
||||
int error);
|
||||
static char *escape_cmnd(const char *src);
|
||||
|
||||
/* Policy plugin convenience functions. */
|
||||
static int policy_open(struct plugin_container *plugin, char * const settings[],
|
||||
@@ -278,6 +280,12 @@ main(int argc, char *argv[], char *envp[])
|
||||
if (ISSET(command_details.flags, CD_SUDOEDIT)) {
|
||||
exitcode = sudo_edit(&command_details, argv_out, user_env_out);
|
||||
} else {
|
||||
if (ISSET(sudo_mode, MODE_SHELL)) {
|
||||
/* Escape meta chars if running a shell with args. */
|
||||
if (argv_out[1] != NULL && strcmp(argv_out[1], "-c") == 0 &&
|
||||
argv_out[2] != NULL && argv_out[3] == NULL)
|
||||
argv_out[2] = escape_cmnd(argv_out[2]);
|
||||
}
|
||||
exitcode = run_command(&command_details, argv_out, user_env_out);
|
||||
}
|
||||
/* The close method was called by sudo_edit/run_command. */
|
||||
@@ -907,6 +915,30 @@ done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Escape any non-alpha numeric or blank characters to make sure
|
||||
* they are not interpreted specially by the shell.
|
||||
*/
|
||||
static char *
|
||||
escape_cmnd(const char *src)
|
||||
{
|
||||
char *cmnd, *dst;
|
||||
|
||||
/* Worst case scenario, we have to escape everything. */
|
||||
cmnd = dst = emalloc((2 * strlen(src)) + 1);
|
||||
while (*src != '\0') {
|
||||
if (!isalnum((unsigned char)*src) && !isspace((unsigned char)*src) &&
|
||||
*src != '_' && *src != '-') {
|
||||
/* quote potential meta character */
|
||||
*dst++ = '\\';
|
||||
}
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst++ = '\0';
|
||||
|
||||
return cmnd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run the command and wait for it to complete.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user