Chapter 1. Using groups in Directory Server You can add users to groups in Directory Server. Groups are one of the mechanisms to group directory entries, that simplifies management of the user accounts. When you use a group, Directory Server stores the distinguished name (DN) of the users who are members of this group in a membership attribute of the group entry. This special attribute is defined by the object class you choose when creating a group entry. For details about the group types, see Group types in Directory Server . Groups are faster than roles. However, for a group to have benefits of a role, you need to enable the MemberOf plug-in. By default, the MemberOf plug-in automatically adds the memberOf attribute to a user entry if this user is a member of the group. As a result, the information about the membership is stored in both the group and user entries. For details about the MemberOf plug-in, see Listing group membership in user entries . 1.1. Group types in Directory Server In Directory Server, you can add members to a static or dynamic group. For more details about definition of each group type, see About groups in Directory Server . A group object class defines a membership attribute, and to add a member to the group, you need to add a value to this membership attribute of the group entry. The following table lists group object classes and corresponding membership attributes. Group type Object class Membership attribute Static groupOfNames member groupOfUniqueNames uniqueMember Dynamic groupOfURLs memberURL groupOfCertificates memberCertificate Object classes that you can use when you create a group: groupOfNames is a simple group. You can add any entry to this group. The member attribute determines the group membership. The member attribute values are distinguished names (DN) of user entries that are members of the group. groupOfUniqueNames lists user DNs as members, however the DNs must be unique. This group prevents self-referential group memberships. The uniqueMember attribute determines the group membership. groupOfURLs uses a list of LDAP URLs to filter and create its membership list. Any dynamic group requires this object class and you can use it in conjunction with groupOfNames and groupOfUniqueNames . The memberURL attribute determines the group membership. groupOfCertificates uses an LDAP filter to search for certificate names to identify group members. Use the groupOfCertificates object class for group-based access control, because you can give special access permissions to this group. The memberCertificateDescription attribute determines the group membership. Important If you use an object class of a static group together with one of the dynamic object classes, the group becomes dynamic. The MemberOf plug-in does not support dynamic groups. Therefore, the plug-in does not add the memberOf attribute to the user entry if the user entry matches the filter of a dynamic group. 1.2. Creating a static group You can create a static group by using the command line or the web console. 1.2.1. Creating a static group using the command line Use the dsidm utility to create a static group with the groupOfNames object class. Use the ldapmodify utility to create a static group with the groupOfUniqueNames object class. The following example creates two static groups in the ou=groups,dc=example,dc=com entry. Prerequisites The ou=groups,dc=example,dc=com parent entry exists. Procedure To create cn=simple_group group with the groupOfNames object class, run: Note that the dsidm group create command creates groups only in the ou=group sub-entry. If you want to create a group in another entry, use ldapmodify utility. To create cn=unique_members_group group with the groupOfUniqueNames object class, run: Verification Use dsidm group list command to list groups with the the groupOfNames object class: Use dsidm uniquegroup list command to list groups with the unique members: steps Adding members to a static group . 1.2.2. Creating a static group in the LDAP Browser You can use the web console to create a static group. The following example creates a static_group in the ou=groups,dc=example,dc=com parent entry. Prerequisites The ou=groups,dc=example,dc=com parent entry exists. You have permissions to log in to the instance in the web console. For more information about logging in to the web console, see Logging in to the Directory Server by using the web console . Procedure Navigate to LDAP Browser menu. Using the Tree or Table view, expand the parent entry ou=groups,dc=example,dc=com under which you want to create the group. Click the Options menu (⫶) and select New to open the wizard window. Select the Create a group and click . Select the Basic Group for the groupe type and click . Add the group name, group description, and select the membership attribute for the group: member for the group with the groupOfNames object class. uniquemember for the group with the groupOfUniqueNames object class. Click . Optional: Add members to the group and click . Verify the group information, click Create , and Finish . Verification Expand the newly created group entry in the suffix tree. 1.3. Adding members to static groups You can add a member to a group by using the command line of the web console. 1.3.1. Adding members to a static group using the command line To add a member to a static group use the ldapmodify utility. Prerequisites The group entry exists. The users entry exist. Procedure To add a member to a static group with the groupOfNames object class, add the user distinguished name (DN) as the value to the member attribute of the group entry: The command adds the uid=jsmith user to the cn=simple_group group. To add a member to a static group with the groupOfUniqueNames object class, add the user distinguished name (DN) as the value to the uniqueMember attribute of the group entry: The command adds the uid=ajonson user to the cn=unique_members_group group. Verification List the members of the group: 1.3.2. Adding members to a static group in LDAP Browser You can add a member to a static group in the web console by using LDAP Browser. Prerequisites The group entry exists. The user entry exists. You are logged in to the instance in the web console. For more details about logging in to the web console, see Logging in to the Directory Server by using the web console . Procedure Navigate to LDAP Browser menu. Using the Tree or Table view, expand the group entry to which you want to add the member. For example. you want to add a member to cn=unique_members_group,ou=groups,dc=example,dc=com . Click the Options menu (⫶) and select Edit to open the wizard window. The window displays the current members list. Select Find New Members tab. Type the part of the uid or cn attribute value of the member in the search bar and press Enter . The Available Members field displays the user distinguished names (DN) that you can add to the group. Select the member DN and move it to the Chosen Members field by click on the arrow (>). Click Add Member button. Verification Expand the cn=unique_members_group,ou=groups,dc=example,dc=com group entry and find the added user in the entry details. 1.4. Creating a dynamic group using the command line Directory Server supports creating dynamic groups by using only the command line. Use the ldapmodify utility to create a dynamic group with the groupOfURLs and groupOfCertificates object classes. The following example creates two dynamic groups in the ou=groups,dc=example,dc=com entry. Prerequisites The ou=groups,dc=example,dc=com parent entry exists. Procedure To create cn=example_dynamic_group group with the groupOfURLs object class, run: The command creates a dynamic group that filters members with the person object class and the sen substring in the right part of the common name ( cn ) value. To create cn=example_certificates_group group with the groupOfCertificates object class, run: The command creates a dynamic group that filters members whose certificate subject DNs contain ou=people,l=USA,dc=example,dc=com . Verification Search for the newly created group with the groupOfURLs object class: Search for the newly created group with the groupOfCertificates object class: Additional resources Adding an LDAP entry using the command line 1.5. Listing group membership in user entries A group defines entries that belong to this group by using the membership attribute. It is easy to look at the group and find its members. For example, a static group with the groupOfNames object class stores distinguished names (DNs) of its members as values of the member attribute. However, you cannot quickly find out what groups a single user belongs to. With groups, a user entry does not contain anything that indicates the user memberships, unlike with roles. To solve this problem, you can use the MemberOf plug-in. The MemberOf plug-in analyzes the membership attribute in a group entry and automatically writes the memberOf attribute in the user entry that points to the group. By default, the plug-in checks the member attribute in the groups, however, you can use several attributes to support different group types. When you add or delete a member of a group, the plug-in updates the memberOf attributes in the user entries. With the MemberOf plug-in, you can do a simple search against a specific user entry to find all groups that the user is a member of. The MemberOf Plug-in shows direct and indirect memberships for all groups. Important The MemberOf plug-in manages membership attributes only for static groups. Additional resources Group types in Directory Server 1.5.1. Considerations when using the MemberOf plug-in When using the MemberOf plug-in, consider the following: The MemberOf plug-in in a replication topology In a replication topology, you can manage the MemberOf plug-in in two ways: Enable the MemberOf plug-in on all supplier and consumer servers in the topology. In this case, you must exclude the memberOf attribute of user entries from replication in all replication agreements. Enable the MemberOf plug-in only on all supplier servers in the topology. To do this: You must disable replication of the memberOf attribute to all write-enabled suppliers in the replication agreement. You must enable replication of the memberOf attribute to all consumer replicas in their replication agreement. You must disable the MemberOf plug-in on consumer replicas. The MemberOf plug-in with distributed databases As described in Creating and maintaining databases , you can store sub-trees of your directory in separate databases. By default, the MemberOf plug-in only updates user entries that are stored within the same database as the group. To update users across all databases, you must set the memberOfAllBackends parameter to on . For more details about setting the memberOfAllBackends parameter, see Configuring the MemberOf plug-in on each server using the web console . 1.5.2. Required object classes for the MemberOf plug-in By default, the MemberOf plug-in adds the nsMemberOf object class to user entries to provide the memberOf attribute. The nsMemberOf object class is sufficient for the plug-in to work correctly. Alternatively, you can create user entries that contain the inetUser , inetAdmin , inetOrgPerson object class. These object classes support the memberOf attribute. To configure nested groups, the group must use the extensibleObject object class. Note If directory entries do not contain an object class that supports required attributes operations fail with the following error: 1.5.3. The MemberOf plug-in syntax When configuring the MemberOf plug-in, you set the main two attributes: memberOfGroupAttr . Defines which membership attribute to poll from the group entry. The memberOfGroupAttr attribute is multi-valued. Therefore, the plug-in can manage multiple types of groups. By default, the plug-in polls the member attribute. memberOfAttr . Defines which membership attribute to create and manage in the member's user entry. By default, the plug-in adds the memberOf attribute to the user entry. In addition, the plug-in syntax provides the plug-in path, function to identify the MemberOf plug-in, the plug-in state, and other configuration parameters. The following example shows the default MemberOf plug-in entry configuration: For details about the parameters in the example and other parameters you can set, see MemberOf plug-in section in the "Configuration and schema reference" documentation. 1.5.4. Enabling the MemberOf plug-in You can enable the MemberOf plug-in by using the command line or the web console. 1.5.4.1. Enabling the MemberOf plug-in using the command line Use the dsconf utility to enable the MemberOf plug-in. Procedure Enable the plug-in: Restart the instance: Verification View the plug-in configuration details: Additional resources Configuring the MemberOf plug-in on each server 1.5.4.2. Enabling the MemberOf plug-in using the web console You can use the web console to enable the MemberOf plug-in. Prerequisites You are logged in to the instance in the web console. For more details about logging in to the web console, see Logging in to the Directory Server by using the web console . Procedure Navigate to the Plugins menu. Select the MemberOf plug-in in the list of plug-ins. Change the status to ON to enable the plug-in. Restart the instance. For instructions for restarting the instance, see Starting and stopping a Directory Server instance by using the web console . Additional resources Configuring the MemberOf plug-in on each server using the web console 1.5.5. Configuring the MemberOf plug-in on each server If you do not want to replicate the configuration of the MemberOf plug-in, configure the plug-in manually on each server by using the command line or the web console. 1.5.5.1. Configuring the MemberOf plug-in on each server using the command line By default, the MemberOf plug-in reads the member membership attribute from the group entries and adds the memberOf attribute to the user entries. However, you can configure the plug-in to read other membership attribute from the group, add another attribute to the user entry, skip nested groups, work on all databases and other settings. For example, you want the MemberOf plug-in to do the following: Read uniqueMember attribute from group entries to identify membership. Skip nested groups. Search for user entries in all databases. Prerequisites You enabled the MemberOf plug-in. For details, see Enabling the MemberOf plug-in . Procedure Optionally: Display the MemberOf plug-in configuration to see which membership attribute the plug-in currently reads from groups entries: The plug-in currently reads the member attribute from the group entry to retrieve members. Set the uniqueMember attribute as the value to the memberOfGroupAttr parameter in the plug-in configuration: The memberOfGroupAttr parameter is multi-valued and you can set several values by passing them all to the --groupattr parameter. For example: In an environment that uses distributed databases, configure the plug-in to search user entries in all databases instead of only the local database: The command sets the memberOfAllBackends parameter. Configure the plug-in to skip nested groups: The command sets the memberOfSkipNested parameter. Optional: By default, the plug-in adds nsMemberOf object class to user entries if the user entries do not have the object class that allows the memberOf attribute. To configure the plug-in to add the inetUser object class to the user entries instead of nsMemberOf , run: The command sets the memberOfAutoAddOC parameter. Restart the instance: Verification View the MemberOf plug-in configuration: Additional resources Updating the memberOf attribute values in user entries using the fixup task Sharing the MemberOf plug-in configuration between servers Setting the scope of the MemberOf plug-in Required object classes for the MemberOf plug-in 1.5.5.2. Configuring the MemberOf plug-in on each server using the web console By default, the MemberOf plug-in reads the member membership attribute from the group entries and adds the memberOf attribute to the user entries. However, you can configure the plug-in to read other membership attribute from the group, skip nested groups, work on all databases and other settings by using the web console. For example, you want the MemberOf plug-in to do the following: Read member and uniqueMember attributes from group entries to identify membership. Set the scope of the plug-in to dc=example,dc=com . Skip nested groups. Search for user entries in all databases. Prerequisites You are logged in to the instance in the web console. For more details about logging in to the web console, see Logging in to the Directory Server by using the web console . You enabled the MemberOf plug-in. For details, see Enabling the MemberOf plug-in . Procedure Navigate to LDAP Browser menu. Select the MemberOf plug-in from the plug-ins list. Add the uniqueMember attribute to the Group Attribute field. Set the scope of the plug-in to dc=example,dc=com : Enter dc=example,dc=com to the Subtree Scope field. Click Create "dc=example,dc=com" in the drop-down list. Optional: Set a subtree to exclude. For example, you do not want the plug-in to work on the ou=private,dc=example,dc=com subtree: Enter ou=private,dc=example,dc=com to the Exclude Subtree field. Click Create "ou=private,dc=example,dc=com" in the drop-down list. Check All Backends to configure the plug-in to search user entries in all databases instead of only the local database. Check Skip Nested to configure the plug-in to skip nested groups. Click Save Config . Additional resources Sharing the MemberOf plug-in configuration between servers Setting the scope of the MemberOf plug-in using the command line MemberOf plug-in Updating the memberOf attribute values in user entries using the fixup task 1.5.6. Sharing the MemberOf plug-in configuration between servers By default, each server stores its own configuration of the MemberOf plug-in. With the shared configuration of the plug-in, you can use the same settings without configuring the plug-in manually on each server. Directory Server stores the shared configuration outside of the cn=config suffix and replicates it. For example, you want to store the plug-in shared configuration in the cn=shared_MemberOf_config,dc=example,dc=com entry. Important After enabling the shared configuration, the plug-in ignores all parameters set in the cn=MemberOf Plugin,cn=plugins,cn=config plug-in entry and only uses settings from the shared configuration entry. Prerequisites You enabled the MemberOf plug-in on all servers in the replication topology. For details, see Enabling the MemberOf plug-in . Procedure Enable the shared configuration entry on a server: The command sets nsslapd-pluginConfigArea attribute value to cn=shared_MemberOf_config,dc=example,dc=com . Restart the instance: Enable the shared configuration on other servers in the replication topology that should use the shared configuration: Set the distinguished name (DN) of the configuration entry that stores the shared configuration: Restart the instance: Verification Check that the MemberOf plug-in uses the shared configuration: Optional: Check the shared configuration settings: Additional resources nsslapd-pluginConfigArea 1.5.7. Setting the scope of the MemberOf plug-in If you configured several backends or multiple-nested suffixes, you can use the memberOfEntryScope and memberOfEntryScopeExcludeSubtree parameters to set what suffixes the MemberOf plug-in works on. If you add a user to a group, the MemberOf plug-in only adds the memberOf attribute to the group if both the user and the group are in the plug-in's scope. For example, the following procedure configures the MemberOf plug-in to work on all entries in dc=example,dc=com , but to exclude entries in ou=private,dc=example,dc=com . Prerequisites You enabled the MemberOf plug-in on all servers in the replication topology. For details, see Enabling the MemberOf plug-in . Procedure Set the scope value for the MemberOf plug-in to dc=example,dc=com : Exclude entries in ou=private,dc=example,dc=com : If you moved a user entry out of the scope by using the --scope DN parameter: The MemberOf plug-in updates the membership attribute, such as member , in the group entry to remove the user DN value. The MemberOf plug-in updates the memberOf attribute in the user entry to remove the group DN value. Note The value set in the --exclude parameter has a higher priority than values set in --scope . If the scopes set in both parameters overlap, the MemberOf plug-in only works on the non-overlapping directory entries. For details about setting the scope for the MemberOf plug-in, see Configuring the MemberOf plug-in on each server using the web console . 1.5.8. Updating the memberOf attribute values in user entries using the fixup task The MemberOf plug-in automatically manages memberOf attributes in group member entries based on the configuration in the group entry. However, you need to run the fixup task in the following situations to avoid inconsistency between the memberOf configuration that the server plug-in manages and the actual memberships defined in user entries: You added group members to a group before you enabled the MemberOf plug-in. You manually edited the memberOf attribute in a user entry. You imported or replicated new user entries to the server that already have the memberOf attribute. Note that you can run the fixup tasks only locally. In a replication environment, Directory Server updates the memberOf attribute for entries on other servers after Directory Server replicates the updated entries. Prerequisites You enabled the MemberOf plug-in on all servers in the replication topology. For details, see Enabling the MemberOf plug-in . Procedure For example, to update the memberOf values in dc=example,dc=com entry and subentries, run: By default, the fixup task updates memberOf values in all entries that contain the inetUser , inetAdmin , or nsMemberOf object class. If you want the fixup task to also work on entries that contain other object classes, use -f filter option: This fixup task updates memberOf values in all entries that contain the inetUser , inetAdmin , nsMemberOf , or inetOrgPerson object class. Additional resources LDAP search filters

Commands:
dsidm -D "cn=Directory Manager" ldap://server.example.com -b "dc=example,dc=com" group create --cn "simple_group" Successfully created simple_group
ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x dn: cn=unique_members_group,ou=groups,dc=example,dc=com changetype: add objectClass: top objectClass: groupOfUniqueNames cn: unique_members_group description: A static group with unique members adding new entry "cn=unique_members_group,ou=groups,dc=example,dc=com"
dsidm --basedn "dc=example,dc=com" instance_name group list simple_group
dsidm --basedn "dc=example,dc=com" instance_name uniquegroup list unique_members_group
ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x dn: cn=simple_group,ou=groups,dc=example,dc=com changetype: modify add: member member: uid=jsmith,ou=people,dc=example,dc=com modifying entry "cn=simple_group,ou=groups,dc=example,dc=com"
ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x dn: cn=unique_members_group,ou=groups,dc=example,dc=com changetype: modify add: uniqueMember uniqueMember: uid=ajonson,ou=people,dc=example,dc=com modifying entry "cn=unique_members_group,ou=groups,dc=example,dc=com"
ldapsearch -xLL -D "cn=Directory Manager" -W -b dc=example,dc=com "(cn=simple_group)" dn: cn=simple_group,ou=Groups,dc=example,dc=com objectClass: top objectClass: groupOfNames objectClass: nsMemberOf cn: simple_group member: uid=jsmith,ou=people,dc=example,dc=com member: uid=mtomson,ou=people,dc=example,dc=com
ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x dn: cn=example_dynamic_group,ou=groups,dc=example,dc=com changetype: add objectClass: top objectClass: groupOfURLs cn: example_dynamic_group description: Example dynamic group for user entries memberURL: ldap:///dc=example,dc=com??sub?(&(objectclass=person)(cn=*sen)) adding new entry "cn=example_dynamic_group,ou=groups,dc=example,dc=com"
ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x dn: cn=example_certificates_group,ou=groups,dc=example,dc=com changetype: add objectClass: top objectClass: groupOfCertificates cn: example_certificates_group description: Example dynamic group for certificate entries memberCertificateDescription: {ou=people, l=USA, dc=example, dc=com} adding new entry "cn=example_certificates_group,ou=groups,dc=example,dc=com"
ldapsearch -xLLL -D "cn=Directory Manager" -W -H ldap://server.example.com -b "dc=example,dc=com" "objectClass=groupOfURLs" 1.1 dn: cn=example_dynamic_group,ou=groups,dc=example,dc=com
ldapsearch -xLLL -D "cn=Directory Manager" -W -H ldap://server.example.com -b "dc=example,dc=com" "objectClass=groupOfCertificates" 1.1 dn: cn=example_certificates_group,ou=groups,dc=example,dc=com
LDAP: error code 65 - Object Class Violation
dn: cn=MemberOf Plugin,cn=plugins,cn=config cn: MemberOf Plugin memberofallbackends: off memberofattr: memberOf memberofentryscope: dc=example,dc=com memberofgroupattr: member memberofskipnested: off nsslapd-plugin-depends-on-type: database nsslapd-pluginDescription: memberof plugin nsslapd-pluginEnabled: off nsslapd-pluginId: memberof nsslapd-pluginInitfunc: memberof_postop_init nsslapd-pluginPath: libmemberof-plugin nsslapd-pluginType: betxnpostoperation nsslapd-pluginVendor: 389 Project nsslapd-pluginVersion: 2.4.5 objectClass: top objectClass: nsSlapdPlugin objectClass: extensibleObject
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof enable
dsctl instance_name restart
dsconf -D "cn=Directory Manager" ldap:// server.example.com plugin memberof show dn: cn=MemberOf Plugin,cn=plugins,cn=config nsslapd-pluginEnabled: on
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof show memberofgroupattr: member
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --groupattr uniqueMember
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --groupattr member uniqueMember
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --allbackends on
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --skipnested on
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --autoaddoc inetUser
dsctl instance_name restart
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof show dn: cn=MemberOf Plugin,cn=plugins,cn=config cn: MemberOf Plugin memberofallbackends: on memberofattr: memberOf memberofautoaddoc: inetuser memberofentryscope: dc=example,dc=com memberofgroupattr: uniqueMember memberofskipnested: on nsslapd-pluginEnabled: on
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof config-entry add "cn=shared_MemberOf_config,dc=example,dc=com" --attr memberOf --groupattr member Successfully created the cn=shared_MemberOf_config,dc=example,dc=com MemberOf attribute nsslapd-pluginConfigArea (config-entry) was set in the main plugin config
dsctl instance_name restart
dsconf -D "cn=Directory Manager" ldap://server2.example.com plugin memberof set --config-entry cn=shared_MemberOf_config,dc=example,dc=com
dsctl instance_name restart
dsconf -D "cn=Directory Manager" ldap://server1.example.com plugin memberof show dn: cn=MemberOf Plugin,cn=plugins,cn=config cn: MemberOf Plugin nsslapd-pluginConfigArea: cn=shared_MemberOf_config,dc=example,dc=com
dsconf -D "cn=Directory Manager" ldap://server1.example.com plugin memberof config-entry show "cn=shared_MemberOf_config,dc=example,dc=com" dn: cn=shared_MemberOf_config,dc=example,dc=com cn: shared_MemberOf_config memberofattr: memberOf memberofgroupattr: member objectClass: top objectClass: extensibleObject
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --scope "dc=example,dc=com"
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof set --exclude "ou=private,dc=example,com"
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof fixup "dc=example,dc=com" Attempting to add task entry Successfully added task entry
dsconf -D "cn=Directory Manager" ldap://server.example.com plugin memberof fixup -f "(|(objectclass=inetuser)(objectclass=inetadmin)(objectclass=nsmemberof)(objectclass=nsmemberof)(objectclass=inetOrgPerson))" "dc=example,dc=com"