/* Define to 1 if you have the `posix_openpt' function. */
#undef HAVE_POSIX_OPENPT
+/* Define to 1 if you have the `priv_set' function. */
+#undef HAVE_PRIV_SET
+
/* Define to 1 if you have the <project.h> header file. */
#undef HAVE_PROJECT_H
: ${mansectform='4'}
: ${with_rpath='yes'}
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ for ac_func in priv_set
+do :
+ ac_fn_c_check_func "$LINENO" "priv_set" "ac_cv_func_priv_set"
+if test "x$ac_cv_func_priv_set" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PRIV_SET 1
+_ACEOF
+
+fi
+done
+
;;
*-*-aix*)
# To get all prototypes (so we pass -Wall)
: ${mansectform='4'}
: ${with_rpath='yes'}
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
+ AC_CHECK_FUNCS(priv_set)
;;
*-*-aix*)
# To get all prototypes (so we pass -Wall)
def_env_reset = FALSE;
/* Build a new environment that avoids any nasty bits. */
- rebuild_env(def_noexec);
+ rebuild_env(def_noexec); /* XXX - move noexec bits */
/* Require a password if sudoers says so. */
if (def_authenticate) {
command_info[info_len++] = estrdup("iolog_compress=true");
}
+ if (def_noexec)
+ command_info[info_len++] = estrdup("noexec=true");
+
log_allowed(validated);
if (ISSET(sudo_mode, MODE_CHECK))
rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
* Fork and execute a command, returns the child's pid.
* Sends errno back on sv[1] if execve() fails.
*/
-static int fork_cmnd(struct command_details *details, char *argv[],
- char *envp[], int sv[2])
+static int fork_cmnd(struct command_details *details, int sv[2])
{
struct command_status cstat;
sigaction_t sa;
closefrom(details->closefrom);
#ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED))
- selinux_execve(details->command, argv, envp);
+ selinux_execve(details->command, details->argv, details->envp);
else
#endif
- my_execve(details->command, argv, envp);
+ my_execve(details->command, details->argv, details->envp);
}
cstat.type = CMD_ERRNO;
cstat.val = errno;
* we fact that we have two different controlling terminals to deal with.
*/
int
-sudo_execve(struct command_details *details, char *argv[], char *envp[],
- struct command_status *cstat)
+sudo_execve(struct command_details *details, struct command_status *cstat)
{
int maxfd, n, nready, sv[2], log_io = FALSE;
fd_set *fdsr, *fdsw;
* to and from pty. Adjusts maxfd as needed.
*/
if (log_io)
- child = fork_pty(details, argv, envp, sv, &maxfd);
+ child = fork_pty(details, sv, &maxfd);
else
- child = fork_cmnd(details, argv, envp, sv);
+ child = fork_cmnd(details, sv);
close(sv[1]);
/* Set command timeout if specified. */
static struct io_buffer *iobufs;
static void flush_output(void);
-static int exec_monitor(struct command_details *details, char *argv[],
- char *envp[], int backchannel);
-static void exec_pty(struct command_details *detail, char *argv[],
- char *envp[]);
+static int exec_monitor(struct command_details *details, int backchannel);
+static void exec_pty(struct command_details *detail);
static void sigwinch(int s);
static void sync_ttysize(int src, int dst);
static void deliver_signal(pid_t pid, int signo);
* Returns the child pid.
*/
int
-fork_pty(struct command_details *details, char *argv[], char *envp[],
- int sv[], int *maxfd)
+fork_pty(struct command_details *details, int sv[], int *maxfd)
{
struct command_status cstat;
struct io_buffer *iob;
close(io_pipe[STDOUT_FILENO][0]);
if (io_pipe[STDERR_FILENO][0])
close(io_pipe[STDERR_FILENO][0]);
- exec_monitor(details, argv, envp, sv[1]);
+ exec_monitor(details, sv[1]);
}
cstat.type = CMD_ERRNO;
cstat.val = errno;
* Returns an error if fork(2) fails, else calls _exit(2).
*/
static int
-exec_monitor(struct command_details *details, char *argv[], char *envp[],
- int backchannel)
+exec_monitor(struct command_details *details, int backchannel)
{
struct command_status cstat;
struct timeval tv;
restore_signals();
/* setup tty and exec command */
- exec_pty(details, argv, envp);
+ exec_pty(details);
cstat.type = CMD_ERRNO;
cstat.val = errno;
if (write(errpipe[1], &cstat, sizeof(cstat)) == -1)
* Returns only if execve() fails.
*/
static void
-exec_pty(struct command_details *details, char *argv[], char *envp[])
+exec_pty(struct command_details *details)
{
pid_t self = getpid();
closefrom(details->closefrom);
#ifdef HAVE_SELINUX
if (ISSET(details->flags, CD_RBAC_ENABLED))
- selinux_execve(details->command, argv, envp);
+ selinux_execve(details->command, details->argv, details->envp);
else
#endif
- my_execve(details->command, argv, envp);
+ my_execve(details->command, details->argv, details->envp);
}
/*
# endif /* __hpux */
# include <prot.h>
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
+#ifdef HAVE_PRIV_SET
+# include <priv.h>
+#endif
#include "sudo.h"
#include "sudo_plugin.h"
}
}
command_info_to_details(command_info, &command_details);
+ command_details.argv = argv_out;
+ command_details.envp = user_env_out;
if (ISSET(sudo_mode, MODE_BACKGROUND))
SET(command_details.flags, CD_BACKGROUND);
/* Restore coredumpsize resource limit before running. */
(void) setrlimit(RLIMIT_CORE, &corelimit);
#endif /* RLIMIT_CORE && !SUDO_DEVEL */
if (ISSET(command_details.flags, CD_SUDOEDIT)) {
- exitcode = sudo_edit(&command_details, argv_out, user_env_out);
+ exitcode = sudo_edit(&command_details);
} else {
if (ISSET(sudo_mode, MODE_SHELL)) {
/* Escape meta chars if running a shell with args. */
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);
+ exitcode = run_command(&command_details);
}
/* The close method was called by sudo_edit/run_command. */
break;
}
}
+ /* XXX - should do env-based noexec here too */
+#ifdef HAVE_PRIV_SET
+ if (ISSET(details->flags, CD_NOEXEC)) {
+ if (priv_set(PRIV_OFF, PRIV_LIMIT, "PRIV_PROC_EXEC", NULL) == -1)
+ warning("unable to remove PRIV_PROC_EXEC from PRIV_LIMIT");
+ }
+#endif /* HAVE_PRIV_SET */
+
#ifdef HAVE_SETRESUID
if (setresuid(details->uid, details->euid, details->euid) != 0) {
warning("unable to change to runas uid (%u, %u)", details->uid,
* Run the command and wait for it to complete.
*/
int
-run_command(struct command_details *details, char *argv[], char *envp[])
+run_command(struct command_details *details)
{
struct plugin_container *plugin;
struct command_status cstat;
cstat.type = CMD_INVALID;
cstat.val = 0;
- sudo_execve(details, argv, envp, &cstat);
+ sudo_execve(details, &cstat);
switch (cstat.type) {
case CMD_ERRNO:
const char *chroot;
const char *selinux_role;
const char *selinux_type;
+ char **argv;
+ char **envp;
};
/* Status passed between parent and child via socketpair */
void zero_bytes(volatile void *, size_t);
/* exec.c */
-int sudo_execve(struct command_details *details, char *argv[], char *envp[],
- struct command_status *cstat);
+int sudo_execve(struct command_details *details, struct command_status *cstat);
void save_signals(void);
void restore_signals(void);
/* sudo.c */
int exec_setup(struct command_details *details, const char *ptyname, int ptyfd);
-int run_command(struct command_details *details, char *argv[],
- char *envp[]);
+int run_command(struct command_details *details);
void sudo_debug(int level, const char *format, ...) __printflike(2, 3);
extern int debug_level;
extern const char *list_user, *runas_user, *runas_group;
extern struct user_details user_details;
/* sudo_edit.c */
-int sudo_edit(struct command_details *details, char *argv[], char *envp[]);
+int sudo_edit(struct command_details *details);
/* parse_args.c */
void usage(int);
* Wrapper to allow users to edit privileged files with their own uid.
*/
int
-sudo_edit(struct command_details *command_details, char *argv[], char *envp[])
+sudo_edit(struct command_details *command_details)
{
struct command_details editor_details;
ssize_t nread, nwritten;
* The user's editor must be separated from the files to be
* edited by a "--" option.
*/
- for (ap = argv; *ap != NULL; ap++) {
+ for (ap = command_details->argv; *ap != NULL; ap++) {
if (files)
nfiles++;
else if (strcmp(*ap, "--") == 0)
nargc = editor_argc + nfiles;
nargv = (char **) emalloc2(nargc + 1, sizeof(char *));
for (ac = 0; ac < editor_argc; ac++)
- nargv[ac] = argv[ac];
+ nargv[ac] = command_details->argv[ac];
for (i = 0; i < nfiles && ac < nargc; )
nargv[ac++] = tf[i++].tfile;
nargv[ac] = NULL;
editor_details.egid = user_details.gid;
editor_details.ngroups = user_details.ngroups;
editor_details.groups = user_details.groups;
- rval = run_command(&editor_details, nargv, envp);
+ editor_details.argv = nargv;
+ rval = run_command(&editor_details);
gettimeofday(&tv2, NULL);
/* Copy contents of temp files to real ones */
* Must have the ability to change the effective uid to use sudoedit.
*/
int
-sudo_edit(struct command_details *command_details, char *argv[], char *envp[])
+sudo_edit(struct command_details *command_details)
{
return 1;
}
int pipe_nonblock(int fds[2]);
/* exec_pty.c */
-int fork_pty(struct command_details *details, char *argv[], char *envp[],
- int sv[], int *maxfd);
+int fork_pty(struct command_details *details, int sv[], int *maxfd);
int perform_io(fd_set *fdsr, fd_set *fdsw, struct command_status *cstat);
int suspend_parent(int signo);
void fd_set_iobs(fd_set *fdsr, fd_set *fdsw);