--On October 27, 2011 4:14:12 AM +0000 Viktor Dukhovni <postfix-us...@dukhovni.org> wrote:

Therefore, I propose the following Postfix fix/work-around which
is required for anyone running Postfix 2.3 or later, linked with
OpenLDAP 2.4 or later (perhaps even late 2.3.x releases, I just
compared OpenLDAP 2.3.4 with 2.4.23).

Hi Victor,

Your patch didn't change the behavior. I did some debugging and fixed the problem with the following patch (I kept your patch in place in case it does anything). As far as the API change, the OpenLDAP primary developer responded with: "The old API was garbage because it didn't disclose whether an error occurred locally (in the API) or remotely (from the server). An application's recovery/response procedures need to be able to differentiate the two. E.g., if the API returned ENOMEM, you'd know that your entire program is hosed. If the server returned ENOMEM, you know that your app is OK but you should leave the server alone for a while and try again later."

--Quanah

--- postfix-2.8.5/src/global/dict_ldap.c.orig 2011-10-27 16:06:24.139024496 -0700 +++ postfix-2.8.5/src/global/dict_ldap.c 2011-10-27 16:13:54.959021674 -0700
@@ -498,6 +498,7 @@
static int dict_ldap_result(LDAP *ld, int msgid, int timeout, LDAPMessage **res)
{
    struct timeval mytimeval;
+    int err;

    mytimeval.tv_sec = timeout;
    mytimeval.tv_usec = 0;
@@ -505,10 +506,12 @@
#define GET_ALL 1
    if (ldap_result(ld, msgid, GET_ALL, &mytimeval, res) == -1)
       return (dict_ldap_get_errno(ld));
-
-    if (dict_ldap_get_errno(ld) == LDAP_TIMEOUT) {
-       (void) dict_ldap_abandon(ld, msgid);
-       return (dict_ldap_set_errno(ld, LDAP_TIMEOUT));
+    if ((err = dict_ldap_get_errno(ld)) != LDAP_SUCCESS) {
+      if (err == LDAP_TIMEOUT) {
+        (void) dict_ldap_abandon(ld, msgid);
+        return (dict_ldap_set_errno(ld, LDAP_TIMEOUT));
+      }
+      return err;
    }
    return LDAP_SUCCESS;
}
@@ -566,8 +569,11 @@
                              &res)) != LDAP_SUCCESS)
       return (rc);

-#define FREE_RESULT 1
- return (ldap_parse_sasl_bind_result(dict_ldap->ld, res, 0, FREE_RESULT));
+#define FREE_RESULT 0
+ if ((rc = ldap_parse_sasl_bind_result(dict_ldap->ld, res, 0, FREE_RESULT)) != LDAP_SUCCESS)
+       return (rc);
+
+    return(ldap_result2error( dict_ldap->ld, res, 1 ));
}

/* search_st - Synchronous search with timeout */



--
Quanah Gibson-Mount
Principal Software Engineer
Zimbra, Inc
--------------------
Zimbra ::  the leader in open source messaging and collaboration

Reply via email to