-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b09
-
generic
-
generic
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.
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.
- relates to
-
JDK-8288895 LdapContext doesn't honor set referrals limit
-
- Resolved
-