[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#785053: jessie-pu: package nss-pam-ldapd/0.9.4-3+deb8u1



On Sat, 2015-08-29 at 15:26 +0200, Julien Cristau wrote:
> Sorry for the delay in getting back to you.
> 
> Please feel free to upload 0.9.4-3+deb8u1.

Thanks. In the meantime, two more bugs arose in nss-pam-ldapd that I
would like to fix in jessie.

The first (#794686) is an RC bug with a one-line fix. The problem was
that the exit code of the init script was wrong in some cases.

I would also like to get #794068 fixed. This fixes password policy
expiration. Instead of forcing the user to change their password, a
warning message should be presented to the user instead. I have just
uploaded the fix to unstable.

Attached is a debdiff with the changes.

Thanks,

-- 
-- arthur - adejong@debian.org - http://people.debian.org/~adejong --
diff -Nru nss-pam-ldapd-0.9.4/debian/changelog nss-pam-ldapd-0.9.4/debian/changelog
--- nss-pam-ldapd-0.9.4/debian/changelog	2014-09-28 15:08:58.000000000 +0200
+++ nss-pam-ldapd-0.9.4/debian/changelog	2015-08-30 13:58:54.000000000 +0200
@@ -1,3 +1,14 @@
+nss-pam-ldapd (0.9.4-3+deb8u1) stable; urgency=low
+
+  * fix-issues-withdaemonising.patch, avoid-signal-race.patch: patches to
+    fix issues with daemonising nslcd and avoid a race condition in signal
+    handling during start-up (closes: #759544)
+  * ensure proper return code of init script (closes: #794686)
+  * fix-ppolicy-expiration-warnings.patch: fix password policy expiration
+    warnings (closes: #794068)
+
+ -- Arthur de Jong <adejong@debian.org>  Sun, 30 Aug 2015 13:00:00 +0200
+
 nss-pam-ldapd (0.9.4-3) unstable; urgency=low
 
   * use-ip-range-for-tests.patch: use a different IP range for running the
diff -Nru nss-pam-ldapd-0.9.4/debian/nslcd.init nss-pam-ldapd-0.9.4/debian/nslcd.init
--- nss-pam-ldapd-0.9.4/debian/nslcd.init	2014-06-08 00:33:57.000000000 +0200
+++ nss-pam-ldapd-0.9.4/debian/nslcd.init	2015-08-30 13:53:17.000000000 +0200
@@ -174,5 +174,3 @@
   exit 1
   ;;
 esac
-
-exit 0
diff -Nru nss-pam-ldapd-0.9.4/debian/patches/avoid-signal-race.patch nss-pam-ldapd-0.9.4/debian/patches/avoid-signal-race.patch
--- nss-pam-ldapd-0.9.4/debian/patches/avoid-signal-race.patch	1970-01-01 01:00:00.000000000 +0100
+++ nss-pam-ldapd-0.9.4/debian/patches/avoid-signal-race.patch	2015-08-30 11:19:41.000000000 +0200
@@ -0,0 +1,71 @@
+From: Arthur de Jong <arthur@arthurdejong.org>
+Subject: Avoid signal race condition on start-up
+
+This only restores the signal mask after signal handlers are in place
+and the daemon has completely daemonised to avoid a race condition in
+the start-up phase of nslcd where a signal could be sent to nslcd
+causing it to quit or fail to write information to the parent process.
+
+This also block signals sooner in an attempt to avoid race conditions.
+
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=1d3b19b1ecd3b10f36e8925e8a752a28e3e74b56
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=530cc24c83dd5d2d347acb40d64c3ae06a43a293
+Bug-Debian: http://bugs.debian.org/759544
+
+--- a/nslcd/nslcd.c
++++ b/nslcd/nslcd.c
+@@ -648,6 +648,17 @@ int main(int argc, char *argv[])
+ #ifdef HAVE_PTHREAD_TIMEDJOIN_NP
+   struct timespec ts;
+ #endif /* HAVE_PTHREAD_TIMEDJOIN_NP */
++  /* block all these signals so our worker threads won't handle them */
++  sigemptyset(&signalmask);
++  sigaddset(&signalmask, SIGHUP);
++  sigaddset(&signalmask, SIGINT);
++  sigaddset(&signalmask, SIGQUIT);
++  sigaddset(&signalmask, SIGABRT);
++  sigaddset(&signalmask, SIGPIPE);
++  sigaddset(&signalmask, SIGTERM);
++  sigaddset(&signalmask, SIGUSR1);
++  sigaddset(&signalmask, SIGUSR2);
++  pthread_sigmask(SIG_BLOCK, &signalmask, &oldmask);
+   /* close all file descriptors (except stdin/out/err) */
+   daemonize_closefds();
+   /* parse the command line */
+@@ -785,17 +796,6 @@ int main(int argc, char *argv[])
+     }
+     log_log(LOG_DEBUG, "setuid(%d) done", (int)nslcd_cfg->uid);
+   }
+-  /* block all these signals so our worker threads won't handle them */
+-  sigemptyset(&signalmask);
+-  sigaddset(&signalmask, SIGHUP);
+-  sigaddset(&signalmask, SIGINT);
+-  sigaddset(&signalmask, SIGQUIT);
+-  sigaddset(&signalmask, SIGABRT);
+-  sigaddset(&signalmask, SIGPIPE);
+-  sigaddset(&signalmask, SIGTERM);
+-  sigaddset(&signalmask, SIGUSR1);
+-  sigaddset(&signalmask, SIGUSR2);
+-  pthread_sigmask(SIG_BLOCK, &signalmask, &oldmask);
+   /* start worker threads */
+   log_log(LOG_INFO, "accepting connections");
+   nslcd_threads = (pthread_t *)malloc(nslcd_cfg->threads * sizeof(pthread_t));
+@@ -815,8 +815,7 @@ int main(int argc, char *argv[])
+       exit(EXIT_FAILURE);
+     }
+   }
+-  pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
+-  /* install signalhandlers for some signals */
++  /* install signal handlers for some signals */
+   install_sighandler(SIGHUP, sig_handler);
+   install_sighandler(SIGINT, sig_handler);
+   install_sighandler(SIGQUIT, sig_handler);
+@@ -827,6 +826,8 @@ int main(int argc, char *argv[])
+   install_sighandler(SIGUSR2, SIG_IGN);
+   /* signal the starting process to exit because we can provide services now */
+   daemonize_ready(EXIT_SUCCESS, NULL);
++  /* enable receiving of signals */
++  pthread_sigmask(SIG_SETMASK, &oldmask, NULL);
+   /* wait until we received a signal */
+   while ((nslcd_receivedsignal == 0) || (nslcd_receivedsignal == SIGUSR1))
+   {
diff -Nru nss-pam-ldapd-0.9.4/debian/patches/fix-issues-withdaemonising.patch nss-pam-ldapd-0.9.4/debian/patches/fix-issues-withdaemonising.patch
--- nss-pam-ldapd-0.9.4/debian/patches/fix-issues-withdaemonising.patch	1970-01-01 01:00:00.000000000 +0100
+++ nss-pam-ldapd-0.9.4/debian/patches/fix-issues-withdaemonising.patch	2015-08-30 11:19:41.000000000 +0200
@@ -0,0 +1,93 @@
+From: Arthur de Jong <arthur@arthurdejong.org>
+Subject: Fix issues with daemonising
+
+This fixes a problem with a buffer that could end up padded with
+garbage.
+
+This also clarifies the code a bit and adds extra logging for errors
+that could occur during daemonising.
+
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=a726d291b0f6794abec0a0192cf2b2a742648e4a
+
+--- a/nslcd/daemonize.c
++++ b/nslcd/daemonize.c
+@@ -57,13 +57,13 @@ void daemonize_closefds(void)
+ void daemonize_redirect_stdio(void)
+ {
+   /* close stdin, stdout and stderr */
+-  close(0);   /* stdin */
+-  close(1);   /* stdout */
+-  close(2);   /* stderr */
++  (void)close(0);   /* stdin */
++  (void)close(1);   /* stdout */
++  (void)close(2);   /* stderr */
+   /* reconnect to /dev/null */
+-  open("/dev/null", O_RDWR);  /* stdin, fd=0 */
+-  dup(0);     /* stdout, fd=1 */
+-  dup(0);     /* stderr, fd=2 */
++  (void)open("/dev/null", O_RDWR);  /* stdin, fd=0 */
++  (void)dup(0);     /* stdout, fd=1 */
++  (void)dup(0);     /* stderr, fd=2 */
+ }
+ 
+ /* try to fill the buffer until EOF or error */
+@@ -95,18 +95,27 @@ static int wait_for_response(int fd)
+   int i, l, rc;
+   char buffer[1024];
+   /* read return code */
++  errno = 0;
+   i = read_response(fd, (void *)&rc, sizeof(int));
++  log_log(LOG_DEBUG, "DEBUG: wait_for_response(): i=%d, rc=%d", i, rc);
+   if (i != sizeof(int))
++  {
++    log_log(LOG_ERR, "wait_for_response(): read_response() returned %d (expected %d)",
++            i, (int)sizeof(int));
++    if (errno == 0)
++      errno = ENODATA;
+     return -1;
++  }
+   /* read string length */
+   i = read_response(fd, (void *)&l, sizeof(int));
++  log_log(LOG_DEBUG, "DEBUG: wait_for_response(): i=%d, l=%d", i, l);
+   if ((i != sizeof(int)) || (l <= 0))
+     _exit(rc);
+   /* read string */
+   if ((size_t)l > (sizeof(buffer) - 1))
+     l = sizeof(buffer) - 1;
+   i = read_response(fd, buffer, l);
+-  buffer[sizeof(buffer) - 1] = '\0';
++  buffer[l] = '\0';
+   if (i == l)
+     fprintf(stderr, "%s", buffer);
+   _exit(rc);
+@@ -200,22 +209,23 @@ int daemonize_daemon(void)
+ 
+ void daemonize_ready(int status, const char *message)
+ {
++  int l;
+   if (daemonizefd >= 0)
+   {
+     /* we ignore any errors writing */
+-    write(daemonizefd, &status, sizeof(int));
++    (void)write(daemonizefd, &status, sizeof(int));
+     if ((message == NULL) || (message[0] == '\0'))
+     {
+-      status = 0;
+-      write(daemonizefd, &status, sizeof(int));
++      l = 0;
++      (void)write(daemonizefd, &l, sizeof(int));
+     }
+     else
+     {
+-      status = strlen(message);
+-      write(daemonizefd, &status, sizeof(int));
+-      write(daemonizefd, message, status);
++      l = strlen(message);
++      (void)write(daemonizefd, &l, sizeof(int));
++      (void)write(daemonizefd, message, l);
+     }
+-    close(daemonizefd);
++    (void)close(daemonizefd);
+     daemonizefd = -1;
+   }
+ }
diff -Nru nss-pam-ldapd-0.9.4/debian/patches/fix-ppolicy-expiration-warnings.patch nss-pam-ldapd-0.9.4/debian/patches/fix-ppolicy-expiration-warnings.patch
--- nss-pam-ldapd-0.9.4/debian/patches/fix-ppolicy-expiration-warnings.patch	1970-01-01 01:00:00.000000000 +0100
+++ nss-pam-ldapd-0.9.4/debian/patches/fix-ppolicy-expiration-warnings.patch	2015-08-30 13:54:18.000000000 +0200
@@ -0,0 +1,145 @@
+Description: Fix password policy warnings
+ Previously, when a password was about to expire, nslcd would incorrectly
+ signal the PAM module to force a password change. This changes this to
+ only present a message to the user.
+ This also ensures that the PAM module logs messages that are presented
+ to the user.
+Author: Arthur de Jong <arthur@arthurdejong.org>
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=4302901a2708d55b24880b77437e3d782b0de1cb
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=263a44340badb1e553c997f2dfb4986fb2f4c28b
+Origin: upstream, http://arthurdejong.org/git/nss-pam-ldapd/commit/?id=309f127416cd38f972d28b29f59e784ea5403785
+Bug-Debian: https://bugs.debian.org/794068
+
+--- a/nslcd/myldap.c
++++ b/nslcd/myldap.c
+@@ -5,7 +5,7 @@
+ 
+    Copyright (C) 1997-2006 Luke Howard
+    Copyright (C) 2006-2007 West Consulting
+-   Copyright (C) 2006-2014 Arthur de Jong
++   Copyright (C) 2006-2015 Arthur de Jong
+ 
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+@@ -406,7 +406,7 @@ static int do_sasl_interact(LDAP UNUSED(
+   }
+ 
+ #if defined(HAVE_LDAP_SASL_BIND) && defined(LDAP_SASL_SIMPLE)
+-static void handle_ppasswd_controls(MYLDAP_SESSION *session, LDAP *ld, LDAPControl **ctrls)
++static void handle_ppolicy_controls(MYLDAP_SESSION *session, LDAP *ld, LDAPControl **ctrls)
+ {
+   int i;
+   int rc;
+@@ -434,10 +434,9 @@ static void handle_ppasswd_controls(MYLD
+       sec = atol(seconds);
+       log_log(LOG_DEBUG, "got LDAP_CONTROL_PWEXPIRING (password will expire in %ld seconds)",
+               sec);
+-      /* return this warning to PAM */
+-      if (session->policy_response == NSLCD_PAM_SUCCESS)
++      /* return this warning so PAM can present it to the user */
++      if (strlen(session->policy_message) == 0)
+       {
+-        session->policy_response = NSLCD_PAM_NEW_AUTHTOK_REQD;
+         mysnprintf(session->policy_message, sizeof(session->policy_message),
+                    "password will expire in %ld seconds",  sec);
+       }
+@@ -453,9 +452,8 @@ static void handle_ppasswd_controls(MYLD
+       else
+       {
+         /* log returned control information */
+-        if (error != PP_noError)
+-          log_log(LOG_DEBUG, "got LDAP_CONTROL_PASSWORDPOLICYRESPONSE (%s)",
+-                  ldap_passwordpolicy_err2txt(error));
++        log_log(LOG_DEBUG, "got LDAP_CONTROL_PASSWORDPOLICYRESPONSE (%s)",
++                ldap_passwordpolicy_err2txt(error));
+         if (expire >= 0)
+           log_log(LOG_DEBUG, "got LDAP_CONTROL_PASSWORDPOLICYRESPONSE (password will expire in %d seconds)",
+                   expire);
+@@ -467,7 +465,8 @@ static void handle_ppasswd_controls(MYLD
+             ((session->policy_response == NSLCD_PAM_SUCCESS) ||
+              (session->policy_response == NSLCD_PAM_NEW_AUTHTOK_REQD)))
+         {
+-          session->policy_response = NSLCD_PAM_AUTHTOK_EXPIRED;
++          /* this means that the password has expired and must be reset */
++          session->policy_response = NSLCD_PAM_NEW_AUTHTOK_REQD;
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "%s", ldap_passwordpolicy_err2txt(error));
+         }
+@@ -475,6 +474,8 @@ static void handle_ppasswd_controls(MYLD
+                  ((session->policy_response == NSLCD_PAM_SUCCESS) ||
+                   (session->policy_response == NSLCD_PAM_NEW_AUTHTOK_REQD)))
+         {
++          /* this means that the account is locked and the user cannot log
++             in (the bind probably failed already) */
+           session->policy_response = NSLCD_PAM_ACCT_EXPIRED;
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "%s", ldap_passwordpolicy_err2txt(error));
+@@ -482,6 +483,8 @@ static void handle_ppasswd_controls(MYLD
+         else if ((error == PP_changeAfterReset) &&
+                  (session->policy_response == NSLCD_PAM_SUCCESS))
+         {
++          /* this indicates that the password must be changed before the
++             user is allowed to perform any other operation */
+           session->policy_response = NSLCD_PAM_NEW_AUTHTOK_REQD;
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "%s", ldap_passwordpolicy_err2txt(error));
+@@ -490,22 +493,23 @@ static void handle_ppasswd_controls(MYLD
+                  ((session->policy_response == NSLCD_PAM_SUCCESS) ||
+                   (session->policy_response == NSLCD_PAM_NEW_AUTHTOK_REQD)))
+         {
++          /* any other error is assumed to mean that the operation failed */
+           session->policy_response = NSLCD_PAM_PERM_DENIED;
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "%s", ldap_passwordpolicy_err2txt(error));
+         }
+-        else if ((expire >= 0) &&
+-                 ((session->policy_response == NSLCD_PAM_SUCCESS) ||
+-                  (session->policy_response == NSLCD_PAM_NEW_AUTHTOK_REQD)))
++        /* both expire and grace should just be warnings to the user */
++        if ((expire >= 0) && (strlen(session->policy_message) == 0))
+         {
+-          session->policy_response = NSLCD_PAM_NEW_AUTHTOK_REQD;
++          /* if no other error has happened, this indicates that the password
++             will soon expire (number of seconds) */
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "Password will expire in %d seconds", expire);
+         }
+-        else if ((grace >= 0) &&
+-                 (session->policy_response == NSLCD_PAM_SUCCESS))
++        else if ((grace >= 0) && (strlen(session->policy_message) == 0))
+         {
+-          session->policy_response = NSLCD_PAM_NEW_AUTHTOK_REQD;
++          /* this indicates the number of grace logins that are left before
++             no further login attempts will be allowed */
+           mysnprintf(session->policy_message, sizeof(session->policy_message),
+                      "Password expired, %d grace logins left", grace);
+         }
+@@ -580,7 +584,7 @@ static int do_ppolicy_bind(MYLDAP_SESSIO
+   /* handle any returned controls */
+   if (responsectrls != NULL)
+   {
+-    handle_ppasswd_controls(session, ld, responsectrls);
++    handle_ppolicy_controls(session, ld, responsectrls);
+     ldap_controls_free(responsectrls);
+   }
+   /* return the result of the BIND operation */
+--- a/pam/pam.c
++++ b/pam/pam.c
+@@ -581,9 +581,17 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,
+     pam_syslog(pamh, LOG_DEBUG, "authorization succeeded");
+   /* present any informational messages to the user */
+   if ((authz_resp.msg[0] != '\0') && (!cfg.no_warn))
++  {
+     pam_info(pamh, "%s", authz_resp.msg);
++    pam_syslog(pamh, LOG_INFO, "%s; user=%s",
++               authz_resp.msg, username);
++  }
+   if ((ctx->saved_authz.msg[0] != '\0') && (!cfg.no_warn))
++  {
+     pam_info(pamh, "%s", ctx->saved_authz.msg);
++    pam_syslog(pamh, LOG_INFO, "%s; user=%s",
++               ctx->saved_authz.msg, username);
++  }
+   return PAM_SUCCESS;
+ }
+ 
diff -Nru nss-pam-ldapd-0.9.4/debian/patches/series nss-pam-ldapd-0.9.4/debian/patches/series
--- nss-pam-ldapd-0.9.4/debian/patches/series	2014-08-20 22:18:40.000000000 +0200
+++ nss-pam-ldapd-0.9.4/debian/patches/series	2015-08-30 13:54:57.000000000 +0200
@@ -1 +1,4 @@
 use-ip-range-for-tests.patch
+fix-issues-withdaemonising.patch
+avoid-signal-race.patch
+fix-ppolicy-expiration-warnings.patch

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: