* 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:
parent
da18e77e9a
commit
756700ddf3
@ -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
6
NEWS
@ -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
|
||||
|
47
man/su.1.xml
47
man/su.1.xml
@ -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>
|
||||
|
37
src/su.c
37
src/su.c
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user