Closed rwinch closed 8 years ago
nate_moser said: The subclass of org.springframework.ldap.core.support.DefaultDirObjectFactory that strips LDAP URLs from DNs returned when JNDI follows referrals.
marthursson said: Trying to create a test case for this I'm running into some ambiguities: it seems that creating a {{CompositeName}} using the string {{ldap://localhost:389/ou=People,o=JNDITutorial}} (i.e. {{new CompositeName("ldap://localhost:389/ou=People,o=JNDITutorial"}})results in a an instance with not one, but four parts. Could you just verify for me that you are indeed receiving a {{CompositeName}} with one part only (i.e. that {{name.get(0)}} on the instance handed from JNDI gives you the full string representing the referral)?
nate_moser said: That's worrying for my implementation... with OpenLDAP I'm indeed getting the whole
name = {javax.naming.CompositeName@1297}"cn=jamesB,ou=QA,dc=example,dc=com" impl = {javax.naming.NameImpl@1560}"cn=jamesB,ou=QA,dc=example,dc=com" components = {java.util.Vector@1564} size = 1 [0] = {java.lang.String@1298}"cn=jamesB,ou=QA,dc=example,dc=com"
for an entry from the original directory, and
name = {javax.naming.CompositeName@1308}"\"ldap://server2.example.com:389/cn=user1,ou=ou1,dc=example,dc=com\"" impl = {javax.naming.NameImpl@1552}"\"ldap://server2.example.com:389/cn=user1,ou=ou1,dc=example,dc=com\"" components = {java.util.Vector@1556} size = 1 [0] = {java.lang.String@1309}"ldap://server2.example.com:389/cn=user1,ou=ou1,dc=example,dc=com"
for an entry coming from a referral, so name.get(0) gets the whole String in either case.
I'm seeing the same results for SunONE and AD referrals. I haven't set up OpenLDAP using the LDIF from the JNDI tutorial, though, so I'll give that a try.
Also, I'm using
org.springframework.ldap.core.LdapTemplate#search(String base, String filter, SearchControls controls, ContextMapper mapper)
so perhaps the use of ContextMapper is a factor? I'd certainly prefer it to work with all LdapTemplate methods.
marthursson said: I'm doing a pure unit test against {{DefaultDirObjectFactory}} here, so I think it's the construction of the {{CompositeName}} that is the problem (I'm constructing it manually in my test case).
Actually I think your results are quite reassuring. In my test case I was creating the {{CompositeName}} instance passing the string directly to the constructor. I'm sure the JNDI code is doing it differently; at least your tests indicate that's the case.
I'll try to get this in place for you to test the real thing tomorrow.
marthursson said: This is now fixed in the trunk. I decided against using regular expressions as we've previously had severe performance hits caused by using these.
Also, it didn't feel right to just discard the referral information, so I decided to add that information to {{DirContextAdapter}}. If an instance of {{DirContextAdapter}} is created with referral information (which will now be the case if it is created by {{DefaultDirObjectFactory}} and the {{Name}} contains referral information) the referral server url will be accessible using {{DirContextAdapter#getReferralUrl}} and {{DirContextAdapter.isReferral}} methods.
rodrigo.dinis said: Yes, it sounds like the issue I am having. But I don't know how to implement the change. Could someone clarify how to build the solution?
Original Reporter: nate_moser Environment: I'm using spring-ldap-1.2.1, issue should be OS and platform independent Version: 1.2.1 Migrated From: https://jira.spring.io//browse/LDAP-136 In order to follow referrals, I'm using LdapContextSource with env.put(Context.REFERRAL, "follow"); ctx.setBaseEnvironmentProperties(env);
when a search includes results from following a referral, I get a exception
Caused by: org.springframework.ldap.BadLdapGrammarException: Failed to parse DN; nested exception is org.springframework.ldap.core.TokenMgrError: Lexical error at line 1, column 5. Encountered: ":" (58), after : "" at org.springframework.ldap.core.DistinguishedName.parse(DistinguishedName.java:145) at org.springframework.ldap.core.DistinguishedName.(DistinguishedName.java:100)
at org.springframework.ldap.core.DirContextAdapter.(DirContextAdapter.java:139)
at org.springframework.ldap.core.support.DefaultDirObjectFactory.getObjectInstance(DefaultDirObjectFactory.java:61)
at javax.naming.spi.DirectoryManager.createObjectFromFactories(Unknown Source)
at javax.naming.spi.DirectoryManager.getObjectInstance(Unknown Source)
Setting a breakpoint at DirContextAdapter shows that the DN in question is prefixed with the LDAP URL for the referred-to LDAP server. Apparently that's how JNDI prefixes results returned from followed referrals, see http://java.sun.com/products/jndi/tutorial/ldap/referral/follow.html
At Mattias' suggestion, I subclassed DefaultDirObjectFactory and was able to work around the situation by stripping of the LDAP URL prefix. This could conceivably lead to namespace collision if a referred-to server has the same DIT structure as the original server (e.g., they both have a cn=nate,ou=users,dc=example,dc=com entry), but a situation the directory administrator should resolve.
I've tested this with searches Active Directory 2003, SunONE, and OpenLDAP servers with a single-hop referral to another server.