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
%
- duplicates
-
JDK-6201615 LDAP Service Provider does not parse LDAP names with escape characters ('\') properly.
- Closed
- relates to
-
JDK-4892070 java gets hung in com.sun.jndi.ldap.LdapName$TypeAndValue.unescapeValue()
- Resolved
-
JDK-6201517 javax.naming.CompositeName and javax.naming.CompoundName handle escape character ('\') incorrectly.
- Closed