JDK-6201615 : LDAP Service Provider does not parse LDAP names with escape characters ('\') properly.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.naming
  • Affected Version: 1.4.2
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_9
  • CPU: generic
  • Submitted: 2004-11-30
  • Updated: 2014-11-04
  • Resolved: 2004-12-18
Related Reports
Duplicate :  
Relates :  
Description
2004/11/30 18:00 ###@###.### --
If a LDAP entry has a DN with a sequence of escape characters, calls to search() from javax.naming.directory.InitialDirContext do not return the correct number of '\' characters.  For example, if we have an entry like "cn=A:\\TestA", the name of the binding in that name space will appear "A:\\\TestA".  If the entry RDN contains three '\' characters, the binding name will contain two extra '\'s.  It seems that for N proper '\' characters in a RDN, there will be N - 1 '\' characters in the binding name.  The problem may lie in the name parser.

Below is the test program (also attached to this bug).

------------------------------------------------------------
import com.sun.jndi.ldap.LdapName;  // for v1.4.2 and v1.5.0
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
//import javax.naming.ldap.LdapName;  // for v1.5.0 only

public class SearchTest {
    public static void main(String[] argumentList) throws NamingException {
        Attribute         attribute             = null;
	Hashtable         environment           = new Hashtable();
        InitialDirContext initialContext        = null;
        NamingEnumeration attributeEnumeration  = null;
        NamingEnumeration attributesEnumeration = null;
        NamingEnumeration bindingsEnumeration   = null;
        NamingEnumeration resultsEnumeration    = null;
        SearchResult      result                = null;

        environment.put(Context.INITIAL_CONTEXT_FACTORY,
          "com.sun.jndi.ldap.LdapCtxFactory");
        environment.put(Context.PROVIDER_URL,
          "ldap://sb150-a.aus.sun.com:389/o=testRoot");
        environment.put(Context.SECURITY_PRINCIPAL,
          "cn=Directory Manager");
        environment.put(Context.SECURITY_CREDENTIALS,
          "dirmanager");

        initialContext = new InitialDirContext(environment);

        if (argumentList.length > 0 && argumentList[0].compareToIgnoreCase("add") == 0) {
            Attributes attrs  = new BasicAttributes();
            Name       oracle = new LdapName("cn=O:\\\\Oracle,cn=OracleContext");

            attrs.put(new BasicAttribute("objectClass", "top"));
            attrs.put(new BasicAttribute("objectClass", "person"));
            attrs.put(new BasicAttribute("cn",          "O:\\\\Oracle"));
            attrs.put(new BasicAttribute("sn",          "O:\\\\Oracle"));

            initialContext.createSubcontext(oracle, attrs);

            System.out.println("\nsuccessfully added cn=O:\\\\Oracle!\n");
        }

        for (bindingsEnumeration = initialContext.listBindings("cn=OracleContext"); bindingsEnumeration.hasMoreElements(); ) {
            System.out.println("binding: " + ((Binding)bindingsEnumeration.nextElement()).toString());
        }
        System.out.println();
        bindingsEnumeration.close();

        for (resultsEnumeration = initialContext.search("cn=OracleContext", "cn=*", null); resultsEnumeration.hasMoreElements(); ) {
            result = (SearchResult)resultsEnumeration.nextElement();

            System.out.println(" [search found name: " + result.getName() + "]");

            for (attributesEnumeration = (result.getAttributes()).getAll(); attributesEnumeration.hasMoreElements(); ) {
                attribute = (Attribute)attributesEnumeration.nextElement();

                for (attributeEnumeration = attribute.getAll(); attributeEnumeration.hasMoreElements(); ) {
                    System.out.println("\t" + attribute.getID() + " : " + attributeEnumeration.nextElement());
                }
                attributeEnumeration.close();
            }
            attributesEnumeration.close();
        }
        System.out.println();
        resultsEnumeration.close();

        initialContext.close();
    }
}
------------------------------------------------------------


Comments
EVALUATION This is not a bug, but it is a common stumbling point when using JNDI with LDAP. When an LDAP name (called a "DN") gets wrapped into a JNDI composite name, some characters such as backslash may be escaped by JNDI. This means that backslashes are potentially escaped at each of three layers: - JNDI - LDAP - Java (when using String literals containing backslashes) Very confusing! See this page in the JNDI Tutorial for more on this: http://java.sun.com/products/jndi/tutorial/beyond/names/syntax.html A short summary: A string containing a DN should be converted to a JNDI composite name before being passed to an LDAP context operation such as search(). You can do it like this: String dn = ...; Name cname = new CompositeName().add(dn); dirctx.search(cname, ...); There's also an LdapName class new to JDK 5 that provides an alternate (and possibly more intuitive) way to do this: String dn = ...; Name lname = new LdapName(dn); dirctx.search(lname, ...); When a string contains a JNDI composite name (perhaps the result of an LDAP search operation, for example), to extract the DN do something like this: String cname = ...; Name cname = new CompositeName(cname); String dn = cname.get(0); ###@###.### 2004-12-18 00:02:55 GMT
18-12-2004