On Tue, 28 Feb 2012 18:46:10 -0500, Qiang Xu qixu@lexmark.com wrote:
The complete code is quite long. But the essential parts are here. After these options are set, it goes with "ldap_start_tls_s(ldapHandle, NULL, NULL)" and "ldap_sasl_bind(ldapHandle, username, LDAP_SASL_SIMPLE, &password_ber, NULL, NULL, &msgid)". And if all is well with bind and search, then an unbind follows.
The essential parts here are creating the LDAP* with ldap_initialize() or whatever, and ldap_start_tls_s().
Do you use the same LDAP* connection for both "bindings"? Its options are set when it is initialized. Try to unbind and then create a new LDAP*.
It is guaranteed that every bind is paired with an unbind operation.
Note that ldap_unbind() is misnamed, it should have been called ldap_destroy(). It does send an unbind, but the more important part is that it destroys the LDAP*.
Furthermore, these cert options are said to be global, having nothing to do with any specific ldap handle.
Don't know where it says that. Options with LDAP* NULL are global, but global options are copied to newly created LDAP*s. Changing a global option has no effect on an existing LDAP*, unless the option itself really is global - if any option is. I suppose some SASL or TLS opts might be, if some SASL/TLS library does not support per-connection options.
Try this:
/* Usage: <program> [ serverhost [ 2nd arg prevents unbind/reinit ]] */
#include <assert.h> #include <ldap.h> #include <stdio.h>
int main(int argc, char **argv) { int i, r, flags[] = { LDAP_OPT_X_TLS_NEVER, LDAP_OPT_X_TLS_DEMAND }; LDAP *ld; i = LDAP_VERSION3; r = ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &i); assert(r == LDAP_OPT_SUCCESS); for (i = 0; i < 2; i++) { r = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &flags[i]); assert(r == LDAP_OPT_SUCCESS); if (i < argc-2) continue; r = ldap_initialize(&ld, argv[1]); assert(r == LDAP_SUCCESS); r = ldap_start_tls_s(ld, NULL, NULL); printf("#%d => %s%s", i+1, ldap_err2string(r), i ? "\n" : ", "); ldap_unbind_ext_s(ld, NULL, NULL); } return 0; }
./testprog servername ./testprog servername x