Relevant BUGIDs: 476963

Purpose of commit: new feature

Commit summary:
---------------
some applications are not prepared to get a SIGCHLD from a child
process they didn't think they launched, so we now suppress
this signal for the duration of use of the helper binary.
The 'noreap' module argument is provided to override this new
default.
This commit is contained in:
Andrew G. Morgan 2002-07-11 05:43:50 +00:00
parent f58075a049
commit 449f88eeb4
7 changed files with 74 additions and 14 deletions

View File

@ -55,6 +55,10 @@ bug report - outstanding bugs are listed here:
0.77: please submit patches for this section with actual code/doc
patches!
* pam_unix and pam_pwdb: by default turn off the SIGCHLD handler while
running the helper binary (patch from Nalin) added the "noreap"
module argument to both of these modules to turn off this new
default. (Bug 476963 - agmorgan).
* updated CHANGELOG and configure.in for 0.77 work.
0.76: Mon Jul 8 21:44:59 PDT 2002

View File

@ -99,7 +99,8 @@ login account required pam_pwdb.so
<tt/try_first_pass/;
<tt/nullok/;
<tt/nodelay/;
<tt/likeauth/
<tt/likeauth/;
<tt/noreap/
<tag><bf>Description:</bf></tag>
@ -137,7 +138,14 @@ password when it is stored in a read protected database. This binary
is very simple and will only check the password of the user invoking
it. It is called transparently on behalf of the user by the
authenticating component of this module. In this way it is possible
for applications like <em>xlock</em> to work without being setuid-root.
for applications like <em>xlock</em> to work without being
setuid-root. The module, by default, will temporarily turn off
<tt/SIGCHLD/ handling for the duration of execution of the helper
binary. This is generally the right thing to do, as many applications
are not prepared to handle this signal from a child they didn't know
was <tt/fork()/d. The <tt/noreap/ module argument can be used to
suppress this temporary shielding and may be needed for use with
certain applications.
<p>
The <tt>likeauth</tt> argument makes the module return the same value

View File

@ -97,7 +97,8 @@ login account required pam_unix.so
<tt/use_first_pass/;
<tt/try_first_pass/;
<tt/nullok/;
<tt/nodelay/
<tt/nodelay/;
<tt/noreap/
<tag><bf>Description:</bf></tag>
@ -125,18 +126,25 @@ authentication component from requesting a delay should the
authentication as a whole fail. The default action is for the module
to request a delay-on-failure of the order of one second.
<p>
Remaining arguments, supported by the other functions of this module,
are silently ignored. Other arguments are logged as errors through
<tt/syslog(3)/.
<p>
A helper binary, <tt>unix_chkpwd</tt>, is provided to check the user's
password when it is stored in a read protected database. This binary
is very simple and will only check the password of the user invoking
it. It is called transparently on behalf of the user by the
authenticating component of this module. In this way it is possible
for applications like <em>xlock</em> to work without being setuid-root.
for applications like <em>xlock</em> to work without being
setuid-root. The module, by default, will temporarily turn off
<tt/SIGCHLD/ handling for the duration of execution of the helper
binary. This is generally the right thing to do, as many applications
are not prepared to handle this signal from a child they didn't know
was <tt/fork()/d. The <tt/noreap/ module argument can be used to
suppress this temporary shielding and may be needed for use with
certain applications.
<p>
Remaining arguments, supported by the other functions of this module,
are silently ignored. Other arguments are logged as errors through
<tt/syslog(3)/.
<tag><bf>Examples/suggested usage:</bf></tag>

View File

@ -46,7 +46,7 @@ DAMAGE.
<title>The Linux-PAM System Administrators' Guide
<author>Andrew G. Morgan, <tt>morgan@kernel.org</tt>
<date>DRAFT v0.76 2002/06/26
<date>DRAFT v0.77 2002/07/10
<abstract>
This manual documents what a system-administrator needs to know about
the <bf>Linux-PAM</bf> library. It covers the correct syntax of the

View File

@ -79,8 +79,9 @@ typedef struct {
#define UNIX_UNIX 19 /* wish to use /etc/passwd for pwd */
#define UNIX_BIGCRYPT 20 /* use DEC-C2 crypt()^x function */
#define UNIX_LIKE_AUTH 21 /* need to auth for setcred to work */
#define UNIX_NOREAP 22 /* don't reap child process */
/* -------------- */
#define UNIX_CTRLS_ 22 /* number of ctrl arguments defined */
#define UNIX_CTRLS_ 23 /* number of ctrl arguments defined */
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
@ -109,6 +110,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
/* UNIX_BIGCRYPT */ { "bigcrypt", _ALL_ON_^(020000), 02000000 },
/* UNIX_LIKE_AUTH */ { "likeauth", _ALL_ON_, 04000000 },
/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 010000000 },
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@ -342,13 +344,15 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
* verify the password of a user
*/
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
const char *user)
unsigned int ctrl, const char *user)
{
int retval, child, fds[2];
void (*sighandler)(int) = NULL;
D(("called."));
/* create a pipe for the password */
@ -357,6 +361,18 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
return PAM_AUTH_ERR;
}
if (off(UNIX_NOREAP, ctrl)) {
/*
* This code arranges that the demise of the child does not cause
* the application to receive a signal it is not expecting - which
* may kill the application or worse.
*
* The "noreap" module argument is provided so that the admin can
* override this behavior.
*/
sighandler = signal(SIGCHLD, SIG_IGN);
}
/* fork */
child = fork();
if (child == 0) {
@ -397,6 +413,10 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
retval = PAM_AUTH_ERR;
}
if (sighandler != NULL) {
(void) signal(SIGCHLD, sighandler); /* restore old signal handler */
}
D(("returning %d", retval));
return retval;
}
@ -468,7 +488,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name,
if (geteuid()) {
/* we are not root perhaps this is the reason? Run helper */
D(("running helper binary"));
retval = pwdb_run_helper_binary(pamh, p, name);
retval = pwdb_run_helper_binary(pamh, p, ctrl, name);
} else {
retval = PAM_AUTHINFO_UNAVAIL;
_log_err(LOG_ALERT, "get passwd; %s", pwdb_strerror(retval));

View File

@ -16,6 +16,7 @@
#include <limits.h>
#include <utmp.h>
#include <errno.h>
#include <signal.h>
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
@ -434,6 +435,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
unsigned int ctrl, const char *user)
{
int retval, child, fds[2];
void (*sighandler)(int) = NULL;
D(("called."));
/* create a pipe for the password */
@ -442,6 +444,18 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
return PAM_AUTH_ERR;
}
if (off(UNIX_NOREAP, ctrl)) {
/*
* This code arranges that the demise of the child does not cause
* the application to receive a signal it is not expecting - which
* may kill the application or worse.
*
* The "noreap" module argument is provided so that the admin can
* override this behavior.
*/
sighandler = signal(SIGCHLD, SIG_IGN);
}
/* fork */
child = fork();
if (child == 0) {
@ -486,6 +500,10 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
retval = PAM_AUTH_ERR;
}
if (sighandler != NULL) {
(void) signal(SIGCHLD, sighandler); /* restore old signal handler */
}
D(("returning %d", retval));
return retval;
}

View File

@ -80,8 +80,9 @@ typedef struct {
#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */
#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */
#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */
#define UNIX_NOREAP 21 /* don't reap child process */
/* -------------- */
#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
#define UNIX_CTRLS_ 22 /* number of ctrl arguments defined */
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
@ -110,6 +111,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000},
/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000},
/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000},
/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000},
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)