[Date Prev][Date Next] [Chronological] [Thread] [Top]

LDAPv3 referral when server supplies an invalid referral URL



Hi All,

I'd like to know what is supposed to be a correct behaviour of the
"chasing referrals" feature of libldap if the LDAP referral URL is
invalid according to RFC2255.

There is an LDAPv3/v2 server (ldap.surfnet.nl:389) which generates
referrals non-conformant to the standard, namely
"ldap://dsa.megaplex.nl:389??base";. RFC2255 says any "?" in the URL are
possible only if the "/<DN>" also exists.
I believe libldap should report an error in that case, just don't know
which error. Instead, in case of LDAPv2 pseudo-referral it strips
"??base" off (which may be correct), but for LDAPv3 referral it treats
"base" as the DN for the next request while chasing.
I'm attaching a unified diff between -d1 logs of LDAPv2 and v3 requests.
To be exact, the requests were done as follows:
ldapsearch -H ldap://ldap.surfnet.nl:389/ -s base -b o=GemNet,c=NL -C -d
1 -P 2
ldapsearch -H ldap://ldap.surfnet.nl:389/ -s base -b o=GemNet,c=NL -C -d
1

Please be aware that the server is not OpenLDAP or at least a modified
OpenLDAP. For "ldapsearch -s one -b c=NL" it returns not continuation
references but pre-cached copies of subentries. Referrals happen only
for base search on the second level.

diff -U 1000 v2.log v3.log:
--- v2.log      Thu Mar 22 10:45:42 2001
+++ v3.log      Thu Mar 22 10:45:51 2001
@@ -1,324 +1,191 @@
 ldap_create
 ldap_url_parse(ldap://ldap.surfnet.nl:389/)
 ldap_bind_s
 ldap_simple_bind_s
 ldap_sasl_bind_s
 ldap_sasl_bind
 ldap_send_initial_request
 ldap_new_connection
 ldap_int_open_connection
 ldap_connect_to_host
 ldap_pvt_gethostbyname_a: host=ldap.surfnet.nl, r=0
 ldap_new_socket: 4
 ldap_prepare_socket: 4
 ldap_connect_to_host: Trying 192.87.5.135:389
 ldap_connect_timeout: fd: 4 tm: -1 async: 0
 ldap_ndelay_on: 4
 ldap_is_sock_ready: 4
 ldap_ndelay_off: 4
 ldap_int_sasl_open: weetmuts.surfnet.nl
 ldap_delayed_open successful, ld_host is (null)
 ldap_send_server_request
 ber_flush: 14 bytes to sd 4
 ldap_result msgid 1
 ldap_chkResponseList for msgid=1, all=1
 ldap_chkResponseList returns NULL
 wait4msg (infinite timeout), msgid 1
 wait4msg continue, msgid 1, all 1
 ** Connections:
 * host: ldap.surfnet.nl  port: 389  (default)
   refcnt: 2  status: Connected
-  last used: Thu Mar 22 10:45:40 2001
+  last used: Thu Mar 22 10:45:50 2001

 ** Outstanding Requests:
  * msgid 1,  origid 1, status InProgress
    outstanding referrals 0, parent count 0
 ** Response Queue:
    Empty
 ldap_chkResponseList for msgid=1, all=1
 ldap_chkResponseList returns NULL
 do_ldap_select
 read1msg: msgid 1, all 1
 ber_get_next
 ber_get_next: tag 0x30 len 12 contents:
 ldap_read: message type bind msgid 1, original id 1
+ber_scanf fmt ({iaa) ber:
 ber_scanf fmt ({iaa}) ber:
 new result:  res_errno: 0, res_error: <>, res_matched: <>
 read1msg:  0 new referrals
 read1msg:  mark request completed, id = 1
 request 1 done
 res_errno: 0, res_error: <>, res_matched: <>
 ldap_free_request (origid 1, msgid 1)
 ldap_free_connection
 ldap_free_connection: refcnt 1
 ldap_parse_result
 ber_scanf fmt ({iaa) ber:
 ber_scanf fmt (}) ber:
 ldap_msgfree
 ldap_search_ext
 put_filter "(objectclass=*)"
 put_filter: simple
 put_simple_filter "objectclass=*"
 ldap_send_initial_request
 ldap_send_server_request
 ber_flush: 52 bytes to sd 4
 ldap_result msgid -1
 ldap_chkResponseList for msgid=-1, all=0
 ldap_chkResponseList returns NULL
 wait4msg (infinite timeout), msgid -1
 wait4msg continue, msgid -1, all 0
 ** Connections:
 * host: ldap.surfnet.nl  port: 389  (default)
   refcnt: 2  status: Connected
-  last used: Thu Mar 22 10:45:40 2001
+  last used: Thu Mar 22 10:45:50 2001

 ** Outstanding Requests:
  * msgid 2,  origid 2, status InProgress
    outstanding referrals 0, parent count 0
 ** Response Queue:
    Empty
 ldap_chkResponseList for msgid=-1, all=0
 ldap_chkResponseList returns NULL
 do_ldap_select
 read1msg: msgid -1, all 0
 ber_get_next
 ber_get_next: tag 0x30 len 48 contents:
 ldap_read: message type search-result msgid 2, original id 2
-ber_scanf fmt ({iaa}) ber:
-ldap_chase_referrals
-chasing LDAP referral: <ldap://dsa.megaplex.nl:389>
-re_encode_request: new msgid 3, new dn <NONE>
+ber_scanf fmt ({iaa) ber:
+ber_scanf fmt ({v}) ber:
+ldap_chase_v3referrals
+ldap_url_parse(ldap://dsa.megaplex.nl:389??base)
+re_encode_request: new msgid 3, new dn <base>
 ber_scanf fmt ({it) ber:
 ber_scanf fmt ({a) ber:
+ldap_chase_v3referral: msgid 2, url "ldap://dsa.megaplex.nl:389??base";
 ldap_send_server_request
 ldap_new_connection
 ldap_int_open_connection
 ldap_connect_to_host
 ldap_pvt_gethostbyname_a: host=dsa.megaplex.nl, r=0
 ldap_new_socket: 6
 ldap_prepare_socket: 6
 ldap_connect_to_host: Trying 62.12.26.22:389

... (further log is irrelevant).

I will certainly contact the server maintainer and ask him why the
server is using these URLs, but anyway, I think the libldap library
should not just strip "??" of the URL and assume "base" is the DN.
If I got a description of the correct behaviour, I could provide a
patch.

Regards,
    Konstantin.

--
          * *        Konstantin Chuguev - Application Engineer
       *      *              Francis House, 112 Hills Road
     *                       Cambridge CB2 1PQ, United Kingdom
 D  A  N  T  E       WWW:    http://www.dante.net