JDK-4894089 : DN containing four backslashes in Java is retrieved with three backslashes
  • Type: Bug
  • Component: core-libs
  • Sub-Component: javax.naming
  • Affected Version: 1.3.1,1.4.2
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_8,solaris_9,windows_2000
  • CPU: generic
  • Submitted: 2003-07-22
  • Updated: 2003-08-27
  • Resolved: 2003-08-27
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
Backslash is a special character in LDAP and has to be escaped, in order to
be used literally in a Distinguished Name (RFC 2253).
Retrieving DN from LDAP results in a string containing three (3) backslashes.

The problem is easily reproducible:

1. Testcase
-----------
 The testcase consists of the following files:

-rw-r--r--   1 tl15687  sun          251 Jul 22 10:39 test_u.ldif
-rw-r--r--   1 tl15687  sun         3869 Jul 22 10:19 SearchTest.java

% more test_u.ldif
dn: uid=de-dus-mgh-m-02\\u0146221,ou=People,dc=commslab,dc=ldap,dc=com
givenName: u0146221
sn: 0146221
uid: de-dus-mgh-m-02\\u0146221
cn: Backslash Test
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson

%

% more SearchTest.java
 
import java.util.Hashtable;

import javax.naming.*;
import javax.naming.directory.*;

public class SearchTest {

  static int timelimit = 50000;
  static int sizelimit = 2000;
  static String baseDN= "uid=de-dus-mgh-m-02\\\\u0146221"; 
  static String user = "cn=Directory Manager";
    //please adjust to your settings
  static String password = "";
  static String providerURL = 
     "ldap://lab147.germany:389/ou=People,dc=commslab,dc=ldap,dc=com";

  public static void main(String[] args) {

    InitialDirContext ctx = openContext();

    SearchControls searchControls = new SearchControls();
    searchControls.setTimeLimit(timelimit);
    searchControls.setCountLimit(sizelimit);
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    searchControls.setReturningObjFlag(true);
    searchControls.setDerefLinkFlag(false);

    //searchControls.setReturningAttributes(new String[] {"wpproperty"});

    try {

      NamingEnumeration answers = 
         ctx.search("", baseDN, searchControls);

      if (answers == null) System.out.println("no answer record");
      else System.out.println("one or more records found");

      // set data bag

      while(answers.hasMore()) {
       // get the entry from the search

        SearchResult sr = (SearchResult) answers.next();

        String dn = sr.getName();
        System.out.println("Distinguished Name is " + dn);

        Attributes attrs = sr.getAttributes();
        // if there is no mapping read the attributes by physical name

        NamingEnumeration ae = attrs.getAll();
        while (ae.hasMore()) {
          Attribute oneAttribute = (Attribute)ae.next();
          // get attribute name
          String currentAttribute = oneAttribute.getID();
          if (oneAttribute != null) {
            NamingEnumeration allValues = oneAttribute.getAll();
            while (allValues.hasMore()) {
              System.out.println(  
                currentAttribute+" = "+(String) allValues.next());
            }
          }
        }//end while
      }
    }catch (NoInitialContextException e) {
       String logMessage = 
          "ADAPTER: Test JNDI NoInitialContext Exception when "
           +"reading subcontext. System Msg: " + e;
       System.out.println(logMessage);
  
    }catch(CommunicationException e) {
       String logMessage = 
          "ADAPTER: Test JNDI Communication Exception when reading "
          +"subcontext. System Msg: " + e;
       System.out.println(logMessage);

    }catch (NamingException e) {
       System.out.println(
          "Adapter: Test JNDI Exception getting attributes, DN:"
           +baseDN);
       System.out.println("System Msg: " +e);
    }
  }

  public static InitialDirContext openContext () {
    Hashtable env = new Hashtable();
        
    env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, user);
    env.put(Context.SECURITY_CREDENTIALS, password);
    env.put(Context.PROVIDER_URL, providerURL);
    InitialDirContext ctx = null;
    try {
      ctx = new InitialDirContext(env);
    } catch (Exception e) {
      System.out.println("exception when trying to open connection "
                         +e.getMessage());
    }

    return ctx;
  }
}


2. Create LDAP entry
--------------------
 lab147 is running iPlanet Directory Server 5.1 SP 2 (Solaris bundled
 product + patch):

# ldapadd -h lab147 -D "cn=directory manager" -w [wiped] -f test_u.ldif
adding new entry uid=de-dus-mgh-m-02\\u0146221,ou=People,dc=commslab,dc=ldap,dc=com

#

# ldapsearch -h lab147 -D "cn=directory manager" -b ou=People,dc=commslab,dc=ldap,dc=com uid=de*
Bind Password:
uid=de-dus-mgh-m-02\u0146220,ou=People,dc=commslab,dc=ldap,dc=com
uid=de-dus-mgh-m-02\u0146220
uid=de-dus-mgh-m-02u0146220
objectClass=top
objectClass=person
objectClass=organizationalPerson
objectClass=inetorgperson
givenName=Dirk
sn=Winkler
cn=Dirk Winkler

uid=de\\backslashtest,ou=People,dc=commslab,dc=ldap,dc=com
givenName=Backslash
sn=Test
uid=de\\backslashtest
uid=de\backslashtest
cn=Backslash Test
objectClass=top
objectClass=person
objectClass=organizationalPerson
objectClass=inetorgperson

uid=de-dus-mgh-m-02\\u0146221,ou=People,dc=commslab,dc=ldap,dc=com
givenName=u0146221
sn=0146221
uid=de-dus-mgh-m-02\\u0146221
uid=de-dus-mgh-m-02\u0146221
cn=Backslash Test
objectClass=top
objectClass=person
objectClass=organizationalPerson
objectClass=inetorgperson
# 


3. Compile and run
------------------
% /j2sdk1_3_1_08/bin/java -version
java version "1.3.1_08"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_08-b03)
Java HotSpot(TM) Client VM (build 1.3.1_08-b03, mixed mode)
% /j2sdk1_3_1_08/bin/javac SearchTest.java
% 
% /j2sdk1_3_1_08/bin/java SearchTest
one or more records found
Distinguished Name is uid=de-dus-mgh-m-02\\\u0146221   <------- !!!!!
uid = de-dus-mgh-m-02\\u0146221
uid = de-dus-mgh-m-02\u0146221
objectClass = top
objectClass = person
objectClass = organizationalPerson
objectClass = inetorgperson
givenName = u0146221
sn = 0146221
cn = Backslash Test
% 



Comments
PUBLIC COMMENTS Backslash is a special character in LDAP and has to be escaped, in order to be used literally in Distinguished Names (RFC 2253). Retrieving DN from LDAP results in a string containing three (3) backslashes.
02-09-2004

EVALUATION This is not a bug. Adding the relevant email exchanges with ###@###.###: Example 1: > Java: "uid=de-dus-mgh-m-02\\u0146221" > This is what is meant without any escaping: > Name: "uid=de-dus-mgh-m-02\u0146221" > As "\" is literal, it needs to be escaped: > CompositeString Name: "uid=de-dus-mgh-m-02\\u0146221" What you call "Name:" I presume is an LDAP DN. The backslash does not precede a JNDI meta character, so when converting this DN to a JNDI composite name string, no further escaping is required. > Example 2: > Java: "uid=de-dus-mgh-m-02\\\\u0146221" > This is what is meant without any escaping: > Name: "uid=de-dus-mgh-m-02\\u0146221" > As both "\\" are literal, they need to be escaped each: no word was > given that doublebackslash "\\" just need one escape character. > So I would expect: > CompositeString Name: "uid=de-dus-mgh-m-02\\\\u0146221" The first backslash does precede a JNDI meta character (another backslash), so it needs to be escaped. The second backslash does not precede a JNDI meta character, so it does not need to be escaped. ###@###.### 2003-08-27
27-08-2003