Spring ldaptemplate unable to delete attribute with multiple values

154 Views Asked by At

I want to delete attribute with multiple values but it ignores this while successfully deletes another attribute with specific value in directory.

Attribute attr1 = new BasicAttribute("fooAttr");
ModificationItem attr1mod = new 
ModificationItem(DirContext.REMOVE_ATTRIBUTE,attr1);
Attribute attr2 = new BasicAttribute("barAttr","my value");
ModificationItem attr2mod = new 
ModificationItem(DirContext.REMOVE_ATTRIBUTE,attr2);
try{ 
    ldapTemplate.modifyAttributes("cn=myname,dc=example,dc=com", new 
    ModificationItem[]{attr1mod, attr2mod});
    } catch(Exception e) {
    // 
}

barAttr is deleted with the specified value but multivalued fooAttr is not deleted.

barAttr is also multivalued and the specified value is deleted. I also tried to delete a specified value of fooAttr and still it failed to delete the specified value of fooAttr. I confirmed externally that fooAttr exists in the directory.

ldapTemplate.modifyAttributes executes successfully, does not throw exception.

If I do this:

ldapTemplate.modifyAttributes("cn=myname,dc=example,dc=com", new 
    ModificationItem[]{attr1mod});

then in this case exception is thrown:

LDAP: error code 16 - Failed to modify the underlying source: No such attribute

UPDATE I also tried this approach:

DirContextOperation context = ldaptemplate.lookup(dn);
String [] fooAttrValues = context.getStringAttributes("fooAttr");

for(String value : fooattrValues) {
  context.removeAttributeValue("fooAttr", value);
}
String [] fooAttrValues2 = context.getStringAttributes("fooAttr");

This does not work, after program is run the director still has the same attribute and all the values. I debugged through it, it does get the correct values but does not remove any value, even fooAttrValues2 still has all the values.

How can I fix this problem?

2

There are 2 best solutions below

5
Freeman On

I think to delete specific attribute values, you better to use the DirContext.REMOVE_ATTRIBUTE flag for each value individually, right now, you are using DirContext.REMOVE_ATTRIBUTE flag for both attributes attr1 and attr2 in your code and it used to remove the entire attribute, not specific attribute values!

something like this:

Attribute attr1 = new BasicAttribute("fooAttr", "value1"); 
ModificationItem attr1mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr1);

Attribute attr2 = new BasicAttribute("barAttr", "my value"); 
ModificationItem attr2mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, attr2);

try {
    ldapTemplate.modifyAttributes("cn=myname,dc=example,dc=com", new ModificationItem[]{attr1mod, attr2mod});
} catch (Exception e) {
    //here handle your exceptions
}

Update
and also, instead of using the REMOVE_ATTRIBUTE,you can try using the REPLACE_ATTRIBUTE with the modified list of values for fooAttr.it involves retrieving the existing attribute values, removing the specific value you want to delete, and then using REPLACE_ATTRIBUTE to update fooAttr with the modified list!

ModificationItem attr1mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE, new BasicAttribute("fooAttr"));

//removing a specific value of the multi-valued attribute
ModificationItem attr2mod = new ModificationItem(DirContext.REMOVE_ATTRIBUTE | DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("barAttr", "my value"));

ldapTemplate.modifyAttributes("cn=myname,dc=example,dc=com", new ModificationItem[]{attr1mod, attr2mod});
0
Krishan Saini On

First things first, have you checked if youve got the right permissions to mess with fooAttr? Sometimes LDAP can be a bit sneaky like that, and it doesn't let just anyone tweak everyhting.

Also, there might be some quirky rules set in teh LDAP schema. Like, maybe, it's mandatory for fooAttr to always have somevalue? Worth a look.

We can try updating the code as below:

DirContextOperations context = ldapTemplate.lookupContext("cn=myname,dc=example,dc=com");
List<String> currentValues = new ArrayList<>(Arrays.asList(context.getStringAttributes("fooAttr")));

for (String val : new ArrayList<>(currentValues)) {
    currentValues.remove(val);
    context.setAttributeValues("fooAttr", currentValues.toArray(new String[0]));
}

ldapTemplate.modifyAttributes(context);

A heads up, if things still act weird, try turning on debug mode for Spring LDAP. Might catch something fishy there. You can also dive deep and try to make a few changes straight on LDAP server using command line.

Hope this helps. Finger crossed.