Make user_details private to sudo.c.

This commit is contained in:
Todd C. Miller
2023-03-27 16:19:08 -06:00
parent e435b158b8
commit 5108c279af
9 changed files with 97 additions and 79 deletions

View File

@@ -407,7 +407,8 @@ direct_exec_allowed(struct command_details *details)
* we fact that we have two different controlling terminals to deal with. * we fact that we have two different controlling terminals to deal with.
*/ */
int 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); 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. * is configured, this returns false and we run the command without a pty.
*/ */
if (sudo_needs_pty(details)) { if (sudo_needs_pty(details)) {
if (exec_pty(details, cstat)) if (exec_pty(details, user_details, cstat))
goto done; 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. * 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: done:
/* The caller will run any plugin close functions. */ /* The caller will run any plugin close functions. */

View File

@@ -207,8 +207,9 @@ signal_cb_nopty(int signo, int what, void *v)
* Allocates events for the signal pipe and error pipe. * Allocates events for the signal pipe and error pipe.
*/ */
static void static void
fill_exec_closure(struct exec_closure *ec, fill_exec_closure(struct exec_closure *ec, struct command_status *cstat,
struct command_status *cstat, struct command_details *details, int errfd) struct command_details *details, struct user_details *user_details,
int errfd)
{ {
debug_decl(fill_exec_closure, SUDO_DEBUG_EXEC); debug_decl(fill_exec_closure, SUDO_DEBUG_EXEC);
@@ -217,8 +218,8 @@ fill_exec_closure(struct exec_closure *ec,
ec->ppgrp = getpgrp(); ec->ppgrp = getpgrp();
ec->cstat = cstat; ec->cstat = cstat;
ec->details = details; ec->details = details;
ec->rows = user_details.ts_rows; ec->rows = user_details->ts_rows;
ec->cols = user_details.ts_cols; ec->cols = user_details->ts_cols;
/* Setup event base and events. */ /* Setup event base and events. */
ec->evbase = details->evbase; 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. * Execute a command and wait for it to finish.
*/ */
void 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 io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
int errpipe[2], intercept_sv[2] = { -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 * Fill in exec closure, allocate event base, signal events and
* the error pipe event. * 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)) { if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) {
int rc = 1; int rc = 1;

View File

@@ -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. * Returns the dyamically allocated pty name on success, NULL on failure.
*/ */
static char * static char *
pty_setup(struct command_details *details, const char *tty) pty_setup(struct command_details *details)
{ {
char *ptyname = NULL; char *ptyname = NULL;
debug_decl(pty_setup, SUDO_DEBUG_EXEC); debug_decl(pty_setup, SUDO_DEBUG_EXEC);
@@ -83,12 +83,12 @@ pty_setup(struct command_details *details, const char *tty)
if (ptyname == NULL) if (ptyname == NULL)
sudo_fatal("%s", U_("unable to allocate pty")); 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? */ /* Add entry to utmp/utmpx? */
if (ISSET(details->flags, CD_SET_UTMP)) 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, sudo_debug_printf(SUDO_DEBUG_INFO,
"%s: %s fd %d, pty leader fd %d, pty follower fd %d", "%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 static void
fill_exec_closure(struct exec_closure *ec, struct command_status *cstat, fill_exec_closure(struct exec_closure *ec, struct command_status *cstat,
struct command_details *details, pid_t sudo_pid, pid_t ppgrp, struct command_details *details, struct user_details *user_details,
int backchannel) pid_t sudo_pid, pid_t ppgrp, int backchannel)
{ {
debug_decl(fill_exec_closure, SUDO_DEBUG_EXEC); 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->cmnd_pid = -1;
ec->cstat = cstat; ec->cstat = cstat;
ec->details = details; ec->details = details;
ec->rows = user_details.ts_rows; ec->rows = user_details->ts_rows;
ec->cols = user_details.ts_cols; ec->cols = user_details->ts_cols;
/* Reset cstat for running the command. */ /* Reset cstat for running the command. */
cstat->type = CMD_INVALID; 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. * we fact that we have two different controlling terminals to deal with.
*/ */
bool 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 } }; int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
bool interpose[3] = { false, false, false }; 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. * 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) if (ec.ptyname == NULL)
debug_return_bool(false); 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 * Fill in exec closure, allocate event base, signal events and
* the backchannel event. * 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. */ /* Create event and closure for intercept mode. */
if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) { if (ISSET(details->flags, CD_INTERCEPT|CD_LOG_SUBCMDS)) {

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 1993-1996, 1998-2022 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 1993-1996, 1998-2023 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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). * for the command to be run (if we are running one).
*/ */
int int
parse_args(int argc, char **argv, int *old_optind, int *nargc, char ***nargv, parse_args(int argc, char **argv, const char *shell, int *old_optind,
struct sudo_settings **settingsp, char ***env_addp, const char **list_userp) int *nargc, char ***nargv, struct sudo_settings **settingsp,
char ***env_addp, const char **list_userp)
{ {
const char *progname, *short_opts = sudo_short_opts; const char *progname, *short_opts = sudo_short_opts;
struct option *long_opts = sudo_long_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)) if (!gc_add(GC_PTR, av))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
av[0] = (char *)user_details.shell; /* plugin may override shell */ av[0] = (char *)shell; /* plugin may override shell */
if (cmnd != NULL) { if (cmnd != NULL) {
av[1] = (char *)"-c"; av[1] = (char *)"-c";
av[2] = cmnd; av[2] = cmnd;

View File

@@ -76,7 +76,7 @@ struct plugin_container policy_plugin;
struct plugin_container_list io_plugins = TAILQ_HEAD_INITIALIZER(io_plugins); 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 audit_plugins = TAILQ_HEAD_INITIALIZER(audit_plugins);
struct plugin_container_list approval_plugins = TAILQ_HEAD_INITIALIZER(approval_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; int sudo_debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
static struct sudo_event_base *sudo_event_base; 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. */ /* Parse command line arguments, preserving the original argv/envp. */
submit_argv = argv; submit_argv = argv;
submit_envp = envp; submit_envp = envp;
sudo_mode = parse_args(argc, argv, &submit_optind, &nargc, &nargv, sudo_mode = parse_args(argc, argv, user_details.shell, &submit_optind,
&sudo_settings, &env_add, &list_user); &nargc, &nargv, &sudo_settings, &env_add, &list_user);
sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode 0x%x", sudo_mode); sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode 0x%x", sudo_mode);
/* Print sudo version early, in case of plugin init failure. */ /* 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)) if (ISSET(sudo_mode, MODE_BACKGROUND))
SET(command_details.flags, CD_BACKGROUND); SET(command_details.flags, CD_BACKGROUND);
if (ISSET(command_details.flags, CD_SUDOEDIT)) { if (ISSET(command_details.flags, CD_SUDOEDIT)) {
status = sudo_edit(&command_details); status = sudo_edit(&command_details, &user_details.cred);
} else { } else {
status = run_command(&command_details); status = run_command(&command_details);
} }
@@ -1039,7 +1039,7 @@ run_command(struct command_details *details)
debug_return_int(status); debug_return_int(status);
} }
sudo_execute(details, &cstat); sudo_execute(details, &user_details, &cstat);
switch (cstat.type) { switch (cstat.type) {
case CMD_ERRNO: case CMD_ERRNO:
@@ -2153,6 +2153,16 @@ free_plugin_container(struct plugin_container *plugin, bool ioplugin)
debug_return; 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 bool
gc_add(enum sudo_gc_types type, void *v) gc_add(enum sudo_gc_types type, void *v)
{ {

View File

@@ -245,12 +245,12 @@ char *tgetpass(const char *prompt, int timeout, int flags,
struct sudo_conv_callback *callback); struct sudo_conv_callback *callback);
/* exec.c */ /* 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 */ /* parse_args.c */
int parse_args(int argc, char **argv, int *old_optind, int *nargc, int parse_args(int argc, char **argv, const char *shell, int *old_optind,
char ***nargv, struct sudo_settings **settingsp, char ***env_addp, int *nargc, char ***nargv, struct sudo_settings **settingsp,
const char **list_user); char ***env_addp, const char **list_user);
extern int tgetpass_flags; extern int tgetpass_flags;
/* get_pty.c */ /* 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[]); const char *audit_msg, char * const command_info[]);
bool approval_check(char * const command_info[], char * const run_argv[], bool approval_check(char * const command_info[], char * const run_argv[],
char * const run_envp[]); char * const run_envp[]);
extern struct user_details user_details; struct sudo_cred *sudo_get_user_cred(void);
extern int sudo_debug_instance; extern int sudo_debug_instance;
/* sudo_edit.c */ /* 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 */ /* parse_args.c */
sudo_noreturn void usage(void); sudo_noreturn void usage(void);

View File

@@ -163,7 +163,8 @@ sudo_edit_mktemp(const char *ofile, char **tfile)
*/ */
static int static int
sudo_edit_create_tfiles(struct command_details *command_details, 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; int i, j, tfd, ofd, rc;
struct timespec times[2]; 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); command_details->cred.ngroups, command_details->cred.groups);
ofd = sudo_edit_open(files[i], O_RDONLY, ofd = sudo_edit_open(files[i], O_RDONLY,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details->flags, 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 || errno == ENOENT) {
if (ofd != -1) { if (ofd != -1) {
rc = fstat(ofd, &sb); rc = fstat(ofd, &sb);
} else { } else {
/* New file, verify parent dir exists and is not writable. */ /* New file, verify parent dir exists and is not writable. */
memset(&sb, 0, sizeof(sb)); 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; rc = 0;
} }
} }
switch_user(ROOT_UID, user_details.cred.egid, switch_user(ROOT_UID, user_cred->egid, user_cred->ngroups, user_cred->groups);
user_details.cred.ngroups, user_details.cred.groups);
if (ofd != -1 && !S_ISREG(sb.st_mode)) { if (ofd != -1 && !S_ISREG(sb.st_mode)) {
sudo_warnx(U_("%s: not a regular file"), files[i]); sudo_warnx(U_("%s: not a regular file"), files[i]);
close(ofd); close(ofd);
@@ -217,9 +217,9 @@ sudo_edit_create_tfiles(struct command_details *command_details,
tf[j].osize = sb.st_size; // -V614 tf[j].osize = sb.st_size; // -V614
mtim_get(&sb, tf[j].omtim); mtim_get(&sb, tf[j].omtim);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", (unsigned int)user_details.cred.uid); "seteuid(%u)", (unsigned int)user_cred->uid);
if (seteuid(user_details.cred.uid) != 0) if (seteuid(user_cred->uid) != 0)
sudo_fatal("seteuid(%u)", (unsigned int)user_details.cred.uid); sudo_fatal("seteuid(%u)", (unsigned int)user_cred->uid);
tfd = sudo_edit_mktemp(tf[j].ofile, &tf[j].tfile); tfd = sudo_edit_mktemp(tf[j].ofile, &tf[j].tfile);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", ROOT_UID); "seteuid(%u)", ROOT_UID);
@@ -267,7 +267,8 @@ sudo_edit_create_tfiles(struct command_details *command_details,
*/ */
static int static int
sudo_edit_copy_tfiles(struct command_details *command_details, 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; int i, tfd, ofd, errors = 0;
struct timespec ts; struct timespec ts;
@@ -278,16 +279,16 @@ sudo_edit_copy_tfiles(struct command_details *command_details,
/* Copy contents of temp files to real ones. */ /* Copy contents of temp files to real ones. */
for (i = 0; i < nfiles; i++) { for (i = 0; i < nfiles; i++) {
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", (unsigned int)user_details.cred.uid); "seteuid(%u)", (unsigned int)user_cred->uid);
if (seteuid(user_details.cred.uid) != 0) if (seteuid(user_cred->uid) != 0)
sudo_fatal("seteuid(%u)", (unsigned int)user_details.cred.uid); sudo_fatal("seteuid(%u)", (unsigned int)user_cred->uid);
tfd = sudo_edit_open(tf[i].tfile, O_RDONLY, 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) if (seteuid(ROOT_UID) != 0)
sudo_fatal("seteuid(ROOT_UID)"); sudo_fatal("seteuid(ROOT_UID)");
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", ROOT_UID); "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); sudo_warnx(U_("%s left unmodified"), tf[i].ofile);
if (tfd != -1) if (tfd != -1)
close(tfd); close(tfd);
@@ -312,10 +313,9 @@ sudo_edit_copy_tfiles(struct command_details *command_details,
oldmask = umask(command_details->umask); oldmask = umask(command_details->umask);
ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_CREAT, ofd = sudo_edit_open(tf[i].ofile, O_WRONLY|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details->flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details->flags,
&user_details.cred, &command_details->cred); user_cred, &command_details->cred);
umask(oldmask); umask(oldmask);
switch_user(ROOT_UID, user_details.cred.egid, switch_user(ROOT_UID, user_cred->egid, user_cred->ngroups, user_cred->groups);
user_details.cred.ngroups, user_details.cred.groups);
if (ofd == -1) { if (ofd == -1) {
sudo_warn(U_("unable to write to %s"), tf[i].ofile); sudo_warn(U_("unable to write to %s"), tf[i].ofile);
goto bad; goto bad;
@@ -380,28 +380,28 @@ selinux_run_helper(uid_t uid, gid_t gid, int ngroups, GETGROUPS_T *groups,
} }
static char * static char *
selinux_fmt_sudo_user(void) selinux_fmt_sudo_user(struct sudo_cred *user_cred)
{ {
char *cp, *user_str; char *cp, *user_str;
size_t user_size; size_t user_size;
int i, len; int i, len;
debug_decl(selinux_fmt_sudo_user, SUDO_DEBUG_EDIT); 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) if ((user_str = malloc(user_size)) == NULL)
debug_return_ptr(NULL); debug_return_ptr(NULL);
/* UID:GID: */ /* UID:GID: */
len = snprintf(user_str, user_size, "%u:%u:", 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) if (len < 0 || (size_t)len >= user_size)
sudo_fatalx(U_("internal error, %s overflow"), __func__); sudo_fatalx(U_("internal error, %s overflow"), __func__);
/* Supplementary GIDs */ /* Supplementary GIDs */
cp = user_str + len; 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", 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)) if (len < 0 || (size_t)len >= user_size - (cp - user_str))
sudo_fatalx(U_("internal error, %s overflow"), __func__); sudo_fatalx(U_("internal error, %s overflow"), __func__);
cp += len; cp += len;
@@ -412,7 +412,8 @@ selinux_fmt_sudo_user(void)
static int static int
selinux_edit_create_tfiles(struct command_details *command_details, 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; const char **sesh_args, **sesh_ap;
char *user_str = NULL; 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)) if (!ISSET(command_details->flags, CD_SUDOEDIT_FOLLOW))
*sesh_ap++ = "--no-dereference"; *sesh_ap++ = "--no-dereference";
if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) { 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")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done; goto done;
} }
@@ -498,9 +499,9 @@ selinux_edit_create_tfiles(struct command_details *command_details,
close(tfd); close(tfd);
goto done; 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", 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); close(tfd);
goto done; goto done;
} }
@@ -518,7 +519,8 @@ done:
static int static int
selinux_edit_copy_tfiles(struct command_details *command_details, 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; const char **sesh_args, **sesh_ap;
char *user_str = NULL; char *user_str = NULL;
@@ -541,7 +543,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details,
*sesh_ap++ = "sesh"; *sesh_ap++ = "sesh";
*sesh_ap++ = "--edit-install"; *sesh_ap++ = "--edit-install";
if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) { 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")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done; 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); sudo_warn(U_("unable to open %s"), tf[i].tfile);
continue; 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; continue;
mtim_get(&sb, ts); mtim_get(&sb, ts);
if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
@@ -625,7 +627,7 @@ done:
* of 1 on failure. * of 1 on failure.
*/ */
int 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; struct command_details saved_command_details;
char **nargv = NULL, **files = NULL; char **nargv = NULL, **files = NULL;
@@ -648,7 +650,7 @@ sudo_edit(struct command_details *command_details)
} }
/* Find a temporary directory writable by the user. */ /* Find a temporary directory writable by the user. */
if (!set_tmpdir(&user_details.cred)) if (!set_tmpdir(user_cred))
goto cleanup; goto cleanup;
if (nfiles > 0) { if (nfiles > 0) {
@@ -690,10 +692,10 @@ sudo_edit(struct command_details *command_details)
} }
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (ISSET(command_details->flags, CD_RBAC_ENABLED)) 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 else
#endif #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) if (nfiles <= 0)
goto cleanup; goto cleanup;
@@ -729,9 +731,9 @@ sudo_edit(struct command_details *command_details)
selinux_audit_role_change(); selinux_audit_role_change();
#endif #endif
memcpy(&saved_command_details, command_details, sizeof(struct command_details)); memcpy(&saved_command_details, command_details, sizeof(struct command_details));
command_details->cred = user_details.cred; command_details->cred = *user_cred;
command_details->cred.euid = user_details.cred.uid; command_details->cred.euid = user_cred->uid;
command_details->cred.egid = user_details.cred.gid; command_details->cred.egid = user_cred->gid;
command_details->argc = nargc; command_details->argc = nargc;
command_details->argv = nargv; command_details->argv = nargv;
ret = run_command(command_details); ret = run_command(command_details);
@@ -748,10 +750,10 @@ sudo_edit(struct command_details *command_details)
/* Copy contents of temp files to real ones. */ /* Copy contents of temp files to real ones. */
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
if (ISSET(command_details->flags, CD_RBAC_ENABLED)) 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 else
#endif #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) { if (errors) {
/* Preserve the edited temporary files. */ /* Preserve the edited temporary files. */
ret = W_EXITCODE(1, 0); ret = W_EXITCODE(1, 0);
@@ -783,7 +785,7 @@ cleanup:
* Must have the ability to change the effective uid to use sudoedit. * Must have the ability to change the effective uid to use sudoedit.
*/ */
int 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_decl(sudo_edit, SUDO_DEBUG_EDIT);
debug_return_int(W_EXITCODE(1, 0)); debug_return_int(W_EXITCODE(1, 0));

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2010-2017, 2020-2022 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2010-2017, 2020-2023 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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) # define USER_SIGNALED(_info) ((_info) != NULL && (_info)->si_code <= 0)
#endif #endif
struct user_details;
struct command_details; struct command_details;
struct command_status; struct command_status;
struct sudo_event_base; struct sudo_event_base;
@@ -204,10 +205,10 @@ void del_io_events(bool nonblocking);
void init_ttyblock(void); void init_ttyblock(void);
/* exec_nopty.c */ /* 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 */ /* 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]; extern int io_fds[6];
/* exec_monitor.c */ /* exec_monitor.c */

View File

@@ -290,7 +290,7 @@ static char *
sudo_askpass(const char *askpass, const char *prompt) sudo_askpass(const char *askpass, const char *prompt)
{ {
static char buf[SUDO_CONV_REPL_MAX + 1], *pass; 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; sigset_t chldmask;
enum tgetpass_errval errval; enum tgetpass_errval errval;
int pfd[2], status; int pfd[2], status;