rpms/nss_ldap/devel pam_ldap-183-rebind_control.patch, NONE, 1.1 pam_ldap-184-referral-passwd.patch, NONE, 1.1

Nalin Somabhai Dahyabhai (nalin) fedora-extras-commits at redhat.com
Fri Oct 12 19:40:00 UTC 2007


Author: nalin

Update of /cvs/pkgs/rpms/nss_ldap/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv5942

Added Files:
	pam_ldap-183-rebind_control.patch 
	pam_ldap-184-referral-passwd.patch 
Log Message:
patches for upstream #232 and our #300251, in which referrals in combination
with expired passwords indicated using server controls tends to fail, first
by not attempting to bind to the master with a password, and then because it
denies us due to the password having expired


pam_ldap-183-rebind_control.patch:

--- NEW FILE pam_ldap-183-rebind_control.patch ---
The rebind_proc is expected to return LDAP, not PAM error codes.  (Fallout from
the fix for upstream #210).

We check for password expiration controls when rebinding, and ignore a
password-expired error if we appear to be in the middle of a password change
attempt.  Attached to upstream #232.

diff -up pam_ldap-176/pam_ldap.c pam_ldap-176/pam_ldap.c
--- pam_ldap-176/pam_ldap.c	2007-10-04 10:51:18.000000000 -0400
+++ pam_ldap-176/pam_ldap.c	2007-10-04 10:51:25.000000000 -0400
@@ -207,6 +207,8 @@ static void _cleanup_data (pam_handle_t 
 static void _cleanup_authtok_data (pam_handle_t * pamh, void *data,
 				   int error_status);
 static int _alloc_config (pam_ldap_config_t ** presult);
+static int _get_password_policy_response_value (struct berval *response_value,
+						pam_ldap_session_t * session);
 #ifdef YPLDAPD
 static int _ypldapd_read_config (pam_ldap_config_t ** presult);
 #endif
@@ -1592,7 +1594,10 @@ _rebind_proc (LDAP * ld, LDAP_CONST char
   pam_ldap_session_t *session = global_session;
 #endif
   char *who, *cred;
-  int rc;
+  struct timeval timeout;
+  int rc, parserc;
+  LDAPMessage *result;
+  LDAPControl **controls;
 
   if (session->info != NULL && session->info->bound_as_user == 1)
     {
@@ -1620,11 +1626,79 @@ _rebind_proc (LDAP * ld, LDAP_CONST char
         {
           syslog (LOG_ERR, "pam_ldap: ldap_starttls_s: %s",
                   ldap_err2string (rc));
-          return PAM_AUTHINFO_UNAVAIL;
+          return LDAP_OPERATIONS_ERROR;
         }
     }
 
+#if !defined(HAVE_LDAP_PARSE_RESULT) || !defined(HAVE_LDAP_CONTROLS_FREE)
   return ldap_simple_bind_s (ld, who, cred);
+#else
+  msgid = ldap_simple_bind (ld, who, cred);
+  if (msgid == -1)
+    {
+      syslog (LOG_ERR, "pam_ldap: ldap_simple_bind %s",
+              ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
+      return LDAP_OPERATIONS_ERROR;
+    }
+
+  timeout.tv_sec = session->conf->bind_timelimit;
+  timeout.tv_usec = 0;
+  result = NULL;
+  rc = ldap_result (ld, msgid, FALSE, &timeout, &result);
+  if (rc == -1 || rc == 0)
+    {
+      syslog (LOG_ERR, "pam_ldap: ldap_result %s",
+              ldap_err2string (ldap_get_lderrno (ld, 0, 0)));
+      ldap_msgfree (result);
+      return LDAP_OPERATIONS_ERROR;
+    }
+
+  controls = NULL;
+  parserc = ldap_parse_result (ld, result, &rc, 0, 0, 0, &controls, TRUE);
+  if (parserc != LDAP_SUCCESS)
+    {
+      syslog (LOG_ERR, "pam_ldap: ldap_parse_result %s",
+              ldap_err2string (parserc));
+      _pam_overwrite (session->info->userpw);
+      _pam_drop (session->info->userpw);
+      return PAM_SERVICE_ERR;
+    }
+  if (controls != NULL)
+    {
+      LDAPControl **ctlp;
+      for (ctlp = controls; *ctlp != NULL; ctlp++)
+        {
+          if (!strcmp ((*ctlp)->ldctl_oid, LDAP_CONTROL_PWEXPIRED))
+            {
+              if (session->info->policy_error == POLICY_ERROR_SUCCESS)
+                session->info->policy_error = POLICY_ERROR_PASSWORD_EXPIRED;
+            }
+          else if (!strcmp ((*ctlp)->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE))
+            _get_password_policy_response_value (&(*ctlp)->ldctl_value,
+                                                 session);
+        }
+      ldap_controls_free (controls);
+      /* suppress a failure due to password expiration or needs-changing if we
+       * appear to be in the middle of changing a password */
+      switch (request)
+        {
+        case LDAP_REQ_MODIFY:
+        case LDAP_REQ_EXTENDED:
+          switch (session->info->policy_error)
+            {
+            case POLICY_ERROR_PASSWORD_EXPIRED:
+            case POLICY_ERROR_CHANGE_AFTER_RESET:
+              rc = LDAP_SUCCESS;
+              break;
+            default:
+              break;
+            }
+        default:
+          break;
+        }
+    }
+    return rc;
+#endif
 }
 #else
 #if LDAP_SET_REBIND_PROC_ARGS == 3

pam_ldap-184-referral-passwd.patch:

--- NEW FILE pam_ldap-184-referral-passwd.patch ---
We need to hang on to the user's (old) password when the policy error is
change-after-reset or password-expired, because at password-change time,
we may need it to chase a referral during the update operation.  Attached
to upstream #232.

--- pam_ldap-184/pam_ldap.c	2005-12-08 12:04:43.000000000 -0600
+++ pam_ldap-184/pam_ldap.c	2005-12-08 12:09:12.000000000 -0600
@@ -2087,7 +2087,14 @@
       return PAM_AUTH_ERR;
     }
 
-  if (session->info->policy_error != POLICY_ERROR_SUCCESS)
+  /*
+   * the above hack to get to acct_mgmt when passwd is expired requires
+   * us to preserve the userpw for subsequent binds to a master server
+   * in case we're doing referrals
+   */
+  if ((session->info->policy_error != POLICY_ERROR_SUCCESS) &&
+      (session->info->policy_error != POLICY_ERROR_PASSWORD_EXPIRED) &&
+      (session->info->policy_error != POLICY_ERROR_CHANGE_AFTER_RESET))
     {
       _pam_overwrite (session->info->userpw);
       _pam_drop (session->info->userpw);




More information about the fedora-extras-commits mailing list