Results 1 to 10 of 12

Thread: Serious bug in DirContextAdaptor?

Hybrid View

  1. #1
    Join Date
    Sep 2006
    Posts
    5

    Default Serious bug in DirContextAdaptor?

    I'm getting the following behavior using Active Directory (Win2k Server):

    When I change an existing multi-valued attribute, for example, removing an item or adding an item, when a value already exists, I get (ATT_OR_VALUE_EXISTS) with the attribute that it tried to modify.

    As near as I can tell, this is because for some reason DirContextAdaptor.collectModifications(Attribute, List) calls collectModifications(DirContext.ADD_ATTRIBUTE, etc...) before collectModifications(DirContext.REMOVE_ATTRIBUTE, etc...)

    Basically, it's generating the ModificationItems in the wrong order, attempting to add the new attribute before removing the old one. When I reverse the order of the statements, it appears to work correctly.

    I'm not really sure where to post bug reports for this, since it appears that there is no JIRA module set up for Spring-LDAP. Maybe someone can point me to the right place to be posting this?

  2. #2
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    Until we have a JIRA space for Spring LDAP, this is the correct forum for any issues. We'll look into your problem.
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

  3. #3
    Join Date
    Mar 2005
    Location
    Landskrona, Sweden
    Posts
    505

    Default

    It does seem like something is not functioning correctly, but the order of the ModificationItems really shouldn't matter - if the attribute value is already there, no ADD_ATTRIBUTE operation for that value should be generated.

    Anyway, we need to look into it. A code example would be helpful in tracking down the problem.
    Last edited by rasky; Sep 12th, 2006 at 02:32 PM.
    Mattias Arthursson
    Jayway AB (www.jayway.se)
    Spring-LDAP project member

  4. #4
    Join Date
    Sep 2006
    Posts
    5

    Default Well...

    Well, if you read the javadocs and the comments in DirContextAdaptor you will see that it says: "Otherwise, the attribute is a multi-value attribute, in which case all modifications to the original value (removals and additions) will be collected individually."

    So, it seems to be following the strategy that it mentions, except that it does the ADD and REMOVE in the wrong order. The order of the ModificationItems is indeed significant, since reversing them produces the correct result. Unless you meant something else when you said the order of the modifications shouldn't matter?

    I don't have any sample code that I can share at the moment, since it's embedded quite deeply into another framework at the moment. In a nutshell, though, I am mapping a POJO to the ldap template using mapToContext and a custom ContextMapper. When I map a modified POJO back to the context, it calls context.setAttributeValues to set the multi-valued attribute, and then, ldapTemplate.modifyAttributes(dn, context.getModificationItems()). When modifyAttributes is called with the ModificationItems currently produced by getModificationItems(), Active Directory complains. When the order of the ModificationItems is reversed, it works fine.

  5. #5
    Join Date
    Mar 2005
    Location
    Landskrona, Sweden
    Posts
    505

    Default

    While the order of the ModificationItems is indeed the order in which the actual modification takes place, making it significant in the general case, I would like to argue that it really shouldn't matter in this particular case.

    I'm unable to reproduce your problem (I'm running against Apache Directory Server, which shouldn't make a difference, but admittedly Active Directory has been known to behave strangely on occations).

    If I understand your problem correctly your code is similar to the following test, which works just fine for me:
    Code:
    protected void onSetUp() throws Exception {
        DirContextAdapter adapter = new DirContextAdapter();
        adapter.setAttributeValues("objectclass", new String[] { "top",
                "person" });
        adapter.setAttributeValue("cn", "Some Person5");
        adapter.setAttributeValue("sn", "Person5");
        adapter.setAttributeValues("description", new String[ {"qwe", "123", "rty", "uio"});
    
        ldapTemplate.bind(PERSON5_DN, adapter, null);        
    }
    
    public void testModifyAttributes_DirContextAdapter_MultiAttributes(){
        DirContextAdapter adapter = (DirContextAdapter) ldapTemplate.lookup(PERSON5_DN);
        adapter.setAttributeValues("description", new String[]{"qwe", "123", "klytt", "kalle"});
            
        ldapTemplate.modifyAttributes(PERSON5_DN, adapter.getModificationItems());
            
        // Verify
        adapter = (DirContextAdapter) ldapTemplate.lookup(PERSON5_DN);
        String[] attributes = adapter.getStringAttributes("description");
        assertEquals(4, attributes.length);
        assertEquals("qwe", attributes[0]);
        assertEquals("123", attributes[1]);
        assertEquals("klytt", attributes[2]);
        assertEquals("kalle", attributes[3]);
    }
    The getModificationItems() above produces two ModificationItems:
    * ADD_ATTRIBUTE with BasicAttribute("description") and the values "klytt" and "kalle".
    * REMOVE_ATTRIBUTE with BasicAttribute("description") and the values "rty" and "uio".

    Since no Attribute value already present is added the order of the ModificationItems shouldn't matter in this case.

    Mabe it would help if you inspected the ModificationItems to see what is actually returned from getModificationItems(). If we can determine that the order does indeed matter due to some particular feature (defect?) in Active Directory we will of course change it, but I'd like to make sure we are actually chasing the correct problem.
    Mattias Arthursson
    Jayway AB (www.jayway.se)
    Spring-LDAP project member

  6. #6
    Join Date
    Sep 2006
    Posts
    5

    Default DNs and case sensitivity

    It appears the reason why this is happening is that DistinguishedName forces all RDN keys to lowercase, while active directory always seems to return keys in uppercase. My multi-valued attribute is a DN, so what is happening is that the DN as stored in my mapped object is returning lowercase keys when 'toString()' is called on it, while the version being compared from the context when doing an update is coming through with uppercase keys. This is causing it to be confused and generating the wrong ModificationItems.

    I really wish there was special handling for DNs in the DirContextAdaptor so that this wouldn't happen. I suppose for now I'll have to modify my mapToContext method to normalize the case of the RDN keys before passing them to the context. Thanks for your help with tracking this issue down.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •