OpenDJ collective privileges

Ran into this when I set up some administrator acis on OpenDJ but still couldn’t change the passwords of other users. Yes, sometimes you’ve got to just read the doc.


So after setting up a some users and groups to handle basic administrative tasks, along with some appropriate acis, I was surprised to find that none of my new admins could change user passwords.

I won’t go into detail on the preliminaries, trust me I got those all right. But my prep did fall short in one very important area: user privileges.

OpenDJ makes privileges an integral part of its permissioning scheme, going way beyond what the old aci paradigm allowed for in terms of granularity but also making things a bit more complicated to set up.

Fortunately the OpenDJ Admin Guide has a pretty good chapter on Configuring Privileges & Access Control, and there have been quite a few blog posts on the subject — including this one (cross-posted here).

What I came up with was a bit different than the examples given above, but I’m just at the beginning.

dn: cn=Administrators Privileges,dc=example,dc=com
changetype: add
objectClass: extensibleObject
objectClass: collectiveAttributeSubentry
objectClass: top
objectClass: subentry
cn: Administrators Privileges
ds-privilege-name;collective: config-read
ds-privilege-name;collective: ldif-export
ds-privilege-name;collective: password-reset
ds-privilege-name;collective: proxied-auth
subtreeSpecification: {base "" specificationFilter "(isMemberOf=cn=Directory Adm
 inistrators,dc=example,dc=com)" }

dn: cn=User Administrators Privileges,dc=example,dc=com
changetype: add
objectClass: extensibleObject
objectClass: collectiveAttributeSubentry
objectClass: top
objectClass: subentry
cn: User Administrators Privileges
ds-privilege-name;collective: password-reset
ds-privilege-name;collective: proxied-auth
subtreeSpecification: {base "", specificationFilter "(|(isMemberOf=cn=User Admi
 nistrators,ou=groups,dc=example,dc=com)(isMemberof=cn=Security Apps,ou=groups,
 dc=example,dc=com))" }

Just a few notes on the above.

1. The subtreeSpecification attribute in the above examples contains 2 important elements: (a) “base” identifies the relative dn (a dn under the directory’s suffix, e.g. “dc=example,dc=com”) under which reside the entries you want to grant a collection of privileges; (b) “specificationFilter” provides the criteria that entries under that base have to match.

In both examples I’ve chosen to make base the rootdn, to avoid having to create a subentry for each container where admin user entries may reside. Again, this isn’t the base for the entries to be administered, but the base for the entries that will do the administering.

The “base” element is not required. If you leave it out the directory will default to setting it at the rootdn (“”).

2. The ds-privilege-name;collective attribute is multi-valued and has a large number of possible values. I highly recommend reading the doc thoroughly to understand what each of these does. In my case I trimmed down the privileges given in most of the examples to what I think was minimally required.

3. LDAP browsers will not show these sorts of subentries without your explicitly searching for them. Look for “(objectclass=subentry)” to view what may be lurking in your own directory. Most of the attributes themselves, including “ds-privilege-name;collective” are operational in nature and thus hidden until you specify them or do a “fetch operational attributes” in your favorite LDAP browser.

4. The “isMemberOf” operational attribute shows the distinguished names of every group an entry is a member of, similar to Active Directory’s “MemberOf” attribute. Because it is operational in nature it can only be seen if explicitly requested, or using an LDAP browser’s “fetch operational attributes” function. It works both with static (“unqiuemember”) and dynamic (“memberurl”) groups — but it does not appear to understand how to handle double-nesting of dynamic groups. This would be where the target is a dynamic group whose members are another dynamic group. So adding a dynamic group called “Help Desk”, whose members are everyone with “businesscategory=Help Desk”, to the “User Administrators” group above will not work but pointing directly at the “Help Desk” group will.

5. To list more than one matching attribute/value pair in specificationFilter, follow the usual LDAP search filter syntax. In the second subentry (“User Administrators Privileges”) you’ll notice that being a member of either the User Administrators or Security Apps groups will result in receiving the privileges granted (in real life I’d break things out so applications have their own privilege subentry to allow more flexibility in rights assignment). As far as I know at this writing the above is the only example on the Internet of the correct syntax to use for a filter containing multiple terms. That’s very sad.