If sudo is not the process group leader we must only send the suspend
signal to sudo itself. When sudo is run via a shell script, it
usually has the same process group as the shell script interpreter.
We do not want to suspend the script itself when the command run
by sudo is suspended.
If we are logging I/O but not terminal input/output (either because
no terminal is present or because that is what the plugin requested),
the non-pty exec path is now taken.
This will be shared with exec_nopty.c in the future to log
stdin/stdout/stderr without running the command in a pty.
Both exec_pty.c and exec_nopty.c now use the same closure.
When ptracing a process, we receive the signal-delivery-stop signal
before the group-stop signal. If sudo is running the command in
the same terminal, we need to wait until the stop signal is actually
delivered to the command before we can suspend sudo itself. If we
suspend sudo before receiving the group-stop, the command will be
restarted with PTRACE_LISTEN too late and will miss the SIGCONT
from sudo.
This allows intercept mode to work with shells that close all open
fds upon startup. The ctor in sudo_intercept.so requests the port
number and secret over the socket inherited from the parent then
closes it. For each policy request, a TCP connection is made to
the sudo parent process to perform the policy check. Child processes
re-use the TCP socket to request the port number and secret just like
the initial process started by sudo does.
The goal is to make it harder for someone to have a fake policy checker.
This will not stop a determined adversary since the secret is present
in the address space of the running process.
This should only be set for signals that terminate the process.
Fixes a bug where the sudo front-end could call the plugin close
function with a non-terminal signal argument.
This fixes an issue on Solaris 11.4 (and probably others) with "sudo
reboot" when I/O logging is enabled. Previously, sudo would kill
the command if it was still running after the event loop terminated,
leaving the system in a half-dead state.
Fixes a problem on Solaris 11.4 (and possibly others) where sudo
continually tries to put itself in the background after the user's
terminal has been revoked.
We currently have no good way to distinguish between an error
executing the command and an error while the command is running.
In the future, we should have additional status codes so we
can tell what type of condition caused the loop to exit.
For now, only kill the command if cstat is left uninitialized.
This can be used to implement logging-only plugins.
The plugin functions now take an errstr argument that can be used
to return an error string to be logged on failure or error.
1) don't assume snprintf() returns -1 on error, check for <0
2) when comparing return value of sizeof(foo), cast the sizeof, not the len
3) cast return value to void in cases where snprintf cannot fail