Announcement Announcement Module
Collapse
No announcement yet.
[spring-ldap 1.2.1] issue (bug?) with modifyAttributes Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • [spring-ldap 1.2.1] issue (bug?) with modifyAttributes

    I have found the following issue with modifyAttributes:

    Use case is a basic user/role relationship where we want to update the list of users that have been assigned to a role. A role has the following structure in our system, where values in <angle brackets> are variable:

    objectClass: groupOfUniqueNames
    objectClass: top
    cn: <ROLE_NAME>
    uniqueMember: <DN of a user>
    uniqueMember: <optional DN of another user>
    ...
    description: <optional description>

    Since a groupOfUniqueNames must have at least one uniqueMember, the following use case pseudo code fails for us:

    1) retrieve an existing role using the role DN
    2) convert to a role domain object using a context mapper
    3) update the list of uniqueMember (users) to a completely different set of users from the original using DirContextOperations.setAttributeValues("uniqueMem ber", newMembers)
    4) call ldapTemplate.modifyAttributes
    5) watch a completely (now explainable) bogus SchemaViolationException get thrown

    The problem is that (I believe) the spring-ldap code deletes all the uniqueMember entries before adding the new ones, so the SchemaViolationException is thrown because you can't have zero uniqueMembers.

    Note: the SchemaViolationException is not thrown when at least one of the new users is the same as one that already exists for the role.

    What (I believe) needs to happen is that more logic needs to be applied under the covers when the multi-attribute being modified is a required attribute, such that the zero value condition is not reached. A suggested approach might be to do set compares (old values vs new values) and add new (non-existing) ones first, then delete obsolete (existing, but not in new set) attribute values.

    I am hopeful I've described this well enough for a contributor to reproduce. I am behind in my project, so need to write some work-around code first rather than debug the spring-ldap stuff. But, if the spring-ldap gurus won't be getting to this soon, I could look at fixing this later this week or next week. If necessary, I will boil this down to a simple test case that shows the problem.

    I'll do what I can to help squash this thing, but have to get some working code first, so others who are waiting on me can get going again...

    Rich

  • #2
    Right, I think I understand the problem. This case actually never occurred to me. The DirContext javadocs for modifyAttributes states that "Where possible, the modifications are performed atomically". I'd guess this is one of the cases where it's not possible.

    We do put the REMOVE_ATTRIBUTE modification items first, and there's actually a very good reason for this (it was the other way around before): the jira issue is here. In short, the attribute value comparison is not always to be trusted: we're delegating to Attribute.contains(), which should theoretically take syntactic attribute value equality into account, but unfortunately it does not, particularly in the case of distinguished names. E.g.: the attribute value
    "cn=John Doe, ou=company" (with a space between the relative dns)
    will be considered different from
    "cn=John Doe,ou=company"
    causing one REMOVE_ATTRIBUTE item and one ADD_ATTRIBUTE item. Putting the ADD_ATTRIBUTE item first will cause some LDAP servers to complain that there's a duplicate attribute value (since the values are actually syntactically equal).

    Bottom line: we need to figure something else out here. I'm not sure how to go about it, but it's clear that neither of these approaches are sufficient: the operation is clearly not atomically performed and having the ADD_ATTRIBUTE or REMOVE_ATTRIBUTE items first will both cause problems in different cases.

    Please raise a jira issue and we'll take this into account for the upcoming release.

    Comment


    • #3
      new JIRA raised

      I raised JIRA issue LDAP-119, but I can't put a link here due to just creating a new JIRA account. So, copy/paste the following to your favorite browser address bar:
      jira.springframework.org/browse/LDAP-119
      I hope I entered enough of a description to go on. Thanks for your attention to this.

      BTW, I do have my own workaround in place, but it took me a couple tries due to not understanding the underpinnings of modifyAttributes.

      Comment


      • #4
        We have always thought that an LDAP Group MUST have at least one member is a mistake.
        All our OpenLDAP servers are modified to change the 'uniqueMember' attribute from MUST to MAY (I think it's in the core.schema).

        This way, you would never have any problem.

        Comment


        • #5
          Originally posted by mlarchet View Post
          We have always thought that an LDAP Group MUST have at least one member is a mistake.
          All our OpenLDAP servers are modified to change the 'uniqueMember' attribute from MUST to MAY (I think it's in the core.schema).

          This way, you would never have any problem.
          You're right, it is a very strange requirement that a group must have at least one member. Nevertheless, there might be other multi-value attributes for which it would make sense, so I guess the problem in getModificationItems should be addressed anyway.

          Thanks for the tip.

          Comment


          • #6
            must vs may

            I agree with rasky -- not all people are allowed to change their core schemas. BTW, out of the box ApacheDS will not allow a groupOfUniqueNames entry to exist without a member. And, you said you had to modify OpenLDAP from its out of the box condition. So, it must be the general consensus (or spec) that a group must have at least one member.

            I do agree, however, that in many business cases, you should be allowed to have a group with no members.

            Comment


            • #7
              A DN is allowed to be empty, and one workaround is to always make sure there is a member with an empty DN in all groups.

              Comment


              • #8
                Our little workaround for now is to add a "required" dummy user that is obvious when you browse the LDAP server with another tool. This might help prevent users from accidently deleting the bogus member if it were null.

                So, to make it obvious, we have a uniqueMember with a DN similar to "_dummyUser_doNotDelete_"

                Comment


                • #9
                  Removing attributes does not respect DN matching.

                  I'm running into a similar problem with Spring-LDAP 1.3.0. I have a role named supervisor that is a groupOfNames node:

                  dn: cn=supervisor,ou=roles,o=Acme,c=us
                  cn: supervisor
                  member: cn=John Doe, ou=People, ou=Accounting, o=Acme,c=us
                  In Spring code, I try
                  DirContextOperations supervisor = ...
                  supervisor.removeAttributeValue("member", "cn=John Doe, ou=People, ou=Accounting, o=Acme,c=US");
                  template.modifyAttributes(supervisor);
                  Nothing happens, even though the member I'm removing matches the member in the list according to DN matching rules.

                  Comment

                  Working...
                  X