Thursday, March 12, 2009

Combining dynamic and static groups

After my previous post, I've been trying to figure out some solutions to the scenario I presented (a dynamic email group with opt-in/opt-out capabilities). I got some good suggestions from Matt Flynn and will have a subsequent post with some commercial tools that provide end-user self-service for things like distribution list management in AD or LDAP.

My bigger concern, though, was trying to prove out my little quasi-code example in Sun Directory Server. While the software supports dynamic groups, defined with an LDAP search URL, it seems to be client-specific as to whether those dynamic URLs in the group definition are actually followed (meaning, the users matching the URL filter are returned to the client). I was unable to get a command-line ldapsearch query to successfully return all the members of a dynamic group (suggestions, anyone?). However, by using a combination of managed and filtered roles, instead of groups, it was quite easy to accomplish this.

First, you can define a managed (static) role and manually assign users in. This could be your "opt-in" group -- those users who would like to receive an email newsletter, for example, but would not normally be included automatically based on degree or major or what have you. With a self-service tool, users could add themselves into this managed role as a sort of 'subscribe' functionality.

Secondly, if needed, you could assign an attribute for the opt-out capability. Unfortunately, you can't use the 'nsRole' calculated attribute as part of the filter in the definition of another role. But there are certainly ways around this limitation (extend the schema to include an attribute called 'optout' with the value of the list name, or just use an existing attribute like 'memberof' with a value of your choice). You also can't use the 'isMemberOf' attribute (which is used to return all the static group memberships for a particular user), because, again, this is a calculated attribute.

For reference purposes, here is the filtered role definition I used for testing my example:
nsRoleFilter: (&(sn=Black)(!(memberof=optout_dllist)))

(All users with a last name of "Black", EXCEPT for those who have a memberof attribute set to "optout_dllist")

Once the filtered role is defined, you can then create a nested role with the managed (static) role you created for 'opt-ins', along with the filtered role with users matching a particular criteria (and optionally, excluding those who may have opted out) After the nested role has been defined, you can simply query a given user for the 'nsrole' attribute to see which roles they belong to, or search directly against the 'nsrole=nested_role_dn' to show all the members of the role. Note that you must explicitly ask for the nsrole attribute in an ldapsearch command -- just doing a normal search against a user's attributes will not show their role memberships.

And to save you some of the same headaches that I went through, since a role is defined as a subentry, it is not returned in a normal ldapsearch command. You must specifically ask for them using a search filter like :
"(&(objectclass=nsManagedRoleDefinition)(objectclass=ldapSubEntry))"


For additional information about Roles in SUN DSEE 6.3, the documentation is here.

No comments: