diff --git a/src/exec.c b/src/exec.c index 2af81c880..072b53d13 100644 --- a/src/exec.c +++ b/src/exec.c @@ -407,7 +407,8 @@ direct_exec_allowed(struct command_details *details) * we fact that we have two different controlling terminals to deal with. */ int -sudo_execute(struct command_details *details, struct command_status *cstat) +sudo_execute(struct command_details *details, struct user_details *user_details, + struct command_status *cstat) { debug_decl(sudo_execute, SUDO_DEBUG_EXEC); @@ -461,7 +462,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat) * is configured, this returns false and we run the command without a pty. */ if (sudo_needs_pty(details)) { - if (exec_pty(details, cstat)) + if (exec_pty(details, user_details, cstat)) goto done; } @@ -481,7 +482,7 @@ sudo_execute(struct command_details *details, struct command_status *cstat) /* * Run the command in the existing tty (if any) and wait for it to finish. */ - exec_nopty(details, cstat); + exec_nopty(details, user_details, cstat); done: /* The caller will run any plugin close functions. */ diff --git a/src/exec_nopty.c b/src/exec_nopty.c index e4e077b7b..f973fcc0e 100644 --- a/src/exec_nopty.c +++ b/src/exec_nopty.c @@ -207,8 +207,9 @@ signal_cb_nopty(int signo, int what, void *v) * Allocates events for the signal pipe and error pipe. */ static void -fill_exec_closure(struct exec_closure *ec, - struct command_status *cstat, struct command_details *details, int errfd) +fill_exec_closure(struct exec_closure *ec, struct command_status *cstat, + struct command_details *details, struct user_details *user_details, + int errfd) { debug_decl(fill_exec_closure, SUDO_DEBUG_EXEC); @@ -217,8 +218,8 @@ fill_exec_closure(struct exec_closure *ec, ec->ppgrp = getpgrp(); ec->cstat = cstat; ec->details = details; - ec->rows = user_details.ts_rows; - ec->cols = user_details.ts_cols; + ec->rows = user_details->ts_rows; + ec->cols = user_details->ts_cols; /* Setup event base and events. */ ec->evbase = details->evbase; @@ -535,7 +536,8 @@ interpose_pipes(struct exec_closure *ec, int io_pipe[3][2]) * Execute a command and wait for it to finish. */ void -exec_nopty(struct command_details *details, struct command_status *cstat) +exec_nopty(struct command_details *details, struct user_details *user_details, + struct command_status *cstat) { int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } }; int errpipe[2], intercept_sv[2] = { -1, -1 }; @@ -658,7 +660,7 @@ exec_nopty(struct command_details *details, struct command_status *cstat) * Fill in exec closure, allocate event base, signal events and * the error pipe event. */ - fill_exec_closure(&ec, cstat, details, errpipe[0]); + fill_exec_closure(&ec, cstat, details, user_details, errpipe[0]); if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) { int rc = 1; diff --git a/src/exec_pty.c b/src/exec_pty.c index 1000c8b82..10bc4fa75 100644 --- a/src/exec_pty.c +++ b/src/exec_pty.c @@ -66,7 +66,7 @@ static void schedule_signal(struct exec_closure *ec, int signo); * Returns the dyamically allocated pty name on success, NULL on failure. */ static char * -pty_setup(struct command_details *details, const char *tty) +pty_setup(struct command_details *details) { char *ptyname = NULL; debug_decl(pty_setup, SUDO_DEBUG_EXEC); @@ -83,12 +83,12 @@ pty_setup(struct command_details *details, const char *tty) if (ptyname == NULL) sudo_fatal("%s", U_("unable to allocate pty")); - /* Update tty name in command details (used by monitor, SELinux, AIX). */ - details->tty = ptyname; - /* Add entry to utmp/utmpx? */ if (ISSET(details->flags, CD_SET_UTMP)) - utmp_login(tty, ptyname, io_fds[SFD_FOLLOWER], details->utmp_user); + utmp_login(details->tty, ptyname, io_fds[SFD_FOLLOWER], details->utmp_user); + + /* Update tty name in command details (used by monitor, SELinux, AIX). */ + details->tty = ptyname; sudo_debug_printf(SUDO_DEBUG_INFO, "%s: %s fd %d, pty leader fd %d, pty follower fd %d", @@ -935,8 +935,8 @@ fwdchannel_cb(int sock, int what, void *v) */ static void fill_exec_closure(struct exec_closure *ec, struct command_status *cstat, - struct command_details *details, pid_t sudo_pid, pid_t ppgrp, - int backchannel) + struct command_details *details, struct user_details *user_details, + pid_t sudo_pid, pid_t ppgrp, int backchannel) { debug_decl(fill_exec_closure, SUDO_DEBUG_EXEC); @@ -946,8 +946,8 @@ fill_exec_closure(struct exec_closure *ec, struct command_status *cstat, ec->cmnd_pid = -1; ec->cstat = cstat; ec->details = details; - ec->rows = user_details.ts_rows; - ec->cols = user_details.ts_cols; + ec->rows = user_details->ts_rows; + ec->cols = user_details->ts_cols; /* Reset cstat for running the command. */ cstat->type = CMD_INVALID; @@ -1063,7 +1063,8 @@ fill_exec_closure(struct exec_closure *ec, struct command_status *cstat, * we fact that we have two different controlling terminals to deal with. */ bool -exec_pty(struct command_details *details, struct command_status *cstat) +exec_pty(struct command_details *details, struct user_details *user_details, + struct command_status *cstat) { int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } }; bool interpose[3] = { false, false, false }; @@ -1081,7 +1082,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) /* * Allocate a pty if sudo is running in a terminal. */ - ec.ptyname = pty_setup(details, user_details.tty); + ec.ptyname = pty_setup(details); if (ec.ptyname == NULL) debug_return_bool(false); @@ -1360,7 +1361,7 @@ exec_pty(struct command_details *details, struct command_status *cstat) * Fill in exec closure, allocate event base, signal events and * the backchannel event. */ - fill_exec_closure(&ec, cstat, details, sudo_pid, ppgrp, sv[0]); + fill_exec_closure(&ec, cstat, details, user_details, sudo_pid, ppgrp, sv[0]); /* Create event and closure for intercept mode. */ if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) { diff --git a/src/parse_args.c b/src/parse_args.c index 8e3d62e10..437ecad3f 100644 --- a/src/parse_args.c +++ b/src/parse_args.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 1993-1996, 1998-2022 Todd C. Miller + * Copyright (c) 1993-1996, 1998-2023 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -226,8 +226,9 @@ parse_env_list(struct environment *e, char *list) * for the command to be run (if we are running one). */ int -parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, - struct sudo_settings **settingsp, char ***env_addp, const char **list_userp) +parse_args(int argc, char **argv, const char *shell, int *old_optind, + int *nargc, char ***nargv, struct sudo_settings **settingsp, + char ***env_addp, const char **list_userp) { const char *progname, *short_opts = sudo_short_opts; struct option *long_opts = sudo_long_opts; @@ -647,7 +648,7 @@ parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, if (!gc_add(GC_PTR, av)) exit(EXIT_FAILURE); - av[0] = (char *)user_details.shell; /* plugin may override shell */ + av[0] = (char *)shell; /* plugin may override shell */ if (cmnd != NULL) { av[1] = (char *)"-c"; av[2] = cmnd; diff --git a/src/sudo.c b/src/sudo.c index d0599eba8..fc7ee20ea 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -76,7 +76,7 @@ struct plugin_container policy_plugin; struct plugin_container_list io_plugins = TAILQ_HEAD_INITIALIZER(io_plugins); struct plugin_container_list audit_plugins = TAILQ_HEAD_INITIALIZER(audit_plugins); struct plugin_container_list approval_plugins = TAILQ_HEAD_INITIALIZER(approval_plugins); -struct user_details user_details; +static struct user_details user_details; int sudo_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER; static struct sudo_event_base *sudo_event_base; @@ -206,8 +206,8 @@ main(int argc, char *argv[], char *envp[]) /* Parse command line arguments, preserving the original argv/envp. */ submit_argv = argv; submit_envp = envp; - sudo_mode = parse_args(argc, argv, &submit_optind, &nargc, &nargv, - &sudo_settings, &env_add, &list_user); + sudo_mode = parse_args(argc, argv, user_details.shell, &submit_optind, + &nargc, &nargv, &sudo_settings, &env_add, &list_user); sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode 0x%x", sudo_mode); /* Print sudo version early, in case of plugin init failure. */ @@ -295,7 +295,7 @@ main(int argc, char *argv[], char *envp[]) if (ISSET(sudo_mode, MODE_BACKGROUND)) SET(command_details.flags, CD_BACKGROUND); if (ISSET(command_details.flags, CD_SUDOEDIT)) { - status = sudo_edit(&command_details); + status = sudo_edit(&command_details, &user_details.cred); } else { status = run_command(&command_details); } @@ -1039,7 +1039,7 @@ run_command(struct command_details *details) debug_return_int(status); } - sudo_execute(details, &cstat); + sudo_execute(details, &user_details, &cstat); switch (cstat.type) { case CMD_ERRNO: @@ -2153,6 +2153,16 @@ free_plugin_container(struct plugin_container *plugin, bool ioplugin) debug_return; } +/* + * Getter for the user cred. + * Needed for sudo_askpass() in tgetpass.c + */ +struct sudo_cred * +sudo_get_user_cred(void) +{ + return &user_details.cred; +} + bool gc_add(enum sudo_gc_types type, void *v) { diff --git a/src/sudo.h b/src/sudo.h index 503a0af76..1ca47e448 100644 --- a/src/sudo.h +++ b/src/sudo.h @@ -245,12 +245,12 @@ char *tgetpass(const char *prompt, int timeout, int flags, struct sudo_conv_callback *callback); /* exec.c */ -int sudo_execute(struct command_details *details, struct command_status *cstat); +int sudo_execute(struct command_details *details, struct user_details *ud, struct command_status *cstat); /* parse_args.c */ -int parse_args(int argc, char **argv, int *old_optind, int *nargc, - char ***nargv, struct sudo_settings **settingsp, char ***env_addp, - const char **list_user); +int parse_args(int argc, char **argv, const char *shell, int *old_optind, + int *nargc, char ***nargv, struct sudo_settings **settingsp, + char ***env_addp, const char **list_user); extern int tgetpass_flags; /* get_pty.c */ @@ -272,11 +272,11 @@ bool audit_error(const char *plugin_name, unsigned int plugin_type, const char *audit_msg, char * const command_info[]); bool approval_check(char * const command_info[], char * const run_argv[], char * const run_envp[]); -extern struct user_details user_details; +struct sudo_cred *sudo_get_user_cred(void); extern int sudo_debug_instance; /* sudo_edit.c */ -int sudo_edit(struct command_details *details); +int sudo_edit(struct command_details *command_details, struct sudo_cred *user_cred); /* parse_args.c */ sudo_noreturn void usage(void); diff --git a/src/sudo_edit.c b/src/sudo_edit.c index 21ac97f2e..38ac471fe 100644 --- a/src/sudo_edit.c +++ b/src/sudo_edit.c @@ -163,7 +163,8 @@ sudo_edit_mktemp(const char *ofile, char **tfile) */ static int sudo_edit_create_tfiles(struct command_details *command_details, - struct tempfile *tf, char *files[], int nfiles) + struct sudo_cred *user_cred, struct tempfile *tf, char *files[], + int nfiles) { int i, j, tfd, ofd, rc; struct timespec times[2]; @@ -180,19 +181,18 @@ sudo_edit_create_tfiles(struct command_details *command_details, command_details->cred.ngroups, command_details->cred.groups); ofd = sudo_edit_open(files[i], O_RDONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details->flags, - &user_details.cred, &command_details->cred); + user_cred, &command_details->cred); if (ofd != -1 || errno == ENOENT) { if (ofd != -1) { rc = fstat(ofd, &sb); } else { /* New file, verify parent dir exists and is not writable. */ memset(&sb, 0, sizeof(sb)); - if (sudo_edit_parent_valid(files[i], command_details->flags, &user_details.cred, &command_details->cred)) + if (sudo_edit_parent_valid(files[i], command_details->flags, user_cred, &command_details->cred)) rc = 0; } } - switch_user(ROOT_UID, user_details.cred.egid, - user_details.cred.ngroups, user_details.cred.groups); + switch_user(ROOT_UID, user_cred->egid, user_cred->ngroups, user_cred->groups); if (ofd != -1 && !S_ISREG(sb.st_mode)) { sudo_warnx(U_("%s: not a regular file"), files[i]); close(ofd); @@ -217,9 +217,9 @@ sudo_edit_create_tfiles(struct command_details *command_details, tf[j].osize = sb.st_size; // -V614 mtim_get(&sb, tf[j].omtim); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, - "seteuid(%u)", (unsigned int)user_details.cred.uid); - if (seteuid(user_details.cred.uid) != 0) - sudo_fatal("seteuid(%u)", (unsigned int)user_details.cred.uid); + "seteuid(%u)", (unsigned int)user_cred->uid); + if (seteuid(user_cred->uid) != 0) + sudo_fatal("seteuid(%u)", (unsigned int)user_cred->uid); tfd = sudo_edit_mktemp(tf[j].ofile, &tf[j].tfile); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, "seteuid(%u)", ROOT_UID); @@ -267,7 +267,8 @@ sudo_edit_create_tfiles(struct command_details *command_details, */ static int sudo_edit_copy_tfiles(struct command_details *command_details, - struct tempfile *tf, int nfiles, struct timespec *times) + struct sudo_cred *user_cred, struct tempfile *tf, + int nfiles, struct timespec *times) { int i, tfd, ofd, errors = 0; struct timespec ts; @@ -278,16 +279,16 @@ sudo_edit_copy_tfiles(struct command_details *command_details, /* Copy contents of temp files to real ones. */ for (i = 0; i < nfiles; i++) { sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, - "seteuid(%u)", (unsigned int)user_details.cred.uid); - if (seteuid(user_details.cred.uid) != 0) - sudo_fatal("seteuid(%u)", (unsigned int)user_details.cred.uid); + "seteuid(%u)", (unsigned int)user_cred->uid); + if (seteuid(user_cred->uid) != 0) + sudo_fatal("seteuid(%u)", (unsigned int)user_cred->uid); tfd = sudo_edit_open(tf[i].tfile, O_RDONLY, - S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 0, &user_details.cred, NULL); + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, 0, user_cred, NULL); if (seteuid(ROOT_UID) != 0) sudo_fatal("seteuid(ROOT_UID)"); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, "seteuid(%u)", ROOT_UID); - if (tfd == -1 || !sudo_check_temp_file(tfd, tf[i].tfile, user_details.cred.uid, &sb)) { + if (tfd == -1 || !sudo_check_temp_file(tfd, tf[i].tfile, user_cred->uid, &sb)) { sudo_warnx(U_("%s left unmodified"), tf[i].ofile); if (tfd != -1) close(tfd); @@ -312,10 +313,9 @@ sudo_edit_copy_tfiles(struct command_details *command_details, oldmask = umask(command_details->umask); ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details->flags, - &user_details.cred, &command_details->cred); + user_cred, &command_details->cred); umask(oldmask); - switch_user(ROOT_UID, user_details.cred.egid, - user_details.cred.ngroups, user_details.cred.groups); + switch_user(ROOT_UID, user_cred->egid, user_cred->ngroups, user_cred->groups); if (ofd == -1) { sudo_warn(U_("unable to write to %s"), tf[i].ofile); goto bad; @@ -380,28 +380,28 @@ selinux_run_helper(uid_t uid, gid_t gid, int ngroups, GETGROUPS_T *groups, } static char * -selinux_fmt_sudo_user(void) +selinux_fmt_sudo_user(struct sudo_cred *user_cred) { char *cp, *user_str; size_t user_size; int i, len; debug_decl(selinux_fmt_sudo_user, SUDO_DEBUG_EDIT); - user_size = (MAX_UID_T_LEN + 1) * (2 + user_details.cred.ngroups); + user_size = (MAX_UID_T_LEN + 1) * (2 + user_cred->ngroups); if ((user_str = malloc(user_size)) == NULL) debug_return_ptr(NULL); /* UID:GID: */ len = snprintf(user_str, user_size, "%u:%u:", - (unsigned int)user_details.cred.uid, (unsigned int)user_details.cred.gid); + (unsigned int)user_cred->uid, (unsigned int)user_cred->gid); if (len < 0 || (size_t)len >= user_size) sudo_fatalx(U_("internal error, %s overflow"), __func__); /* Supplementary GIDs */ cp = user_str + len; - for (i = 0; i < user_details.cred.ngroups; i++) { + for (i = 0; i < user_cred->ngroups; i++) { len = snprintf(cp, user_size - (cp - user_str), "%s%u", - i ? "," : "", (unsigned int)user_details.cred.groups[i]); + i ? "," : "", (unsigned int)user_cred->groups[i]); if (len < 0 || (size_t)len >= user_size - (cp - user_str)) sudo_fatalx(U_("internal error, %s overflow"), __func__); cp += len; @@ -412,7 +412,8 @@ selinux_fmt_sudo_user(void) static int selinux_edit_create_tfiles(struct command_details *command_details, - struct tempfile *tf, char *files[], int nfiles) + struct sudo_cred *user_cred, struct tempfile *tf, + char *files[], int nfiles) { const char **sesh_args, **sesh_ap; char *user_str = NULL; @@ -434,7 +435,7 @@ selinux_edit_create_tfiles(struct command_details *command_details, if (!ISSET(command_details->flags, CD_SUDOEDIT_FOLLOW)) *sesh_ap++ = "--no-dereference"; if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) { - if ((user_str = selinux_fmt_sudo_user()) == NULL) { + if ((user_str = selinux_fmt_sudo_user(user_cred)) == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto done; } @@ -498,9 +499,9 @@ selinux_edit_create_tfiles(struct command_details *command_details, close(tfd); goto done; } - if (fchown(tfd, user_details.cred.uid, user_details.cred.gid) != 0) { + if (fchown(tfd, user_cred->uid, user_cred->gid) != 0) { sudo_warn("unable to chown(%s) to %d:%d for editing", - tf[i].tfile, user_details.cred.uid, user_details.cred.gid); + tf[i].tfile, user_cred->uid, user_cred->gid); close(tfd); goto done; } @@ -518,7 +519,8 @@ done: static int selinux_edit_copy_tfiles(struct command_details *command_details, - struct tempfile *tf, int nfiles, struct timespec *times) + struct sudo_cred *user_cred, struct tempfile *tf, + int nfiles, struct timespec *times) { const char **sesh_args, **sesh_ap; char *user_str = NULL; @@ -541,7 +543,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, *sesh_ap++ = "sesh"; *sesh_ap++ = "--edit-install"; if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) { - if ((user_str = selinux_fmt_sudo_user()) == NULL) { + if ((user_str = selinux_fmt_sudo_user(user_cred)) == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto done; } @@ -557,7 +559,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, sudo_warn(U_("unable to open %s"), tf[i].tfile); continue; } - if (!sudo_check_temp_file(tfd, tf[i].tfile, user_details.cred.uid, &sb)) + if (!sudo_check_temp_file(tfd, tf[i].tfile, user_cred->uid, &sb)) continue; mtim_get(&sb, ts); if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { @@ -625,7 +627,7 @@ done: * of 1 on failure. */ int -sudo_edit(struct command_details *command_details) +sudo_edit(struct command_details *command_details, struct sudo_cred *user_cred) { struct command_details saved_command_details; char **nargv = NULL, **files = NULL; @@ -648,7 +650,7 @@ sudo_edit(struct command_details *command_details) } /* Find a temporary directory writable by the user. */ - if (!set_tmpdir(&user_details.cred)) + if (!set_tmpdir(user_cred)) goto cleanup; if (nfiles > 0) { @@ -690,10 +692,10 @@ sudo_edit(struct command_details *command_details) } #ifdef HAVE_SELINUX if (ISSET(command_details->flags, CD_RBAC_ENABLED)) - nfiles = selinux_edit_create_tfiles(command_details, tf, files, nfiles); + nfiles = selinux_edit_create_tfiles(command_details, user_cred, tf, files, nfiles); else #endif - nfiles = sudo_edit_create_tfiles(command_details, tf, files, nfiles); + nfiles = sudo_edit_create_tfiles(command_details, user_cred, tf, files, nfiles); if (nfiles <= 0) goto cleanup; @@ -729,9 +731,9 @@ sudo_edit(struct command_details *command_details) selinux_audit_role_change(); #endif memcpy(&saved_command_details, command_details, sizeof(struct command_details)); - command_details->cred = user_details.cred; - command_details->cred.euid = user_details.cred.uid; - command_details->cred.egid = user_details.cred.gid; + command_details->cred = *user_cred; + command_details->cred.euid = user_cred->uid; + command_details->cred.egid = user_cred->gid; command_details->argc = nargc; command_details->argv = nargv; ret = run_command(command_details); @@ -748,10 +750,10 @@ sudo_edit(struct command_details *command_details) /* Copy contents of temp files to real ones. */ #ifdef HAVE_SELINUX if (ISSET(command_details->flags, CD_RBAC_ENABLED)) - errors = selinux_edit_copy_tfiles(command_details, tf, nfiles, times); + errors = selinux_edit_copy_tfiles(command_details, user_cred, tf, nfiles, times); else #endif - errors = sudo_edit_copy_tfiles(command_details, tf, nfiles, times); + errors = sudo_edit_copy_tfiles(command_details, user_cred, tf, nfiles, times); if (errors) { /* Preserve the edited temporary files. */ ret = W_EXITCODE(1, 0); @@ -783,7 +785,7 @@ cleanup: * Must have the ability to change the effective uid to use sudoedit. */ int -sudo_edit(struct command_details *command_details) +sudo_edit(struct command_details *command_details, struct sudo_cred *user_cred) { debug_decl(sudo_edit, SUDO_DEBUG_EDIT); debug_return_int(W_EXITCODE(1, 0)); diff --git a/src/sudo_exec.h b/src/sudo_exec.h index 8bf3c2aad..de6ac45ad 100644 --- a/src/sudo_exec.h +++ b/src/sudo_exec.h @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2010-2017, 2020-2022 Todd C. Miller + * Copyright (c) 2010-2017, 2020-2023 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -42,6 +42,7 @@ # define USER_SIGNALED(_info) ((_info) != NULL && (_info)->si_code <= 0) #endif +struct user_details; struct command_details; struct command_status; struct sudo_event_base; @@ -204,10 +205,10 @@ void del_io_events(bool nonblocking); void init_ttyblock(void); /* exec_nopty.c */ -void exec_nopty(struct command_details *details, struct command_status *cstat); +void exec_nopty(struct command_details *details, struct user_details *user_details, struct command_status *cstat); /* exec_pty.c */ -bool exec_pty(struct command_details *details, struct command_status *cstat); +bool exec_pty(struct command_details *details, struct user_details *user_details, struct command_status *cstat); extern int io_fds[6]; /* exec_monitor.c */ diff --git a/src/tgetpass.c b/src/tgetpass.c index 935afac7c..a16af292c 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -290,7 +290,7 @@ static char * sudo_askpass(const char *askpass, const char *prompt) { static char buf[SUDO_CONV_REPL_MAX + 1], *pass; - struct sudo_cred *cred = &user_details.cred; + struct sudo_cred *cred = sudo_get_user_cred(); sigset_t chldmask; enum tgetpass_errval errval; int pfd[2], status;