JDK-8176553 : LdapContext follows referrals infinitely ignoring set limit
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.naming
  • Affected Version: 8,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2017-03-07
  • Updated: 2022-06-21
  • Resolved: 2018-08-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 12
12 b09Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

(identical behavior also on jdk-8u72)

ADDITIONAL OS VERSION INFORMATION :
Linux lenovo 4.9.10-200.fc25.x86_64 #1 SMP Wed Feb 15 23:28:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
If "java.naming.referral" is set to "follow" and LDAP directory contains loop, LdapContext iterate infinitely.

By documentation is should stop with LimitExceededException after exceeding set limit, but limit set in "java.naming.ldap.referral.limit" is ignored.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. prepare LDAP server with referral back to itself (or any loop of referring LDAP servers)
2. prepare DirContext env:
2a set "follow" mode
2b set referrals following depth limit: "java.naming.ldap.referral.limit"
3. use context to search directory

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When depth of referring go through set limit, LimitExceededException should be thrown and iteration skipped.
ACTUAL -
Iteration continues infinitely.
Exception is generated somewhere in JVM by debugger, but it is catch and ignored inside of LdapCtx, not visible behind the API.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
>>>
>>>ou=test
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com
...
>>>ldap://localhost:10389/dc=example,dc=com
>>>ldap://localhost:10389/ou=test,dc=example,dc=com

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package org.example;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import java.util.Hashtable;

public class ReferralsTest {
    public static void main(String[] args) throws Exception {

        Hashtable<String, Object> env = new Hashtable<>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://localhost:10389/dc=example,dc=com");
        env.put(Context.REFERRAL, "follow");
        env.put("java.naming.ldap.referral.limit", "5"); // ignored :(

        DirContext ctx = new InitialDirContext(env);

        SearchControls ctls = new SearchControls();
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        NamingEnumeration answer = ctx.search("", "(objectclass=*)", ctls);

        while (answer.hasMore()) {
            System.out.println(">>>" + ((SearchResult)answer.next()).getName());
        } // never ends, when loop in refferals in LDAP

        ctx.close();
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Need to use "throw" mode instead of "follow" mode and handle referrals manually.


Comments
URL: http://hg.openjdk.java.net/jdk/jdk/rev/0f8e680269d4 User: vtewari Date: 2018-08-29 08:40:59 +0000
29-08-2018

Patch submitted in email: http://mail.openjdk.java.net/pipermail/core-libs-dev/2018-January/051080.html
31-01-2018

To submitter: Please refer the link http://openjdk.java.net/contribute/ to see the procedure for contributing to OpenJDK. Please send out the details of your patch to the core-libs mailing list at core-libs-dev@openjdk.java.net where it can be reviewed and the fix may be sponsored.
24-01-2018

Additional Information from submitter: I have prepared trivial patch fixing bug JDK-8176553 for latest OpenJDK. I will welcome if it could be merged into JDK. (I am covered by Red Hat OCA.) The patch: diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java b/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java --- a/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java @@ -312,7 +312,8 @@ if ((refEx != null) && (refEx.hasMoreReferrals() || - refEx.hasMoreReferralExceptions())) { + refEx.hasMoreReferralExceptions()) && + ! (errEx instanceof LimitExceededException)) { if (homeCtx.handleReferrals == LdapClient.LDAP_REF_THROW) { throw (NamingException)(refEx.fillInStackTrace());
24-01-2018

Import the attached ldif file to the LDAP connection and run the attached test case. JDK 8u121 - Fail JDK 9-ea+161 - Fail Following output goes on indefinitely: >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com >>>ldap://localhost:10389/dc=example,dc=com >>>ldap://localhost:10389/ou=test,dc=example,dc=com ................................... ...................................
04-04-2017

From submitter: Additional Information: LDIF used to testing: (only one server referring itself: ldap://localhost:10389) ---------------------------- version: 1 dn: dc=example,dc=com objectclass: top objectclass: domain dc: example dn: ou=test,dc=example,dc=com objectClass: organizationalUnit objectClass: top ou: test dn: ou=myref,dc=example,dc=com objectClass: extensibleObject objectClass: referral objectClass: top ou: myref ref: ldap://localhost:10389/dc=example,dc=com
24-03-2017

To submitter: Can you please provide the LDIF that can be used for running the test case and reproducing the issue.
13-03-2017