pingidentity / ldapsdk

UnboundID LDAP SDK for Java
Other
334 stars 81 forks source link

Fails to retrieve objects of Child AD Domain's OU if OU name contains special characters #75

Closed prashanthmysore closed 4 years ago

prashanthmysore commented 4 years ago

Steps to reproduce: 1) Let's say AD root domain is root.abc.com and it has a child AD Domain child.root.abc.com 2) In the Child AD Domain 'child.root.abc.com', create a OU with special characters say '%^%^%^'. Create few objects under that OU 3) Now connect to the root AD 'root.abc.com' and query with Base DN as 'OU=%^%^%^,DC=child,DC=root,DC=abc,DC=com' 4) It fails with following error: LDAPException(resultCode=10 (referral), numEntries=0, numReferences=0, diagnosticMessage='0000202B: RefErr: DSID-03100781, data 0, 1 access points ref 1: 'child.root.abc.com' ', referralURLs={'ldap://child.root.abc.com/OU=%25%5E%25%5E%25%5E*,DC=child,DC=root,DC=abc,DC=com'}, responseControls={SimplePagedResultsControl(pageSize=0, isCritical=false)}, ldapSDKVersion=4.0.13, revision=f2bf4773e5efb286552d3fa7288eebcdfb31e086') at com.unboundid.ldap.sdk.LDAPConnection.search(LDAPConnection.java:3803)

dirmgr commented 4 years ago

I'm definitely not an Active Directory expert, but I don't think that this necessarily has anything to do with the use of special characters in the DN. Assuming that GitHub isn't doing anything weird with the formatting and that the OU value you're trying to use is "percent, caret, percent, caret, percent, caret, asterisk", then that's a valid OU value and shouldn't require any special encoding.

The response that you're getting is a referral response, which means that the server is telling the client that it should send the search request somewhere else. In this case, the server root.abc.com is telling the client that it should instead send the request to child.root.abc.com.

The LDAP SDK can automatically follow referrals, but you have to enable that. You can do that by creating an LDAPConnectionOptions object and calling setFollowReferrals(true) on it. Then, provide that LDAPConnectionOptions object to the connection when you're creating it. For example:

LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions();
connectionOptions.setFollowReferrals(true);

LDAPConnection connection = new LDAPConnection(sslSocketFactory,
     connectionOptions, "root.abc.com", 636);

Then, when you send a request and the server sends a referral response, then the LDAP SDK will try to automatically follow the referral and get the data from the alternate server.

prashanthmysore commented 4 years ago

Referral is enabled for the LDAP connection.

When I debugged further, I found unboundId SDK is failing when it is decoding Referral URL in LDAPURL class's percentDecode method. It throws the following error:

LDAPException(resultCode=84 (decoding error), errorMessage='Invalid non-hexadecimal character '%' found following a percent sign in the URL string.', ldapSDKVersion=4.0.11, revision=34e39aab27ea4fb92659a6888933db08099c7e41)

dirmgr commented 4 years ago

It looks like there was a bug in the LDAP SDK in its support for decoding LDAP URLs with consecutive percent-encoded bytes. I've just committed a fix for the problem.

dirmgr commented 4 years ago

FYI, the new LDAP SDK version 4.0.14 release includes the fix for this issue.