0

I have some code which is using community version of OpenLDAP. Application is client side. To establish connection with LDAP server I'm using ldap_sasl_bind_s this looks more or less like this:

char *nAuthOption = LDAP_SASL_SIMPLE;
struct berval pPassword = {
    m_Credentials.m_sPassword.length(),
    const_cast<char *>(m_Credentials.m_sPassword.c_str())
};
nStatus = ldap_sasl_bind_s(m_pLDAPConnection,
                           m_Credentials.m_sUsername.c_str(),
                           nAuthOption,
                           &pPassword,
                           NULL,
                           NULL,
                           &servercredp);
free(nAuthOption);

if (nStatus!=LDAP_SUCCESS)
{
    LOGE() << METHOD_NAME << "Failed to bind to LDAP " << LDAPError(nStatus);
    return false;
}
return true;

Now problem is error reporting. I had a case where client randomly could not connect to the LDAP service and in logs I could see only information:

Failed to bind to LDAP Status: -1(0xffffffff): Can't contact LDAP server

This turned out to be useless information. After long investigation we discovered that problem was that one of possible servers didn't support TLS protocol (for security reason secure connections has been limited to TLS protocol only).

Now it would be nice to have in logs something more handy than Can't contact LDAP server. I was thinking to fetch error from OpenSSL context used by OpenLDAP, but I cant find a good way to do that.

Can I fetch some more detailed information why ldap_sasl_bind_s has failed? I'm able to fetch SSL_CTX * but have no idea what I can do with that.

jww
  • 97,681
  • 90
  • 411
  • 885
Marek R
  • 32,568
  • 6
  • 55
  • 140

1 Answers1

0

One way that I've found for getting more detailed information from OpenLDAP is to provide a logging callback for the libber library, like so:

#if defined(LBER_OPT_LOG_PRINT_FN)
static void ldap_debug_cb(const char *msg) {
  /* Write out message to e.g. stderr */
  fprintf(stderr, "LDAP debug: %s\n", msg);
}
#endif /* no LBER_OPT_LOG_PRINT_FN */

#if defined(LBER_OPT_LOG_PRINT_FN)
  if (ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN, ldap_debug_cb) != LBER_OPT_SUCCESS) {
     /* Log error about setting option/callback */
  }
#endif /* LBER_OPT_LOG_PRINT_FN */

Note that you may also need to make sure the OpenLDAP LDAP_DEBUG_LEVEL option is set to a high-enough level, too:

  LDAP *ldap = ...

  /* This debug level value should be LDAP_DEBUG_ANY, but that macro is, I
   * think, OpenLDAP-specific.
   */
  int debug_level = -1;

  if (ldap_set_option(ldap, LDAP_OPT_DEBUG_LEVEL, &debug_level) != LDAP_OPT_SUCCESS) {
    /* Write error about setting option */
  }

Hope this helps!

Castaglia
  • 2,972
  • 5
  • 28
  • 49