* NEWS, src/su.c: When su receives a signal, wait for the child to

terminate (after sending a SIGTERM), and kill it only if it did
	not terminate by itself. No delay will be enforced if the child
	cooperates. See http://bugs.gentoo.org/282094
	* NEWS, man/su.1.xml: Document su's exit values.
This commit is contained in:
nekral-guest 2009-09-08 20:39:15 +00:00
parent da18e77e9a
commit 756700ddf3
4 changed files with 91 additions and 7 deletions

View File

@ -1,3 +1,11 @@
2009-09-08 Nicolas François <nicolas.francois@centraliens.net>
* NEWS, src/su.c: When su receives a signal, wait for the child to
terminate (after sending a SIGTERM), and kill it only if it did
not terminate by itself. No delay will be enforced if the child
cooperates. See http://bugs.gentoo.org/282094
* NEWS, man/su.1.xml: Document su's exit values.
2009-09-08 Nicolas François <nicolas.francois@centraliens.net>
* src/useradd.c: The default value for the CREATE_MAIL_SPOOL

6
NEWS
View File

@ -6,6 +6,12 @@ shadow-4.1.4.2 -> shadow-4.1.4.3 UNRELEASED
* report usage error to stderr, but report usage help to stdout (and return
zero) when explicitly requested (e.g. with --help).
- su
* Document the su exit values.
* When su receives a signal, wait for the child to terminate (after
sending a SIGTERM), and kill it only if it did not terminate by itself.
No delay will be enforced if the child cooperates.
shadow-4.1.4.1 -> shadow-4.1.4.2 2009-07-24
- general

View File

@ -358,6 +358,53 @@
</variablelist>
</refsect1>
<refsect1 id='exit_values'>
<title>EXIT VALUES</title>
<para>
On success, <command>su</command> returns the exit value of the
command it executed.
</para>
<para>
If this command was terminated by a signal, <command>su</command>
returns the number of this signal plus 128.
</para>
<para>
If su has to kill the command (because it was asked to terminate,
and the command did not terminate in time), <command>su</command>
returns 255.
</para>
<para>
Some exit values from <command>su</command> are independent from the
executed command:
<variablelist>
<varlistentry>
<term><replaceable>0</replaceable></term>
<listitem>
<para>success (<option>--help</option> only)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>1</replaceable></term>
<listitem>
<para>System or authentication failure</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>126</replaceable></term>
<listitem>
<para>The requested command was not found</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable>127</replaceable></term>
<listitem>
<para>The requested command could not be executed</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 id='see_also'>
<title>SEE ALSO</title>
<para><citerefentry>

View File

@ -78,6 +78,8 @@
* Global variables
*/
char *Prog;
/* PID of the child, in case it needs to be killed */
static pid_t pid_child = 0;
/* not needed by sulog.c anymore */
static char name[BUFSIZ];
@ -103,11 +105,16 @@ extern size_t newenvc;
/* local function prototypes */
static void execve_shell (const char *shellstr,
char *args[],
char *const envp[]);
static RETSIGTYPE kill_child (int s);
#ifndef USE_PAM
static RETSIGTYPE die (int);
static int iswheel (const char *);
#endif /* !USE_PAM */
#ifndef USE_PAM
/*
* die - set or reset termio modes.
*
@ -126,7 +133,7 @@ static RETSIGTYPE die (int killed)
if (killed) {
closelog ();
exit (killed);
exit (128+killed);
}
}
@ -143,6 +150,18 @@ static int iswheel (const char *username)
}
#endif /* !USE_PAM */
static RETSIGTYPE kill_child (int unused(s))
{
if (0 != pid_child) {
(void) kill (pid_child, SIGKILL);
(void) fputs (_(" ...killed.\n"), stderr);
} else {
(void) fputs (_(" ...waiting for child to terminate.\n"),
stderr);
}
exit (255);
}
/* borrowed from GNU sh-utils' "su.c" */
static bool restricted_shell (const char *shellstr)
{
@ -252,6 +271,7 @@ static void run_shell (const char *shellstr, char *args[], bool doshell,
exit (1);
}
/* parent only */
pid_child = child;
sigfillset (&ourset);
if (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0) {
(void) fprintf (stderr, "%s: signal malfunction\n", Prog);
@ -293,7 +313,9 @@ static void run_shell (const char *shellstr, char *args[], bool doshell,
}
if (caught) {
fprintf (stderr, "\nSession terminated, killing shell...");
(void) fputs ("\n", stderr);
(void) fputs (_("Session terminated, terminating shell..."),
stderr);
kill (child, SIGTERM);
}
@ -309,10 +331,11 @@ static void run_shell (const char *shellstr, char *args[], bool doshell,
ret = pam_end (pamh, PAM_SUCCESS);
if (caught) {
sleep (2);
kill (child, SIGKILL);
fprintf (stderr, " ...killed.\n");
exit (-1);
(void) signal (SIGALRM, kill_child);
(void) alarm (2);
(void) wait (&status);
(void) fputs (_(" ...terminated.\n"), stderr);
}
exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status)