]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: 476963
authorAndrew G. Morgan <morgan@kernel.org>
Thu, 11 Jul 2002 05:43:50 +0000 (05:43 +0000)
committerAndrew G. Morgan <morgan@kernel.org>
Thu, 11 Jul 2002 05:43:50 +0000 (05:43 +0000)
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.

CHANGELOG
doc/modules/pam_pwdb.sgml
doc/modules/pam_unix.sgml
doc/pam_source.sgml
modules/pam_pwdb/support.-c
modules/pam_unix/support.c
modules/pam_unix/support.h

index 58d98fd995587fe0f8461eb0401d800547a47791..8958c11831f55ef736451f104a7dd6c9f6c55842 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
index 2ee102e17c242bc81b8bf7e09291eed21b097158..51f4f86d0a753309d125507075c0c56e3d0cd62a 100644 (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
index 286cd3f8c5332b4d9e9ce7bb028cad85a204aac4..86c584a892a7ad5642652c2aaf2fdcce308f121c 100644 (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>
 
index 2dd5783e3fd8e8c06339f2a0e4a8e222e418de19..674404b4356d002b44770f948875d24161381f15 100644 (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
index e6d5829d0661dd10b1306f6fb7788c9b8bce95db..96f3460998adc93ac0ce5c19c98a9c50426ad096 100644 (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));
index 5998c7db640bf181872feb7785384fed2f27cd35..98536d21fd17482ebecdcc706921d295bafcb474 100644 (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;
 }
index 0b6b6e04601b39ab83952d52d1fce2df5cfa3830..755d1c9fb8deeca076ab51aaba14347306b3f2d7 100644 (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)