On Wed, Feb 25, 2009 at 05:34:26PM -0600, Nick Geron wrote: >> This is an OpenLDAP API design issue. The OpenLDAP library (at least up >> to version 2.3) has a single global SSL_CTX object, that is initialized >> just once by the first call that creates an SSL-protected LDAP connection. >> All requests to set the global SSL context properties are ignored silently >> after that point. >> >> To solve your problem you must make sure that your nsswitch CAfile and >> CAfile include all the certificates needed by Postfix. > > Understood. Thanks again to Victor and Quanah.
Note, the OpenLDAP API design issue is resolved with OpenLDAP 2.4. With OpenLDAP 2.4 it is possible to set the TLS properties for a particular LDAP connection (not just global properties), and to associate a new OpenLDAP managed TLS context for the connection via the new "LDAP_OPT_X_TLS_NEWCTX" option. Try this completely untested patch (it may not even compile, but it looks promising): Index: src/global/dict_ldap.c --- src/global/dict_ldap.c 28 Jan 2008 04:29:48 -0000 1.1.1.2 +++ src/global/dict_ldap.c 26 Feb 2009 00:04:18 -0000 @@ -484,10 +484,16 @@ { const char *myname = "dict_ldap_set_tls_options"; int rc; +#ifdef LDAP_OPT_X_TLS_NEWCTX + int am_server = 0; + LDAP *ld = dict_ldap->ld; +#else + LDAP *ld = 0; +#endif if (dict_ldap->start_tls || dict_ldap->ldap_ssl) { if (*dict_ldap->tls_random_file) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_RANDOM_FILE, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_RANDOM_FILE, dict_ldap->tls_random_file)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_random_file to %s: %d: %s", myname, dict_ldap->tls_random_file, @@ -496,7 +502,7 @@ } } if (*dict_ldap->tls_ca_cert_file) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTFILE, dict_ldap->tls_ca_cert_file)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_ca_cert_file to %s: %d: %s", myname, dict_ldap->tls_ca_cert_file, @@ -505,7 +511,7 @@ } } if (*dict_ldap->tls_ca_cert_dir) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTDIR, dict_ldap->tls_ca_cert_dir)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_ca_cert_dir to %s: %d: %s", myname, dict_ldap->tls_ca_cert_dir, @@ -514,7 +520,7 @@ } } if (*dict_ldap->tls_cert) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CERTFILE, dict_ldap->tls_cert)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_cert to %s: %d: %s", myname, dict_ldap->tls_cert, @@ -523,7 +529,7 @@ } } if (*dict_ldap->tls_key) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_KEYFILE, dict_ldap->tls_key)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_key to %s: %d: %s", myname, dict_ldap->tls_key, @@ -532,7 +538,7 @@ } } if (*dict_ldap->tls_cipher_suite) { - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CIPHER_SUITE, dict_ldap->tls_cipher_suite)) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_cipher_suite to %s: %d: %s", myname, dict_ldap->tls_cipher_suite, @@ -540,13 +546,21 @@ return (-1); } } - if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &(dict_ldap->tls_require_cert))) != LDAP_SUCCESS) { msg_warn("%s: Unable to set tls_require_cert to %d: %d: %s", myname, dict_ldap->tls_require_cert, rc, ldap_err2string(rc)); return (-1); } +#ifdef LDAP_OPT_X_TLS_NEWCTX + if ((rc = ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &am_server)) + != LDAP_SUCCESS) { + msg_warn("%s: Unable to allocate new TLS context %d: %s", + myname, rc, ldap_err2string(rc)); + return (-1); + } +#endif } return (0); } @@ -592,10 +606,6 @@ #ifdef LDAP_OPT_NETWORK_TIMEOUT #ifdef LDAP_API_FEATURE_X_OPENLDAP - if (dict_ldap_set_tls_options(dict_ldap) != 0) { - dict_errno = DICT_ERR_RETRY; - return (-1); - } ldap_initialize(&(dict_ldap->ld), dict_ldap->server_host); #else dict_ldap->ld = ldap_init(dict_ldap->server_host, @@ -700,6 +710,8 @@ #endif #ifdef LDAP_API_FEATURE_X_OPENLDAP + if (dict_ldap_set_tls_options(dict_ldap) != 0) + DICT_LDAP_UNBIND_RETURN(dict_ldap->ld, DICT_ERR_RETRY, -1); if (dict_ldap->start_tls) { if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) { msg_warn("%s: Error setting signal handler for STARTTLS timeout: %m", -- Viktor. Disclaimer: off-list followups get on-list replies or get ignored. Please do not ignore the "Reply-To" header. To unsubscribe from the postfix-users list, visit http://www.postfix.org/lists.html or click the link below: <mailto:majord...@postfix.org?body=unsubscribe%20postfix-users> If my response solves your problem, the best way to thank me is to not send an "it worked, thanks" follow-up. If you must respond, please put "It worked, thanks" in the "Subject" so I can delete these quickly.