- 
                Notifications
    You must be signed in to change notification settings 
- Fork 38.8k
Description
Dear Spring developers,
we have found some problematic behaviour of the LDAP functionality in Spring. We are not sure if this is bug or expected or intentional behaviour.
We use following part of code to get LDAP group object and to insert new member:
LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
DirContextOperations ctx = ldapTemplate.lookupContext(lookupDn);
ctx.addAttributeValue("member", args[1]);
ldapTemplate.modifyAttributes(ctx);
In the case there are up to 1500 members in the group, everything works fine. The Spring finds already existing member and skip them in the LDAP modification.
But if there are more then 1500 members in the group, the Windows AD returns the member in the 1500-member batches and the remaining members must be requested using range option, i.e.  member;range=1500-*.
member;range=0-1499
member;range=1500-2999
member;range=3000-4999
etc
But the lookupContext() gets only the first 1500 members and does not make subsequent requests to get the rest members.
If we add new value using addAttributeValue("member",...), Spring checks the attribute name member and takes the attribute member;range=... as different attribute. If the ctx contains following values:
dn: cn=....
member;range=0-1400: cn=user1...
member;range=0-1400: cn=user2...
member;range=0-1400: cn=user3...
and we try to add again member: cn=user1..., then ctx.getModificationItems() returns this member: cn=user1... for LDAP modify.
In the case there are up to 1500 members, the ctx object contains the member attribute without range=...
dn: cn=....
member: cn=user1...
member: cn=user2...
member: cn=user3...
and in this case if we try to add again member: cn=user1..., then ctx.getModificationItems() returns empty array, because Spring sees the cn=user1... in the attribute member.
So first "issue" is, that Spring should check only the attribute name (or AttributeType according to RFC 2849 "The LDAP Data Interchange Format (LDIF) - Technical Specification") and ignore the options. Or remove the options after receiving the object and keep only the attribute name (AttributeType) in the object.
AttributeDescription     = AttributeType [";" options]
But there is still other "issue", that there are only first 1500 values in the attribute. Should Spring's LdapTemplate.lookupContext() should be able to get all values for paged attributes?
I am no java nor spring developer. I have asked chatgpt to create small sample application, which is attached. Just set LDAP parameters in application.properties, compilation with mvn clean compile. Usage with
mvn exec:java -Dexec.args="Group-DN User-DN-to-add update"
Probably you understand how this simple app works, it's really easy - it writes current content of the member attribute and then it tries to add member.
Thank you for your consideration.
Regards,
Robert Wolf.