On 27 Jun 2011, at 8:29 PM, Stefan Fritsch wrote:
This is fixed by calling the ldap_get_option() function described
in section 9.2 of
http://www-archive.mozilla.org/directory/ietf-docs/draft-ietf-ldap
ext-ldap-c-api-05.txt . There is no need to move the code to
support this, this can be supported today by adding the
appropriate sanity check on init and failing as appropriate.
This does not help us. We need the information encoded in the package
dependencies so that the package manager refuses to install a version
of httpd together with a version of apr that don't work together.
And I don't think you suggestion would work, at least not without a
new API. The problem is this: If apr uses libldap.A and httpd uses
libldap.B, httpd will call apr_ldap_init() which makes apr call
libldap.A's ldap_init(). Apr then passes the resulting LDAP * pointer
to httpd. But httpd will use libldap.B's other ldap_* functions on the
object created by libldap.A. This usually causes segfaults, but it may
also cause more subtle bugs. To detect this issue, both httpd and apr
would need to call ldap_get_option() and httpd would need to compare
the versions returned by both calls.
To fix this, wrap the rest of the LDAP API. This is specified in http://www-archive.mozilla.org/directory/ietf-docs/draft-ietf-ldapext-ldap-c-api-05.txt
, and should be a straightforward task.
Moving ap(r)_ldap to mod_ldap just means you suffer this problem with
other packages, like mod_vhost_ldap, you don't solve this problem at
all.
The problem is that we also need to modify mod_ldap. If we want true
isolation, we would also get #ifdef APR_HAS_SOLARIS_LDAPSDK sections
in mod_ldap, which is what what apr_ldap tried to avoid in the first
place.
This is the wrong way to solve this, here is the full history behind it.
In the early days of LDAP libraries, SSL support was an extremely
basic affair. Implementers hacked the ldap_init() call in various ugly
ways to pass a flag that caused ldap_init() to make a simple and
immediate SSL connection, based on some server wide notion of CA
certificates and other SSL information. The SSL connection was made
immediately, and success or failure returned from the ldap_init()
directly. Call this "simple mode".
Over time, LDAP library implementations realised that SSL support is
configured per connection, do you want SSL or do you want TLS? Do you
want a specific client or CA certificate for this connection? Instead
of a single call to a hacked up ldap_init(), now you had a multi-stage
process, first you ldap_init, then you set any CA and/or client
certificates with ldap_set_option, and then you set whether the
connection will be SSL or TLS with ldap_set_option again. At this
point the connection is completed, and you get success or failure
after the three steps are complete. Call this "multi-stage mode".
Modern LDAP libraries like openldap and mozilla support "multi-stage
mode", while legacy LDAP libraries like the Solaris library only
support "simple mode".
These are two separate and distinct connection patterns that have to
be allowed for separately.
The apr_ldap API supports both modes. In the apr_ldap API, if you want
"simple mode", you pass the "secure" parameter to apr_ldap_init(). If
you want "multi-stage mode", you pass the "secure" parameter via an
apr_ldap_set_option() call.
Right now, mod_ldap supports "multi-stage" mode only, it does not yet
support "simple mode", simply because nobody has ever asked mod_ldap
to support "simple mode".
The simplest way to tackle this is to teach mod_ldap to autodetect
"simple mode", in other words if no per connection certificates are
present, and if "secure" is "SSL" (not "TLS"), use apr_ldap_init() in
"simple mode", otherwise use the existing "multi-stage mode".
Any solution that attempts to detect APR_HAS_SOLARIS_LDAPSDK in
mod_ldap is both unnecessary and wrong, for the reasons you've already
described, just use the apr_ldap API as it was designed to be used.
Regards,
Graham
--