If plugin sets "sudoedit=true" in the command info, enable
sudoedit mode even if not invoked as sudoedit. This allows a plugin to enable sudoedit when the user runs an editor.
This commit is contained in:
@@ -230,7 +230,7 @@ check_passwd(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char **
|
static char **
|
||||||
build_command_info(char *command)
|
build_command_info(char *command, int sudoedit)
|
||||||
{
|
{
|
||||||
static char **command_info;
|
static char **command_info;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -250,51 +250,17 @@ build_command_info(char *command)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sudoedit) {
|
||||||
|
command_info[i] = strdup("sudoedit=true");
|
||||||
|
if (command_info[i++] == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
#ifdef USE_TIMEOUT
|
#ifdef USE_TIMEOUT
|
||||||
command_info[i++] = "timeout=30";
|
command_info[i++] = "timeout=30";
|
||||||
#endif
|
#endif
|
||||||
return command_info;
|
return command_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Plugin policy check function.
|
|
||||||
* Simple example that prompts for a password, hard-coded to "test".
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
policy_check(int argc, char * const argv[],
|
|
||||||
char *env_add[], char **command_info_out[],
|
|
||||||
char **argv_out[], char **user_env_out[])
|
|
||||||
{
|
|
||||||
char *command;
|
|
||||||
|
|
||||||
if (!argc || argv[0] == NULL) {
|
|
||||||
sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_passwd())
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
command = find_in_path(argv[0], plugin_state.envp);
|
|
||||||
if (command == NULL) {
|
|
||||||
sudo_log(SUDO_CONV_ERROR_MSG, "%s: command not found\n", argv[0]);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No changes to argv or envp */
|
|
||||||
*argv_out = (char **)argv;
|
|
||||||
*user_env_out = plugin_state.envp;
|
|
||||||
|
|
||||||
/* Setup command info. */
|
|
||||||
*command_info_out = build_command_info(command);
|
|
||||||
if (*command_info_out == NULL) {
|
|
||||||
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
find_editor(int nfiles, char * const files[], char **argv_out[])
|
find_editor(int nfiles, char * const files[], char **argv_out[])
|
||||||
{
|
{
|
||||||
@@ -353,6 +319,59 @@ find_editor(int nfiles, char * const files[], char **argv_out[])
|
|||||||
return editor_path;
|
return editor_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Plugin policy check function.
|
||||||
|
* Simple example that prompts for a password, hard-coded to "test".
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
policy_check(int argc, char * const argv[],
|
||||||
|
char *env_add[], char **command_info_out[],
|
||||||
|
char **argv_out[], char **user_env_out[])
|
||||||
|
{
|
||||||
|
char *command;
|
||||||
|
|
||||||
|
if (!argc || argv[0] == NULL) {
|
||||||
|
sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_passwd())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
command = find_in_path(argv[0], plugin_state.envp);
|
||||||
|
if (command == NULL) {
|
||||||
|
sudo_log(SUDO_CONV_ERROR_MSG, "%s: command not found\n", argv[0]);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If "sudo vi" is run, auto-convert to sudoedit.
|
||||||
|
*/
|
||||||
|
if (strcmp(command, _PATH_VI) == 0) {
|
||||||
|
/* Rebuild argv using editor */
|
||||||
|
command = find_editor(argc - 1, argv + 1, argv_out);
|
||||||
|
if (command == NULL) {
|
||||||
|
sudo_log(SUDO_CONV_ERROR_MSG, "unable to find valid editor\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No changes to argv */
|
||||||
|
*argv_out = (char **)argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No changes to envp */
|
||||||
|
*user_env_out = plugin_state.envp;
|
||||||
|
|
||||||
|
/* Setup command info. */
|
||||||
|
*command_info_out = build_command_info(command, *argv_out != argv);
|
||||||
|
if (*command_info_out == NULL) {
|
||||||
|
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Plugin policy edit function.
|
* Plugin policy edit function.
|
||||||
* Simple example that prompts for a password, hard-coded to "test".
|
* Simple example that prompts for a password, hard-coded to "test".
|
||||||
@@ -378,7 +397,7 @@ policy_edit(int argc, char * const argv[],
|
|||||||
*user_env_out = plugin_state.envp;
|
*user_env_out = plugin_state.envp;
|
||||||
|
|
||||||
/* Setup command info. */
|
/* Setup command info. */
|
||||||
*command_info_out = build_command_info(editor);
|
*command_info_out = build_command_info(editor, TRUE);
|
||||||
if (*command_info_out == NULL) {
|
if (*command_info_out == NULL) {
|
||||||
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
|
sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
|
11
src/sudo.c
11
src/sudo.c
@@ -240,16 +240,18 @@ main(int argc, char *argv[], char *envp[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
command_info_to_details(command_info, &command_details);
|
command_info_to_details(command_info, &command_details);
|
||||||
|
if (ISSET(sudo_mode, MODE_EDIT))
|
||||||
|
SET(command_details.flags, CD_SUDOEDIT);
|
||||||
/* Restore coredumpsize resource limit before running. */
|
/* Restore coredumpsize resource limit before running. */
|
||||||
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
|
||||||
(void) setrlimit(RLIMIT_CORE, &corelimit);
|
(void) setrlimit(RLIMIT_CORE, &corelimit);
|
||||||
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
|
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
|
||||||
/* run_command will call the close method for us */
|
if (ISSET(command_details.flags, CD_SUDOEDIT)) {
|
||||||
if (sudo_mode & MODE_EDIT) {
|
|
||||||
exitcode = sudo_edit(&command_details, argv_out, user_env_out);
|
exitcode = sudo_edit(&command_details, argv_out, user_env_out);
|
||||||
} else {
|
} else {
|
||||||
exitcode = run_command(&command_details, argv_out, user_env_out);
|
exitcode = run_command(&command_details, argv_out, user_env_out);
|
||||||
}
|
}
|
||||||
|
/* The close method was called by sudo_edit/run_command. */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errorx(1, "unexpected sudo mode 0x%x", sudo_mode);
|
errorx(1, "unexpected sudo mode 0x%x", sudo_mode);
|
||||||
@@ -538,6 +540,11 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
case 's':
|
case 's':
|
||||||
SET_STRING("selinux_role=", selinux_role)
|
SET_STRING("selinux_role=", selinux_role)
|
||||||
SET_STRING("selinux_type=", selinux_type)
|
SET_STRING("selinux_type=", selinux_type)
|
||||||
|
if (strncmp("sudoedit=", info[i], sizeof("sudoedit=") - 1) == 0) {
|
||||||
|
if (atobool(info[i] + sizeof("sudoedit=") - 1) == TRUE)
|
||||||
|
SET(details->flags, CD_SUDOEDIT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
||||||
|
@@ -115,6 +115,7 @@ struct user_details {
|
|||||||
#define CD_SET_PRIORITY 0x0040
|
#define CD_SET_PRIORITY 0x0040
|
||||||
#define CD_SET_UMASK 0x0080
|
#define CD_SET_UMASK 0x0080
|
||||||
#define CD_SET_TIMEOUT 0x0100
|
#define CD_SET_TIMEOUT 0x0100
|
||||||
|
#define CD_SUDOEDIT 0x0200
|
||||||
|
|
||||||
struct command_details {
|
struct command_details {
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
|
@@ -55,18 +55,6 @@
|
|||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Emulate seteuid() via setresuid() or setreuid()
|
|
||||||
* Needed on HP-UX and perhaps others.
|
|
||||||
*/
|
|
||||||
#if defined(HAVE_SETRESUID)
|
|
||||||
# define seteuid(u) setresuid(-1, u, -1)
|
|
||||||
# define setegid(g) setresgid(-1, g, -1)
|
|
||||||
#elif defined(HAVE_SETREUID)
|
|
||||||
# define seteuid(u) setreuid(-1, u)
|
|
||||||
# define setegid(g) setregid(-1, g)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct user_details user_details;
|
extern struct user_details user_details;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user