Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Added Continuation Reference Processing as defined in section 4.5.3 of RFC 2251 ( #26

merged 1 commit into from

2 participants


4.5.3. Continuation References in the Search Result

If the server was able to locate the entry referred to by the
baseObject but was unable to search all the entries in the scope at
and under the baseObject, the server may return one or more
SearchResultReference, each containing a reference to another set of
servers for continuing the operation. A server MUST NOT return any
SearchResultReference if it has not located the baseObject and
thus has not searched any entries; in this case it would return a
SearchResultDone containing a referral resultCode.

In the absence of indexing information provided to a server from
servers holding subordinate naming contexts, SearchResultReference
responses are not affected by search filters and are always returned
when in scope.

The SearchResultReference is of the same data type as the Referral.
URLs for servers implementing the LDAP protocol are written according
to [9]. The part MUST be present in the URL, with the new target
object name. The client MUST use this name in its next request.
Some servers (e.g. part of a distributed index exchange system) may
provide a different filter in the URLs of the SearchResultReference.
If the filter part of the URL is present in an LDAP URL, the client
MUST use the new filter in its next request to progress the search,
and if the filter part is absent the client will use again the same
filter. Other aspects of the new search request may be the same or
different as the search which generated the continuation references.

Other kinds of URLs may be returned so long as the operation could be
performed using that protocol.

The name of an unexplored subtree in a SearchResultReference need not
be subordinate to the base object.

In order to complete the search, the client MUST issue a new search
operation for each SearchResultReference that is returned. Note that
the abandon operation described in section 4.11 applies only to a
particular operation sent on a connection between a client and server,
and if the client has multiple outstanding search operations to
different servers, it MUST abandon each operation individually. Example

For example, suppose the contacted server (hosta) holds the entry
"O=MNN,C=WW" and the entry "CN=Manager,O=MNN,C=WW". It knows that
either LDAP-capable servers (hostb) or (hostc) hold
"OU=People,O=MNN,C=WW" (one is the master and the other server a
shadow), and that LDAP-capable server (hostd) holds the subtree
"OU=Roles,O=MNN,C=WW". If a subtree search of "O=MNN,C=WW" is
requested to the contacted server, it may return the following:

 SearchResultEntry for O=MNN,C=WW
 SearchResultEntry for CN=Manager,O=MNN,C=WW
 SearchResultReference {
 SearchResultReference {
 SearchResultDone (success)

Client implementors should note that when following a
SearchResultReference, additional SearchResultReference may be
generated. Continuing the example, if the client contacted the
server (hostb) and issued the search for the subtree
"OU=People,O=MNN,C=WW", the server might respond as follows:

 SearchResultEntry for OU=People,O=MNN,C=WW
 SearchResultReference {
 SearchResultReference {
 SearchResultDone (success)

If the contacted server does not hold the base object for the search,
then it will return a referral to the client. For example, if the
client requests a subtree search of "O=XYZ,C=US" to hosta, the server
may return only a SearchResultDone containing a referral.

 SearchResultDone (referral) {
@RoryO RoryO merged commit 76a81cc into ruby-ldap:master

This is a cool addition! It would be helpful to add a test case for this new feature, however.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 9 additions and 0 deletions.
  1. +8 −0 lib/net/ldap.rb
  2. +1 −0  lib/net/ldap/pdu.rb
8 lib/net/ldap.rb
@@ -317,6 +317,7 @@ class LdapError < StandardError; end
2 => "Protocol Error",
3 => "Time Limit Exceeded",
4 => "Size Limit Exceeded",
+ 10 => "Referral",
12 => "Unavailable crtical extension",
14 => "saslBindInProgress",
16 => "No Such Attribute",
@@ -1418,6 +1419,13 @@ def search(args = {})
when 5 # search-result
result_code = pdu.result_code
controls = pdu.result_controls
+ if return_referrals && result_code == 10
+ if block_given?
+ se =
+ se[:search_referrals] = (pdu.search_referrals || [])
+ yield se
+ end
+ end
raise Net::LDAP::LdapError, "invalid response-type in search: #{pdu.app_tag}"
1  lib/net/ldap/pdu.rb
@@ -136,6 +136,7 @@ def parse_ldap_result(sequence)
:matchedDN => sequence[1],
:errorMessage => sequence[2]
+ parse_search_referral(sequence[3]) if @ldap_result[:resultCode] == 10
private :parse_ldap_result
Something went wrong with that request. Please try again.