Description
If the isMemberOf attribute is not completely provisioned, subsequent membership provisionings may incorrectly replace instead of adding attribute values. This bug occurs under certain circumstances related to the number of attribute values to be added.
The offending code is likely in AttributeModifier.java :
public ModificationItem[] getModifications() throws NamingException
...
//
// If everything is being deleted, then build a replacement accordingly
//
if (deletes.size() == deletesCnt) {
In summary : when provisioning memberships, AttributeModifier uses the number of values, not the values themselves, of the currently provisioned attribute to determine whether or not to replace or add/delete values - really not a good idea.
To highlight this issue of ldappc incorrectly provisioning memberships after an incomplete run under 'special' circumstances, I created two groups, each with one and the same member:
groupA
members: subjectA
groupB
members: subjectA
I then provisioned via ldappc :
cn=subjectA
isMemberOf : groupA
isMemberOf : groupB
I then deleted via ldap one of the isMemberOf values :
cn=subjectA
isMemberOf : groupA
After provisioning via ldappc -memberships :
cn=subjectA
isMemberOf : groupB
and again after ldappc -memberships
cn=subjectA
isMemberOf : groupA
ad nauseum.
When provisioning the group whose membership was deleted out-of-band, ldappc will replace instead of adding values. When creating the AttributeModifier, ldappc searches using
(&(uid=*)(isMemberOf=groupB)(objectClass=eduMember))
which will return 0 in this case. Since the AttributeModifier is initialized with 0 entries, AttributeModifier.deletes is empty and AttributeModifier.deletesCnt = 0, and AttributeModifier.adds contains 1 item, cn=subjectA. Then, since 'if (deletes.size == deletesCnt)' evaluates to true in AttributeModifier.getModifications(), attribute values are replaced !