Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8176553

LdapContext follows referrals infinitely ignoring set limit

    XMLWordPrintable

Details

    • b09
    • generic
    • generic

    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.

      Attachments

        Issue Links

          Activity

            People

              vtewari Vyom Tewari
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: