I have completed the implementation of LDAP
V3 referrals and search references and will
submit a patch in a few days after we have
completed additional testing.
When we examined the rebind procedure
functionality, we realized that it doesn't
seem to meet the needs of V3 systems. In the
current V2 mechanism, when a referral is
received, the SDK calls the application
rebind procedure which returns to the SDK
username and password. The SDK then performs
an ldap_bind_s using these credentials.
LDAP V3 supports multiple varieties of bind,
viz. ldap_simple_bind, ldap_sasl_bind, plus
variations left over from LDAP V2. In
addition to additional parameters like
controls, server credentials, and etc.
ldap_sasl_bind may require multiple
interactions with the server to complete a
bind operation. For some operations on V3
bind is not required at all. I could not see
a way to make something analogous to the
current mechanism fit these needs.
I would like your comments, suggestions, or
flames on what we eventually implemented. We
are using the current mechanism to register
the rebind procedure using
ldap_set_rebind_proc. We thought of using
ldap_set_option, but realized that there is
no way to enforce compiler type checking on
the rebind proc definition using
ldap_set_option, where the
ldap_set_rebind_proc does do type checking.
The definitions from ldap.h are as follows:
/* V3 REBIND Function Callback Prototype */
typedef int (LDAP_REBIND_PROC) ( LDAP *ld,
LDAP_CONST char *url, int request, ber_int_t msgid);
LIBLDAP_F( int )
The rebindproc has four parameters:
ld - the session handle
url - the url string of the referral that
caused the rebind procedure to be called
request - the type of LDAP request being
processed that caused the referral or search
reference, for example LDAP_REQ_SEARCH
msgID - the message id of the operation
When the SDK calls the application rebind
procedure, it is up to the rebind procedure
to perform a synchronous bind (or not perform
a bind) according to the requirements of the
application. It is up to the application to
provide the rebind procedure with access to
appropriate credentials. If the bind
succeeds or is not required, the rebind
procedure returns LDAP_SUCCESS to the SDK, or
any other error code if not successful.
When a referral rebind fails, the application
request (ldap_search_s, etc) is ended with an
LDAP_REFERRAL error code.
When a search reference rebind fails, the
reference is returned with the other search
If no rebind procedure is registered, the SDK
performs an anonymous ldap_bind_s.
We tried to give the application everything
we know about the referral.
Using ld and perhaps msgID, the application
could find context specific information
associated with the operation based on an
application specific mechanism. We
considered using ldap_set_option with a (void
*) pointer and a matching ldap_get_option to
save context specific data in the ld and make
it available to the application, but felt
went beyond the requirements of referrals and
requires further discussion.
The referral url could allow the application
to decide whether to follow the referral
based on subnet or other information
contained in the referral. The application
can use the ldap_url_parse function to pull
the referral apart into its various
The request type gives the application
information as to what request type caused
We also changed the semantics of the
ldap_set_rebind_proc a little. We put it
into the options area and treat it exactly as
an option, i.e. if NULL is specified for the
ld parameter, then it is set in the global
options area and will automatically be
registered for any new ld created when
ldap_init is called.
One problem with this and the current
mechanism, is if the application requires
interaction with the user to get credentials,
the LDAP SDK thread may be suspended for
perhaps a very long time. Currently this is
something the application must deal with.
Perhaps in the future, a thread could be
spawned when the rebind procedure is called.
In the current SDK code, there isn't any
threading being done at all, so something
like this could considerably complicate the
Thanks for your comments,