-
Bug
-
Resolution: Not an Issue
-
P4
-
None
-
5.0u12
-
sparc
-
solaris_2.5.1
Steps to Reproduce:
1. Create a LDIF file with the following entries.
dn: cn="+srg1user,;=\;%\+_3",,cn=Users, o=ACME1,dc=com
cn: "+srg1user,;=\;%\+_3"
objectClass:top
objectClass:person
sn:srg1user3_sn
dn: cn=\+srg2user\,\;\=\\\;\%\\\+\_4,,cn=Users, o=ACME1,dc=com
cn: "+srg1user,;=\;%\+_4"
objectClass:top
objectClass:person
sn:srg2user4_sn
2. Perform ldapadd Oracle Internet Directory or SunOne Directory server and add the entries.
3. Perform a ldapsearch to make sure the entries got created correctly.
Ldapsearch -h <LDAPhost> -p <LDAPPort> -D <dn> -w <pwd> -b "cn=users, o=acme1,dc=com" -s sub "objectclass=*"
4. Create a Java class as below:
import java.io.PrintStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import javax.naming.CommunicationException;
import javax.naming.CompositeName;
import javax.naming.CompoundName;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.Attribute;
import javax.naming.directory.AttributeModificationException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.InvalidAttributesException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.LdapName;
// in case of JDK1.5 uncomment this
//import javax.naming.ldap.Rdn;
public class TrialSpecialChar{
protected static Vector mAttrValue = new Vector();
// A table with compound name syntax properties
static Properties nameSyntax;
static StringBuffer strBuf = new StringBuffer();
static {
nameSyntax = new Properties();
nameSyntax.put("jndi.syntax.direction", "right_to_left");
nameSyntax.put("jndi.syntax.separator", ",");
nameSyntax.put("jndi.syntax.ignorecase", "true");
nameSyntax.put("jndi.syntax.escape", "\\");
nameSyntax.put("jndi.syntax.beginquote", "\"");
nameSyntax.put("jndi.syntax.trimblanks", "true");
nameSyntax.put("jndi.syntax.separator.ava", "+");
nameSyntax.put("jndi.syntax.separator.typeval", "=");
}
public static void modifyEntry(DirContext ctx) throws NamingException{
String dn = null;
SearchControls sc = new SearchControls();
SearchResult sr = null;
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
sc.setReturningAttributes(new String[] {"orclGuid"});
//NamingEnumeration<SearchResult> res = null;
NamingEnumeration res = null;
System.out.println("Result");
try{
//this is used to get the DN from the orclGUID.
res = ctx.search("cn=Users, o=ACME1,dc=com","(sn =srg1user3_sn)",sc);
if(res == null) {
System.out.println("Nilesh no dn");
}
}catch(Exception e){
System.out.println("There is an Exception!!!!!!!!!");
e.printStackTrace();
}
//this code snippet does not work for Java 1.5 as the getName functions in Java 1.5 returns an escaped value always.
// Irrespective of the way it has been added to the DS meaning escaped or with double quotes.
// Whereas In Java 1.4 the getName returns the RDN in the fashion it was entered in the DS
// eg : returns RDN that is escaped if it was added in that fashion or
//returns the RDN in double quotes if it was added that way
while(res!=null && res.hasMore()){
sr = (SearchResult)res.next();
try{
Attributes ret = ctx.getAttributes(sr.getName() + ",cn=Users, o=ACME1,dc=com",new String [] {"cn"});
NamingEnumeration nme = ret.getAll();
while(nme.hasMore()){
System.out.println(nme.next());
}
}catch(Exception e){
e.printStackTrace();
}
}
//also tried other methods to return the RDN as done by getName in Java 1.4
//here LDAPName and Composite Name do not work for special characters as they return the entire DN
// when you try to extract RDN by using get(0) API
Name entryName = new CompoundName(sr.getNameInNamespace(), nameSyntax);
Name rdnName = new CompoundName(sr.getName(),nameSyntax);
System.out.println(" compund rdn by getName" + rdnName);
System.out.println(" RDN by getNameInNameSpace " + entryName.get(entryName.size() - 1));
}
public static void main(String[] args) throws NamingException {
LdapContext ctx = null;
try{
//Hashtable<String, String> props = new Hashtable();
Hashtable props = new Hashtable();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put("com.sun.jndi.ldap.trace.ber", System.out);
props.put(Context.PROVIDER_URL, "ldap://stacq32:3060");
props.put(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
props.put(Context.REFERRAL, "ignore");
props.put(Context.SECURITY_AUTHENTICATION, "simple");
// --------------------------------------------------
//specify the root username
// --------------------------------------------------
props.put(Context.SECURITY_PRINCIPAL, "cn=orcladmin");
//--------------------------------------------------
//specify the root password
// --------------------------------------------------
props.put(Context.SECURITY_CREDENTIALS, "welcome1");
//--------------------------------------------------
// Get the environment properties (props) for creating initial
// context and specifying LDAP service provider parameters.
//--------------------------------------------------
ctx = new InitialLdapContext(props,null);
}catch(CommunicationException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
System.out.println("Caught here");
}
try{
modifyEntry(ctx);
}catch(Exception e){
System.out.println("Attribute modify problem");
e.printStackTrace();
}
}
}
5. Modify the class to specify the correct LDAP host/Port details.
6. Compile and run the class using JDK 1.4. It works fine.
7. Compile and run the class using JDK 1.5. There is a exception.
8. Modify the code and replace the 'srg1user3_sn' with srg2user4_sn.
9. Compile and run the class using JDK 1.4. It works fine.
10. Compile and run the class using JDK 1.5. It works fine.
So, this causes a problem based on how the 'dn' is created. Since the 'dn' creation can happen in anyway, it is mandatory that the JDK handles the difference correctly.
Release Regression From : 1.4.2_11
The above release value was the last known release where this
bug was not reproducible. Since then there has been a regression.
Oracle has escalated this bug. However, there is a problem with Sun IT supported escalation tool since this morning. As soon as the escalation tool is fixed, an escalation will be opened against this CR. Please evaluate this bug asap and work on a solution.
More update from the customer:
The problem is getName() and getNameInNameSpace() are not returning
consistent results when the entries are created with special characters
in escape sequences.
The test program used is attached herewith. JNDITest.java.
Here is what the program does.
1) Connect to the directory with the given host, port & credentials
2) Search for an entry in the given container with the given sn value.
3) from the searchresult, call the getName() API to get the 'rdn'
value of the entry.
4) Construct the 'dn' of the entry using the container name.
5) perform getattributes to see, if the constructed 'dn' can be used
to find the entry again in the directory.
6) from the searchresult of step 2, call getNameInNameSpace() to get
the 'dn' of the entry.
7) Perform getAttributes to see if you are able to get the entry
based on the 'dn' value received from Step 6.
There are two sample user entries created with 'dn' having 'escape'
sequences and 'dn' not having the rdn value specified in 'quote'.
When the values are specified using 'quotes' as in the user
'srg1user3_sn' the value returned by getName and the rdn value of
getNameInNameSpace are consistent. So, the result returned in step 5 & 7
are the same. When the values are specified using escape sequences as in
'srg2user4_sn' the value returned by getName and the rdn value of
getNameInNameSpace are not consistent.
Execute it as below:
java jnditest.JNDITest <host> <port> <DN> <PWD> <container> <snvalue>
the sample entries which do and do not produce consistent results are
attached in ipluser.ldif file.
1. Create a LDIF file with the following entries.
dn: cn="+srg1user,;=\;%\+_3",,cn=Users, o=ACME1,dc=com
cn: "+srg1user,;=\;%\+_3"
objectClass:top
objectClass:person
sn:srg1user3_sn
dn: cn=\+srg2user\,\;\=\\\;\%\\\+\_4,,cn=Users, o=ACME1,dc=com
cn: "+srg1user,;=\;%\+_4"
objectClass:top
objectClass:person
sn:srg2user4_sn
2. Perform ldapadd Oracle Internet Directory or SunOne Directory server and add the entries.
3. Perform a ldapsearch to make sure the entries got created correctly.
Ldapsearch -h <LDAPhost> -p <LDAPPort> -D <dn> -w <pwd> -b "cn=users, o=acme1,dc=com" -s sub "objectclass=*"
4. Create a Java class as below:
import java.io.PrintStream;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Vector;
import javax.naming.CommunicationException;
import javax.naming.CompositeName;
import javax.naming.CompoundName;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import javax.naming.directory.Attribute;
import javax.naming.directory.AttributeModificationException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.InvalidAttributesException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.LdapName;
// in case of JDK1.5 uncomment this
//import javax.naming.ldap.Rdn;
public class TrialSpecialChar{
protected static Vector mAttrValue = new Vector();
// A table with compound name syntax properties
static Properties nameSyntax;
static StringBuffer strBuf = new StringBuffer();
static {
nameSyntax = new Properties();
nameSyntax.put("jndi.syntax.direction", "right_to_left");
nameSyntax.put("jndi.syntax.separator", ",");
nameSyntax.put("jndi.syntax.ignorecase", "true");
nameSyntax.put("jndi.syntax.escape", "\\");
nameSyntax.put("jndi.syntax.beginquote", "\"");
nameSyntax.put("jndi.syntax.trimblanks", "true");
nameSyntax.put("jndi.syntax.separator.ava", "+");
nameSyntax.put("jndi.syntax.separator.typeval", "=");
}
public static void modifyEntry(DirContext ctx) throws NamingException{
String dn = null;
SearchControls sc = new SearchControls();
SearchResult sr = null;
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
sc.setReturningAttributes(new String[] {"orclGuid"});
//NamingEnumeration<SearchResult> res = null;
NamingEnumeration res = null;
System.out.println("Result");
try{
//this is used to get the DN from the orclGUID.
res = ctx.search("cn=Users, o=ACME1,dc=com","(sn =srg1user3_sn)",sc);
if(res == null) {
System.out.println("Nilesh no dn");
}
}catch(Exception e){
System.out.println("There is an Exception!!!!!!!!!");
e.printStackTrace();
}
//this code snippet does not work for Java 1.5 as the getName functions in Java 1.5 returns an escaped value always.
// Irrespective of the way it has been added to the DS meaning escaped or with double quotes.
// Whereas In Java 1.4 the getName returns the RDN in the fashion it was entered in the DS
// eg : returns RDN that is escaped if it was added in that fashion or
//returns the RDN in double quotes if it was added that way
while(res!=null && res.hasMore()){
sr = (SearchResult)res.next();
try{
Attributes ret = ctx.getAttributes(sr.getName() + ",cn=Users, o=ACME1,dc=com",new String [] {"cn"});
NamingEnumeration nme = ret.getAll();
while(nme.hasMore()){
System.out.println(nme.next());
}
}catch(Exception e){
e.printStackTrace();
}
}
//also tried other methods to return the RDN as done by getName in Java 1.4
//here LDAPName and Composite Name do not work for special characters as they return the entire DN
// when you try to extract RDN by using get(0) API
Name entryName = new CompoundName(sr.getNameInNamespace(), nameSyntax);
Name rdnName = new CompoundName(sr.getName(),nameSyntax);
System.out.println(" compund rdn by getName" + rdnName);
System.out.println(" RDN by getNameInNameSpace " + entryName.get(entryName.size() - 1));
}
public static void main(String[] args) throws NamingException {
LdapContext ctx = null;
try{
//Hashtable<String, String> props = new Hashtable();
Hashtable props = new Hashtable();
props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
props.put("com.sun.jndi.ldap.trace.ber", System.out);
props.put(Context.PROVIDER_URL, "ldap://stacq32:3060");
props.put(Context.URL_PKG_PREFIXES, "com.sun.jndi.url");
props.put(Context.REFERRAL, "ignore");
props.put(Context.SECURITY_AUTHENTICATION, "simple");
// --------------------------------------------------
//specify the root username
// --------------------------------------------------
props.put(Context.SECURITY_PRINCIPAL, "cn=orcladmin");
//--------------------------------------------------
//specify the root password
// --------------------------------------------------
props.put(Context.SECURITY_CREDENTIALS, "welcome1");
//--------------------------------------------------
// Get the environment properties (props) for creating initial
// context and specifying LDAP service provider parameters.
//--------------------------------------------------
ctx = new InitialLdapContext(props,null);
}catch(CommunicationException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
System.out.println("Caught here");
}
try{
modifyEntry(ctx);
}catch(Exception e){
System.out.println("Attribute modify problem");
e.printStackTrace();
}
}
}
5. Modify the class to specify the correct LDAP host/Port details.
6. Compile and run the class using JDK 1.4. It works fine.
7. Compile and run the class using JDK 1.5. There is a exception.
8. Modify the code and replace the 'srg1user3_sn' with srg2user4_sn.
9. Compile and run the class using JDK 1.4. It works fine.
10. Compile and run the class using JDK 1.5. It works fine.
So, this causes a problem based on how the 'dn' is created. Since the 'dn' creation can happen in anyway, it is mandatory that the JDK handles the difference correctly.
Release Regression From : 1.4.2_11
The above release value was the last known release where this
bug was not reproducible. Since then there has been a regression.
Oracle has escalated this bug. However, there is a problem with Sun IT supported escalation tool since this morning. As soon as the escalation tool is fixed, an escalation will be opened against this CR. Please evaluate this bug asap and work on a solution.
More update from the customer:
The problem is getName() and getNameInNameSpace() are not returning
consistent results when the entries are created with special characters
in escape sequences.
The test program used is attached herewith. JNDITest.java.
Here is what the program does.
1) Connect to the directory with the given host, port & credentials
2) Search for an entry in the given container with the given sn value.
3) from the searchresult, call the getName() API to get the 'rdn'
value of the entry.
4) Construct the 'dn' of the entry using the container name.
5) perform getattributes to see, if the constructed 'dn' can be used
to find the entry again in the directory.
6) from the searchresult of step 2, call getNameInNameSpace() to get
the 'dn' of the entry.
7) Perform getAttributes to see if you are able to get the entry
based on the 'dn' value received from Step 6.
There are two sample user entries created with 'dn' having 'escape'
sequences and 'dn' not having the rdn value specified in 'quote'.
When the values are specified using 'quotes' as in the user
'srg1user3_sn' the value returned by getName and the rdn value of
getNameInNameSpace are consistent. So, the result returned in step 5 & 7
are the same. When the values are specified using escape sequences as in
'srg2user4_sn' the value returned by getName and the rdn value of
getNameInNameSpace are not consistent.
Execute it as below:
java jnditest.JNDITest <host> <port> <DN> <PWD> <container> <snvalue>
the sample entries which do and do not produce consistent results are
attached in ipluser.ldif file.