* src/su.c: Also drop the controlling terminal when PAM is not
used. * src/su.c: Remove run_shell().
This commit is contained in:
parent
e9045e9f55
commit
1340beed16
@ -5,6 +5,9 @@
|
|||||||
prepare_pam_close_session() is now executed before the creation of
|
prepare_pam_close_session() is now executed before the creation of
|
||||||
the pam session and before the UID is changed. This allows to
|
the pam session and before the UID is changed. This allows to
|
||||||
close the session as root.
|
close the session as root.
|
||||||
|
* src/su.c: Also drop the controlling terminal when PAM is not
|
||||||
|
used.
|
||||||
|
* src/su.c: Remove run_shell().
|
||||||
|
|
||||||
2011-06-12 Nicolas François <nicolas.francois@centraliens.net>
|
2011-06-12 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
99
src/su.c
99
src/su.c
@ -61,6 +61,13 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifndef USE_PAM
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#endif /* !USE_PAM */
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "pwauth.h"
|
#include "pwauth.h"
|
||||||
@ -119,6 +126,7 @@ static void execve_shell (const char *shellstr,
|
|||||||
char *const envp[]);
|
char *const envp[]);
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
static RETSIGTYPE kill_child (int unused(s));
|
static RETSIGTYPE kill_child (int unused(s));
|
||||||
|
static void prepare_pam_close_session (void);
|
||||||
#else /* !USE_PAM */
|
#else /* !USE_PAM */
|
||||||
static RETSIGTYPE die (int);
|
static RETSIGTYPE die (int);
|
||||||
static bool iswheel (const char *);
|
static bool iswheel (const char *);
|
||||||
@ -258,9 +266,10 @@ static void catch_signals (int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a session and fork.
|
* prepare_pam_close_session - Fork and wait for the child to close the session
|
||||||
* Only the child returns. The parent will wait for the child to terminate
|
*
|
||||||
* and exit.
|
* Only the child returns. The parent will wait for the child to
|
||||||
|
* terminate and exit.
|
||||||
*/
|
*/
|
||||||
static void prepare_pam_close_session (void)
|
static void prepare_pam_close_session (void)
|
||||||
{
|
{
|
||||||
@ -385,30 +394,6 @@ static void prepare_pam_close_session (void)
|
|||||||
: WTERMSIG (status) + 128);
|
: WTERMSIG (status) + 128);
|
||||||
/* Only the child returns. See above. */
|
/* Only the child returns. See above. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void run_shell (const char *shellstr, char *args[], bool doshell,
|
|
||||||
char *const envp[])
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* PAM_DATA_SILENT is not supported by some modules, and
|
|
||||||
* there is no strong need to clean up the process space's
|
|
||||||
* memory since we will either call exec or exit.
|
|
||||||
pam_end (pamh, PAM_SUCCESS | PAM_DATA_SILENT);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (doshell) {
|
|
||||||
(void) shell (shellstr, (char *) args[0], envp);
|
|
||||||
} else {
|
|
||||||
/* There is no need for a controlling terminal.
|
|
||||||
* This avoids the callee to inject commands on
|
|
||||||
* the caller's tty. */
|
|
||||||
(void) setsid ();
|
|
||||||
|
|
||||||
execve_shell (shellstr, (char **) args, envp);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
|
||||||
}
|
|
||||||
#endif /* USE_PAM */
|
#endif /* USE_PAM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1049,6 +1034,40 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
set_environment (pw);
|
set_environment (pw);
|
||||||
|
|
||||||
|
if (!doshell) {
|
||||||
|
/* There is no need for a controlling terminal.
|
||||||
|
* This avoids the callee to inject commands on
|
||||||
|
* the caller's tty. */
|
||||||
|
int err = -1;
|
||||||
|
|
||||||
|
#ifdef USE_PAM
|
||||||
|
/* When PAM is used, we are on the child */
|
||||||
|
err = setsid ();
|
||||||
|
#else
|
||||||
|
/* Otherwise, we cannot use setsid */
|
||||||
|
int fd = open ("/dev/tty", O_RDWR);
|
||||||
|
|
||||||
|
if (fd >= 0) {
|
||||||
|
err = ioctl (fd, TIOCNOTTY, (char *) 0);
|
||||||
|
(void) close (fd);
|
||||||
|
}
|
||||||
|
#endif /* USE_PAM */
|
||||||
|
|
||||||
|
if (-1 == err) {
|
||||||
|
(void) fprintf (stderr,
|
||||||
|
_("%s: Cannot drop the controlling terminal\n"),
|
||||||
|
Prog);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PAM_DATA_SILENT is not supported by some modules, and
|
||||||
|
* there is no strong need to clean up the process space's
|
||||||
|
* memory since we will either call exec or exit.
|
||||||
|
pam_end (pamh, PAM_SUCCESS | PAM_DATA_SILENT);
|
||||||
|
*/
|
||||||
|
|
||||||
endpwent ();
|
endpwent ();
|
||||||
endspent ();
|
endspent ();
|
||||||
/*
|
/*
|
||||||
@ -1081,6 +1100,7 @@ int main (int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!doshell) {
|
if (!doshell) {
|
||||||
|
int err;
|
||||||
/* Position argv to the remaining arguments */
|
/* Position argv to the remaining arguments */
|
||||||
argv += optind;
|
argv += optind;
|
||||||
if (NULL != command) {
|
if (NULL != command) {
|
||||||
@ -1093,24 +1113,15 @@ int main (int argc, char **argv)
|
|||||||
* with the rest of the command line included.
|
* with the rest of the command line included.
|
||||||
*/
|
*/
|
||||||
argv[-1] = cp;
|
argv[-1] = cp;
|
||||||
#ifndef USE_PAM
|
|
||||||
execve_shell (shellstr, &argv[-1], environ);
|
execve_shell (shellstr, &argv[-1], environ);
|
||||||
err = errno;
|
err = errno;
|
||||||
(void) fputs (_("No shell\n"), stderr);
|
(void) fprintf (stderr,
|
||||||
SYSLOG ((LOG_WARN, "Cannot execute %s", shellstr));
|
_("Cannot execute %s\n"), shellstr);
|
||||||
closelog ();
|
errno = err;
|
||||||
exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
} else {
|
||||||
#else
|
(void) shell (shellstr, cp, environ);
|
||||||
run_shell (shellstr, &argv[-1], false, environ); /* no return */
|
}
|
||||||
#endif
|
|
||||||
}
|
return (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
||||||
#ifndef USE_PAM
|
|
||||||
err = shell (shellstr, cp, environ);
|
|
||||||
exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
|
||||||
#else
|
|
||||||
run_shell (shellstr, &cp, true, environ);
|
|
||||||
#endif
|
|
||||||
/* NOT REACHED */
|
|
||||||
exit (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user