Replace master/slave in code with leader/follower.
This commit is contained in:
@@ -97,21 +97,21 @@ deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
|
|||||||
break;
|
break;
|
||||||
case SIGCONT_FG:
|
case SIGCONT_FG:
|
||||||
/* Continue in foreground, grant it controlling tty. */
|
/* Continue in foreground, grant it controlling tty. */
|
||||||
if (tcsetpgrp(io_fds[SFD_SLAVE], mc->cmnd_pgrp) == -1) {
|
if (tcsetpgrp(io_fds[SFD_FOLLOWER], mc->cmnd_pgrp) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to set foreground pgrp to %d (command)",
|
"%s: unable to set foreground pgrp to %d (command)",
|
||||||
__func__, (int)mc->cmnd_pgrp);
|
__func__, (int)mc->cmnd_pgrp);
|
||||||
}
|
}
|
||||||
/* Lazily initialize the pty if needed. */
|
/* Lazily initialize the pty if needed. */
|
||||||
if (!tty_initialized) {
|
if (!tty_initialized) {
|
||||||
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE]))
|
if (sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_FOLLOWER]))
|
||||||
tty_initialized = true;
|
tty_initialized = true;
|
||||||
}
|
}
|
||||||
killpg(mc->cmnd_pid, SIGCONT);
|
killpg(mc->cmnd_pid, SIGCONT);
|
||||||
break;
|
break;
|
||||||
case SIGCONT_BG:
|
case SIGCONT_BG:
|
||||||
/* Continue in background, I take controlling tty. */
|
/* Continue in background, I take controlling tty. */
|
||||||
if (tcsetpgrp(io_fds[SFD_SLAVE], mc->mon_pgrp) == -1) {
|
if (tcsetpgrp(io_fds[SFD_FOLLOWER], mc->mon_pgrp) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to set foreground pgrp to %d (monitor)",
|
"%s: unable to set foreground pgrp to %d (monitor)",
|
||||||
__func__, (int)mc->mon_pgrp);
|
__func__, (int)mc->mon_pgrp);
|
||||||
@@ -131,7 +131,7 @@ deliver_signal(struct monitor_closure *mc, int signo, bool from_parent)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpack rows and cols from a CMD_TTYWINCH value, set the new window
|
* Unpack rows and cols from a CMD_TTYWINCH value, set the new window
|
||||||
* size on the pty slave and inform the command of the change.
|
* size on the pty follower and inform the command of the change.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
handle_winch(struct monitor_closure *mc, unsigned int wsize_packed)
|
handle_winch(struct monitor_closure *mc, unsigned int wsize_packed)
|
||||||
@@ -143,14 +143,14 @@ handle_winch(struct monitor_closure *mc, unsigned int wsize_packed)
|
|||||||
wsize.ws_row = wsize_packed & 0xffff;
|
wsize.ws_row = wsize_packed & 0xffff;
|
||||||
wsize.ws_col = (wsize_packed >> 16) & 0xffff;
|
wsize.ws_col = (wsize_packed >> 16) & 0xffff;
|
||||||
|
|
||||||
if (ioctl(io_fds[SFD_SLAVE], TIOCGWINSZ, &owsize) == 0 &&
|
if (ioctl(io_fds[SFD_FOLLOWER], TIOCGWINSZ, &owsize) == 0 &&
|
||||||
(wsize.ws_row != owsize.ws_row || wsize.ws_col != owsize.ws_col)) {
|
(wsize.ws_row != owsize.ws_row || wsize.ws_col != owsize.ws_col)) {
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"window size change %dx%d -> %dx%d",
|
"window size change %dx%d -> %dx%d",
|
||||||
owsize.ws_col, owsize.ws_row, wsize.ws_col, wsize.ws_row);
|
owsize.ws_col, owsize.ws_row, wsize.ws_col, wsize.ws_row);
|
||||||
|
|
||||||
(void)ioctl(io_fds[SFD_SLAVE], TIOCSWINSZ, &wsize);
|
(void)ioctl(io_fds[SFD_FOLLOWER], TIOCSWINSZ, &wsize);
|
||||||
deliver_signal(mc, SIGWINCH, true);
|
deliver_signal(mc, SIGWINCH, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ mon_handle_sigchld(struct monitor_closure *mc)
|
|||||||
mc->cstat->val = status;
|
mc->cstat->val = status;
|
||||||
if (WIFSTOPPED(status)) {
|
if (WIFSTOPPED(status)) {
|
||||||
/* Save the foreground pgid so we can restore it later. */
|
/* Save the foreground pgid so we can restore it later. */
|
||||||
pid = tcgetpgrp(io_fds[SFD_SLAVE]);
|
pid = tcgetpgrp(io_fds[SFD_FOLLOWER]);
|
||||||
if (pid != mc->mon_pgrp)
|
if (pid != mc->mon_pgrp)
|
||||||
mc->cmnd_pgrp = pid;
|
mc->cmnd_pgrp = pid;
|
||||||
send_status(mc->backchannel, mc->cstat);
|
send_status(mc->backchannel, mc->cstat);
|
||||||
@@ -400,15 +400,15 @@ exec_cmnd_pty(struct command_details *details, bool foreground, int errfd)
|
|||||||
/* Wire up standard fds, note that stdout/stderr may be pipes. */
|
/* Wire up standard fds, note that stdout/stderr may be pipes. */
|
||||||
if (dup3(io_fds[SFD_STDIN], STDIN_FILENO, 0) == -1)
|
if (dup3(io_fds[SFD_STDIN], STDIN_FILENO, 0) == -1)
|
||||||
sudo_fatal("dup3");
|
sudo_fatal("dup3");
|
||||||
if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDIN] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDIN]);
|
close(io_fds[SFD_STDIN]);
|
||||||
if (dup3(io_fds[SFD_STDOUT], STDOUT_FILENO, 0) == -1)
|
if (dup3(io_fds[SFD_STDOUT], STDOUT_FILENO, 0) == -1)
|
||||||
sudo_fatal("dup3");
|
sudo_fatal("dup3");
|
||||||
if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDOUT] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDOUT]);
|
close(io_fds[SFD_STDOUT]);
|
||||||
if (dup3(io_fds[SFD_STDERR], STDERR_FILENO, 0) == -1)
|
if (dup3(io_fds[SFD_STDERR], STDERR_FILENO, 0) == -1)
|
||||||
sudo_fatal("dup3");
|
sudo_fatal("dup3");
|
||||||
if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDERR] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDERR]);
|
close(io_fds[SFD_STDERR]);
|
||||||
|
|
||||||
/* Wait for parent to grant us the tty if we are foreground. */
|
/* Wait for parent to grant us the tty if we are foreground. */
|
||||||
@@ -416,15 +416,15 @@ exec_cmnd_pty(struct command_details *details, bool foreground, int errfd)
|
|||||||
struct timespec ts = { 0, 1000 }; /* 1us */
|
struct timespec ts = { 0, 1000 }; /* 1us */
|
||||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: waiting for controlling tty",
|
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: waiting for controlling tty",
|
||||||
__func__);
|
__func__);
|
||||||
while (tcgetpgrp(io_fds[SFD_SLAVE]) != self)
|
while (tcgetpgrp(io_fds[SFD_FOLLOWER]) != self)
|
||||||
nanosleep(&ts, NULL);
|
nanosleep(&ts, NULL);
|
||||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: got controlling tty",
|
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: got controlling tty",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Done with the pty slave, don't leak it. */
|
/* Done with the pty follower, don't leak it. */
|
||||||
if (io_fds[SFD_SLAVE] != -1)
|
if (io_fds[SFD_FOLLOWER] != -1)
|
||||||
close(io_fds[SFD_SLAVE]);
|
close(io_fds[SFD_FOLLOWER]);
|
||||||
|
|
||||||
/* Execute command; only returns on error. */
|
/* Execute command; only returns on error. */
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "executing %s in the %s",
|
sudo_debug_printf(SUDO_DEBUG_INFO, "executing %s in the %s",
|
||||||
@@ -551,9 +551,9 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|||||||
int errpipe[2];
|
int errpipe[2];
|
||||||
debug_decl(exec_monitor, SUDO_DEBUG_EXEC);
|
debug_decl(exec_monitor, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
/* The pty master is not used by the monitor. */
|
/* The pty leader is not used by the monitor. */
|
||||||
if (io_fds[SFD_MASTER] != -1)
|
if (io_fds[SFD_LEADER] != -1)
|
||||||
close(io_fds[SFD_MASTER]);
|
close(io_fds[SFD_LEADER]);
|
||||||
|
|
||||||
/* Ignore any SIGTTIN or SIGTTOU we receive (shouldn't be possible). */
|
/* Ignore any SIGTTIN or SIGTTOU we receive (shouldn't be possible). */
|
||||||
memset(&sa, 0, sizeof(sa));
|
memset(&sa, 0, sizeof(sa));
|
||||||
@@ -571,7 +571,7 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Start a new session with the parent as the session leader
|
* Start a new session with the parent as the session leader
|
||||||
* and the slave pty as the controlling terminal.
|
* and the follower device as the controlling terminal.
|
||||||
* This allows us to be notified when the command has been suspended.
|
* This allows us to be notified when the command has been suspended.
|
||||||
*/
|
*/
|
||||||
if (setsid() == -1) {
|
if (setsid() == -1) {
|
||||||
@@ -601,7 +601,7 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|||||||
#ifdef HAVE_SELINUX
|
#ifdef HAVE_SELINUX
|
||||||
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
||||||
if (selinux_setup(details->selinux_role, details->selinux_type,
|
if (selinux_setup(details->selinux_role, details->selinux_type,
|
||||||
details->tty, io_fds[SFD_SLAVE], true) == -1)
|
details->tty, io_fds[SFD_FOLLOWER], true) == -1)
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -655,20 +655,20 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|||||||
sigprocmask(SIG_SETMASK, oset, NULL);
|
sigprocmask(SIG_SETMASK, oset, NULL);
|
||||||
|
|
||||||
/* If any of stdin/stdout/stderr are pipes, close them in parent. */
|
/* If any of stdin/stdout/stderr are pipes, close them in parent. */
|
||||||
if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDIN] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDIN]);
|
close(io_fds[SFD_STDIN]);
|
||||||
if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDOUT] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDOUT]);
|
close(io_fds[SFD_STDOUT]);
|
||||||
if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
if (io_fds[SFD_STDERR] != io_fds[SFD_FOLLOWER])
|
||||||
close(io_fds[SFD_STDERR]);
|
close(io_fds[SFD_STDERR]);
|
||||||
|
|
||||||
/* Put command in its own process group. */
|
/* Put command in its own process group. */
|
||||||
mc.cmnd_pgrp = mc.cmnd_pid;
|
mc.cmnd_pgrp = mc.cmnd_pid;
|
||||||
setpgid(mc.cmnd_pid, mc.cmnd_pgrp);
|
setpgid(mc.cmnd_pid, mc.cmnd_pgrp);
|
||||||
|
|
||||||
/* Make the command the foreground process for the pty slave. */
|
/* Make the command the foreground process for the pty follower. */
|
||||||
if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
|
if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
|
||||||
if (tcsetpgrp(io_fds[SFD_SLAVE], mc.cmnd_pgrp) == -1) {
|
if (tcsetpgrp(io_fds[SFD_FOLLOWER], mc.cmnd_pgrp) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to set foreground pgrp to %d (command)",
|
"%s: unable to set foreground pgrp to %d (command)",
|
||||||
__func__, (int)mc.cmnd_pgrp);
|
__func__, (int)mc.cmnd_pgrp);
|
||||||
@@ -700,7 +700,7 @@ exec_monitor(struct command_details *details, sigset_t *oset,
|
|||||||
* Take the controlling tty. This prevents processes spawned by the
|
* Take the controlling tty. This prevents processes spawned by the
|
||||||
* command from receiving SIGHUP when the session leader (us) exits.
|
* command from receiving SIGHUP when the session leader (us) exits.
|
||||||
*/
|
*/
|
||||||
if (tcsetpgrp(io_fds[SFD_SLAVE], mc.mon_pgrp) == -1) {
|
if (tcsetpgrp(io_fds[SFD_FOLLOWER], mc.mon_pgrp) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to set foreground pgrp to %d (monitor)",
|
"%s: unable to set foreground pgrp to %d (monitor)",
|
||||||
__func__, (int)mc.mon_pgrp);
|
__func__, (int)mc.mon_pgrp);
|
||||||
|
@@ -132,7 +132,7 @@ pty_cleanup(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a pty if /dev/tty is a tty.
|
* Allocate a pty if /dev/tty is a tty.
|
||||||
* Fills in io_fds[SFD_USERTTY], io_fds[SFD_MASTER], io_fds[SFD_SLAVE]
|
* Fills in io_fds[SFD_USERTTY], io_fds[SFD_LEADER], io_fds[SFD_FOLLOWER]
|
||||||
* and ptyname globals.
|
* and ptyname globals.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
@@ -147,7 +147,7 @@ pty_setup(struct command_details *details, const char *tty)
|
|||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_pty(&io_fds[SFD_MASTER], &io_fds[SFD_SLAVE],
|
if (!get_pty(&io_fds[SFD_LEADER], &io_fds[SFD_FOLLOWER],
|
||||||
ptyname, sizeof(ptyname), details->euid))
|
ptyname, sizeof(ptyname), details->euid))
|
||||||
sudo_fatal(U_("unable to allocate pty"));
|
sudo_fatal(U_("unable to allocate pty"));
|
||||||
|
|
||||||
@@ -158,30 +158,30 @@ pty_setup(struct command_details *details, const char *tty)
|
|||||||
if (ISSET(details->flags, CD_SET_UTMP)) {
|
if (ISSET(details->flags, CD_SET_UTMP)) {
|
||||||
utmp_user =
|
utmp_user =
|
||||||
details->utmp_user ? details->utmp_user : user_details.username;
|
details->utmp_user ? details->utmp_user : user_details.username;
|
||||||
utmp_login(tty, ptyname, io_fds[SFD_SLAVE], utmp_user);
|
utmp_login(tty, ptyname, io_fds[SFD_FOLLOWER], utmp_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"%s: %s fd %d, pty master fd %d, pty slave fd %d",
|
"%s: %s fd %d, pty leader fd %d, pty follower fd %d",
|
||||||
__func__, _PATH_TTY, io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
|
__func__, _PATH_TTY, io_fds[SFD_USERTTY], io_fds[SFD_LEADER],
|
||||||
io_fds[SFD_SLAVE]);
|
io_fds[SFD_FOLLOWER]);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the tty slave the controlling tty.
|
* Make the tty follower the controlling tty.
|
||||||
* This is only used by the monitor but ptyname[] is static.
|
* This is only used by the monitor but ptyname[] is static.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pty_make_controlling(void)
|
pty_make_controlling(void)
|
||||||
{
|
{
|
||||||
if (io_fds[SFD_SLAVE] != -1) {
|
if (io_fds[SFD_FOLLOWER] != -1) {
|
||||||
#ifdef TIOCSCTTY
|
#ifdef TIOCSCTTY
|
||||||
if (ioctl(io_fds[SFD_SLAVE], TIOCSCTTY, NULL) != 0)
|
if (ioctl(io_fds[SFD_FOLLOWER], TIOCSCTTY, NULL) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
/* Set controlling tty by reopening pty slave. */
|
/* Set controlling tty by reopening pty follower. */
|
||||||
int fd = open(ptyname, O_RDWR);
|
int fd = open(ptyname, O_RDWR);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -840,7 +840,7 @@ io_buf_new(int rfd, int wfd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We already closed the slave pty so reads from the master will not block.
|
* We already closed the follower so reads from the leader will not block.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
pty_finish(struct command_status *cstat)
|
pty_finish(struct command_status *cstat)
|
||||||
@@ -1424,19 +1424,19 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
* In background mode there is no stdin.
|
* In background mode there is no stdin.
|
||||||
*/
|
*/
|
||||||
if (!ISSET(details->flags, CD_BACKGROUND))
|
if (!ISSET(details->flags, CD_BACKGROUND))
|
||||||
io_fds[SFD_STDIN] = io_fds[SFD_SLAVE];
|
io_fds[SFD_STDIN] = io_fds[SFD_FOLLOWER];
|
||||||
io_fds[SFD_STDOUT] = io_fds[SFD_SLAVE];
|
io_fds[SFD_STDOUT] = io_fds[SFD_FOLLOWER];
|
||||||
io_fds[SFD_STDERR] = io_fds[SFD_SLAVE];
|
io_fds[SFD_STDERR] = io_fds[SFD_FOLLOWER];
|
||||||
|
|
||||||
if (io_fds[SFD_USERTTY] != -1) {
|
if (io_fds[SFD_USERTTY] != -1) {
|
||||||
/* Read from /dev/tty, write to pty master */
|
/* Read from /dev/tty, write to pty leader */
|
||||||
if (!ISSET(details->flags, CD_BACKGROUND)) {
|
if (!ISSET(details->flags, CD_BACKGROUND)) {
|
||||||
io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_MASTER],
|
io_buf_new(io_fds[SFD_USERTTY], io_fds[SFD_LEADER],
|
||||||
log_ttyin, &ec, &iobufs);
|
log_ttyin, &ec, &iobufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read from pty master, write to /dev/tty */
|
/* Read from pty leader, write to /dev/tty */
|
||||||
io_buf_new(io_fds[SFD_MASTER], io_fds[SFD_USERTTY],
|
io_buf_new(io_fds[SFD_LEADER], io_fds[SFD_USERTTY],
|
||||||
log_ttyout, &ec, &iobufs);
|
log_ttyout, &ec, &iobufs);
|
||||||
|
|
||||||
/* Are we the foreground process? */
|
/* Are we the foreground process? */
|
||||||
@@ -1511,8 +1511,8 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
/* Copy terminal attrs from user tty -> pty slave. */
|
/* Copy terminal attrs from user tty -> pty follower. */
|
||||||
if (!sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_SLAVE])) {
|
if (!sudo_term_copy(io_fds[SFD_USERTTY], io_fds[SFD_FOLLOWER])) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO,
|
||||||
"%s: unable to copy terminal settings to pty", __func__);
|
"%s: unable to copy terminal settings to pty", __func__);
|
||||||
foreground = false;
|
foreground = false;
|
||||||
@@ -1570,16 +1570,16 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We close the pty slave so only the monitor and command have a
|
* We close the pty follower so only the monitor and command have a
|
||||||
* reference to it. This ensures that we can don't block reading
|
* reference to it. This ensures that we can don't block reading
|
||||||
* from the master when the command and monitor have exited.
|
* from the leader when the command and monitor have exited.
|
||||||
*/
|
*/
|
||||||
if (io_fds[SFD_SLAVE] != -1) {
|
if (io_fds[SFD_FOLLOWER] != -1) {
|
||||||
close(io_fds[SFD_SLAVE]);
|
close(io_fds[SFD_FOLLOWER]);
|
||||||
io_fds[SFD_SLAVE] = -1;
|
io_fds[SFD_FOLLOWER] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the monitor to continue now that the slave is closed. */
|
/* Tell the monitor to continue now that the follower is closed. */
|
||||||
cstat->type = CMD_SIGNO;
|
cstat->type = CMD_SIGNO;
|
||||||
cstat->val = 0;
|
cstat->val = 0;
|
||||||
while (send(sv[0], cstat, sizeof(*cstat), 0) == -1) {
|
while (send(sv[0], cstat, sizeof(*cstat), 0) == -1) {
|
||||||
@@ -1622,8 +1622,8 @@ exec_pty(struct command_details *details, struct command_status *cstat)
|
|||||||
setlocale(LC_ALL, "C");
|
setlocale(LC_ALL, "C");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In the event loop we pass input from user tty to master
|
* In the event loop we pass input from user tty to leader
|
||||||
* and pass output from master to stdout and IO plugin.
|
* and pass output from leader to stdout and IO plugin.
|
||||||
* Try to recover on ENXIO, it means the tty was revoked.
|
* Try to recover on ENXIO, it means the tty was revoked.
|
||||||
*/
|
*/
|
||||||
add_io_events(ec.evbase);
|
add_io_events(ec.evbase);
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
#if defined(HAVE_OPENPTY)
|
#if defined(HAVE_OPENPTY)
|
||||||
bool
|
bool
|
||||||
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t ttyuid)
|
||||||
{
|
{
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
gid_t ttygid = -1;
|
gid_t ttygid = -1;
|
||||||
@@ -62,7 +62,7 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
|||||||
if ((gr = getgrnam("tty")) != NULL)
|
if ((gr = getgrnam("tty")) != NULL)
|
||||||
ttygid = gr->gr_gid;
|
ttygid = gr->gr_gid;
|
||||||
|
|
||||||
if (openpty(master, slave, name, NULL, NULL) == 0) {
|
if (openpty(leader, follower, name, NULL, NULL) == 0) {
|
||||||
if (chown(name, ttyuid, ttygid) == 0)
|
if (chown(name, ttyuid, ttygid) == 0)
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
@@ -72,23 +72,23 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
|||||||
|
|
||||||
#elif defined(HAVE__GETPTY)
|
#elif defined(HAVE__GETPTY)
|
||||||
bool
|
bool
|
||||||
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t ttyuid)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
debug_decl(get_pty, SUDO_DEBUG_PTY);
|
debug_decl(get_pty, SUDO_DEBUG_PTY);
|
||||||
|
|
||||||
/* IRIX-style dynamic ptys (may fork) */
|
/* IRIX-style dynamic ptys (may fork) */
|
||||||
line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
|
line = _getpty(leader, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
|
||||||
if (line != NULL) {
|
if (line != NULL) {
|
||||||
*slave = open(line, O_RDWR|O_NOCTTY, 0);
|
*follower = open(line, O_RDWR|O_NOCTTY, 0);
|
||||||
if (*slave != -1) {
|
if (*follower != -1) {
|
||||||
(void) chown(line, ttyuid, -1);
|
(void) chown(line, ttyuid, -1);
|
||||||
strlcpy(name, line, namesz);
|
strlcpy(name, line, namesz);
|
||||||
ret = true;
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
close(*master);
|
close(*leader);
|
||||||
*master = -1;
|
*leader = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
@@ -110,32 +110,32 @@ posix_openpt(int oflag)
|
|||||||
# endif /* HAVE_POSIX_OPENPT */
|
# endif /* HAVE_POSIX_OPENPT */
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t ttyuid)
|
||||||
{
|
{
|
||||||
char *line;
|
char *line;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
debug_decl(get_pty, SUDO_DEBUG_PTY);
|
debug_decl(get_pty, SUDO_DEBUG_PTY);
|
||||||
|
|
||||||
*master = posix_openpt(O_RDWR|O_NOCTTY);
|
*leader = posix_openpt(O_RDWR|O_NOCTTY);
|
||||||
if (*master != -1) {
|
if (*leader != -1) {
|
||||||
(void) grantpt(*master); /* may fork */
|
(void) grantpt(*leader); /* may fork */
|
||||||
if (unlockpt(*master) != 0) {
|
if (unlockpt(*leader) != 0) {
|
||||||
close(*master);
|
close(*leader);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
line = ptsname(*master);
|
line = ptsname(*leader);
|
||||||
if (line == NULL) {
|
if (line == NULL) {
|
||||||
close(*master);
|
close(*leader);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
*slave = open(line, O_RDWR|O_NOCTTY, 0);
|
*follower = open(line, O_RDWR|O_NOCTTY, 0);
|
||||||
if (*slave == -1) {
|
if (*follower == -1) {
|
||||||
close(*master);
|
close(*leader);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
# if defined(I_PUSH) && !defined(_AIX)
|
# if defined(I_PUSH) && !defined(_AIX)
|
||||||
ioctl(*slave, I_PUSH, "ptem"); /* pseudo tty emulation module */
|
ioctl(*follower, I_PUSH, "ptem"); /* pseudo tty emulation module */
|
||||||
ioctl(*slave, I_PUSH, "ldterm"); /* line discipline module */
|
ioctl(*follower, I_PUSH, "ldterm"); /* line discipline module */
|
||||||
# endif
|
# endif
|
||||||
(void) chown(line, ttyuid, -1);
|
(void) chown(line, ttyuid, -1);
|
||||||
strlcpy(name, line, namesz);
|
strlcpy(name, line, namesz);
|
||||||
@@ -150,7 +150,7 @@ done:
|
|||||||
static char line[] = _PATH_DEV "ptyXX";
|
static char line[] = _PATH_DEV "ptyXX";
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t ttyuid)
|
||||||
{
|
{
|
||||||
char *bank, *cp;
|
char *bank, *cp;
|
||||||
struct group *gr;
|
struct group *gr;
|
||||||
@@ -165,8 +165,8 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
|||||||
line[sizeof(_PATH_DEV "ptyX") - 2] = *bank;
|
line[sizeof(_PATH_DEV "ptyX") - 2] = *bank;
|
||||||
for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
|
for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
|
||||||
line[sizeof(_PATH_DEV "ptyXX") - 2] = *cp;
|
line[sizeof(_PATH_DEV "ptyXX") - 2] = *cp;
|
||||||
*master = open(line, O_RDWR|O_NOCTTY, 0);
|
*leader = open(line, O_RDWR|O_NOCTTY, 0);
|
||||||
if (*master == -1) {
|
if (*leader == -1) {
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
goto done; /* out of ptys */
|
goto done; /* out of ptys */
|
||||||
continue; /* already in use */
|
continue; /* already in use */
|
||||||
@@ -177,13 +177,13 @@ get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
|
|||||||
# ifdef HAVE_REVOKE
|
# ifdef HAVE_REVOKE
|
||||||
(void) revoke(line);
|
(void) revoke(line);
|
||||||
# endif
|
# endif
|
||||||
*slave = open(line, O_RDWR|O_NOCTTY, 0);
|
*follower = open(line, O_RDWR|O_NOCTTY, 0);
|
||||||
if (*slave != -1) {
|
if (*follower != -1) {
|
||||||
strlcpy(name, line, namesz);
|
strlcpy(name, line, namesz);
|
||||||
ret = true; /* success */
|
ret = true; /* success */
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
(void) close(*master);
|
(void) close(*leader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
@@ -213,7 +213,7 @@ int parse_args(int argc, char **argv, int *old_optind, int *nargc,
|
|||||||
extern int tgetpass_flags;
|
extern int tgetpass_flags;
|
||||||
|
|
||||||
/* get_pty.c */
|
/* get_pty.c */
|
||||||
bool get_pty(int *master, int *slave, char *name, size_t namesz, uid_t uid);
|
bool get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t uid);
|
||||||
|
|
||||||
/* sudo.c */
|
/* sudo.c */
|
||||||
int policy_init_session(struct command_details *details);
|
int policy_init_session(struct command_details *details);
|
||||||
|
@@ -41,8 +41,8 @@
|
|||||||
#define SFD_STDIN 0
|
#define SFD_STDIN 0
|
||||||
#define SFD_STDOUT 1
|
#define SFD_STDOUT 1
|
||||||
#define SFD_STDERR 2
|
#define SFD_STDERR 2
|
||||||
#define SFD_MASTER 3
|
#define SFD_LEADER 3
|
||||||
#define SFD_SLAVE 4
|
#define SFD_FOLLOWER 4
|
||||||
#define SFD_USERTTY 5
|
#define SFD_USERTTY 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user