Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ODM for a group with lot of members are not fetched correctly #561

Open
susil opened this issue Jun 25, 2020 · 9 comments
Open

ODM for a group with lot of members are not fetched correctly #561

susil opened this issue Jun 25, 2020 · 9 comments

Comments

@susil
Copy link

susil commented Jun 25, 2020

Hi
I have Group ODM class as below:

`
@entry(objectClasses = { "group", "top" }, base = "OU=group")

public final class ADGroup implements Serializable {

 private static final long serialVersionUID = 915331212576640803L;
 
@Id
private Name dn;

@Attribute(name = "cn")
@DnAttribute(value="cn", index=1)
private String name;

@Attribute(name = "member")
private Set<Name> members;

public Name getDn() {
    return dn;
}

public void setDn(Name dn) {
    this.dn = dn;
}

public Set<Name> getMembers() {
    return members;
}

public void setMembers(Set<Name> members) {
    this.members = members;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public void addMember(Name member) {
    members.add(member);
}

public void removeMember(Name member) {
    members.remove(member);
}

}`

When I get this ODM class using the ldapTempalte as below

`
ADGroup adGuest = aDldapTemplate.findOne(query().where("cn").is("MyGroup"), ADGroup.class);
Set members = adGuest.getMembers();
log.info("members.size()="+members.size());

`
I see the ODM class mapped to AD group correctly and when I turn on log to trace level I do see member accounts which comes in as

{member;range=0-1499[0]=CN=abc1....,member;range=0-1499[1]=CN=abc2 ....until, member;range=0-1499[1499]=CN=abc1499

I understand this due to set count limit set on Active Directory that only allows certain count of members. And when this happens, "member" attribute is not correctly mapped and "adGuest.getMembers();" does not show the correct count of (1500 ) but just shows 0.

I do not want to change AD bind setting to get all the data at once because it could be huge, but I do want to be able to run pageable like option to get all the records. When I tested this with group with smaller number of members (,1500), it worked just fine, giving the right count and member info as well.

So question is;
Is there a way make this pageable like query and fetch all the records ? If so how to do this. Is there some annotation that I need to provide in ODM class itself or is that done in aDldapTemplate.findOne like call. It will be great to get some insight on this with code snippet to do this.

Thank you in advance
Su

@susil
Copy link
Author

susil commented Jul 23, 2020

Hi All,
Any help/idea on this will be highly appreciated.

Thanks
Su

@jbazp
Copy link

jbazp commented Jun 14, 2021

I have the same problem. @susil, Did you fix it?

@enzolcastro
Copy link

same problem!!!!!! any ideas?

@enzolcastro
Copy link

member;range=0-1499[1499]

@enzolcastro
Copy link

i have 25000 records....

@jbazp
Copy link

jbazp commented Feb 17, 2022

In the spring-data project there is a test that gets more than 1500 values ​​of an attribute. I used that test as a reference and it worked for me: https://github.com/spring-projects/spring-ldap/blob/main/test/integration-tests-ad/src/test/java/org/springframework/ldap/itest/ad/IncrementalAttributeMapperITest.java#L153

 protected IncrementalAttributesMapper<DefaultIncrementalAttributesMapper> getDefaultIncrementalAttributesMapper() {
        return new DefaultIncrementalAttributesMapper(new String[] { "member", "cn" });
 }

protected ArrayList<String> retrievalALotOfAttributeValues(Name dn) {
        var result = new ArrayList<String>();
        final var ctx = ldapTemplate.lookupContext(dn);
        if (ctx.getStringAttribute("member") == null) {
            var attributeMapper = getDefaultIncrementalAttributesMapper();

            while (attributeMapper.hasMore()) {
                attributeMapper = ldapTemplate.lookup(dn, attributeMapper.getAttributesForLookup(), attributeMapper);
            }

            final var memberValues = attributeMapper.getValues("member");
            if (memberValues != null) {
                result = (ArrayList<String>) memberValues.stream().map(object -> object.toString()).collect(Collectors.toList());
            }
        }
        return result;
    }

@enzolcastro
Copy link

I need remove an user (i have the DN) from a Group with 25790 members. So this work for that? obviusly i need to write the code for ldaptemplate.modify

@fishbone1
Copy link

Could this be the reason why addIfDuplicateExists argument doesn't work correctly? Our code looks similar to this:

DirContextOperations dirContextOperations = ldapTemplate.lookupContext(groupDn);
boolean addIfDuplicateExists = false;
dirContextOperations.addAttributeValue("member", userDn, addIfDuplicateExists);
ldapTemplate.modifyAttributes(dirContextOperations);

It works for all groups except one group with more than 1500 members´, which causes following exception:

org.springframework.ldap.AttributeInUseException: (...)
0: 00002083: DSID-03151F38, problem 1006 (ATT_OR_VALUE_EXISTS), data 0, Att 1f (member):len 188
(...)

@jbazp If the test/mock LDAP server has no value count limit for multi value attributes the integration test will be successful even if the problem exists.

We can also see the limit in our LDAP tool. Where other groups' attribute is called "member", it's called "member;range=0-1499" for this one group with more than 1500 members.

@fishbone1
Copy link

@jbazp Ah I misunderstood your comment with the integration test. I thought you are saying that it should work as expected because the test would fail otherwise. But instead the test contains the solution. I wonder why this isn't the default behavior. I try to adapt this for my case with addIfDuplicateExists

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants