OpenLDAP memberOf overlay

By | 2019-02-28

The OpenLDAP memberOf overlay automatically creates and removes attributes when attributes of other entries that refer to their DN are added and removed. That statement, while technically accurate, was confusing to me and I wrote it! For example, if you create a groupOfNames entry with a member attribute of uid=user,ou=users,dc=tylersguides,dc=com, the memberOf overlay can automatically create a memberOf attribute with the DN of the groupOfNames entry you just created.

If you are trying to use memberOf with posixGroups, there isn’t an easy way to do it. This is because the posixGroups memberUid attributes don’t use DNs, which is required by the overlay.

The way the memberOf overlay works is probably easier to grasp with a demonstration.

Example

Suppose you have the following entry.

dn: uid=testuser,ou=users,dc=tylersguides,dc=com
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: First Name
sn: Last Name
uid: testuser
uidNumber: 5000
gidNumber: 5000
homeDirectory: /home/testuser
loginShell: /bin/sh
gecos: Full Name

After configuring the memberOf overlay, suppose you add the following entry:

dn: cn=ldapgroup1,ou=groups,dc=tylersguides,dc=com
objectClass: groupOfNames
cn: ldapgroup1
member: uid=testuser,ou=users,dc=tylersguides,dc=com

Now the entry referenced by the member attribute of the groupOfNames entry has a memberOf attribute with the DN of the groupOfNames entry:

dn: uid=testuser,ou=users,dc=tylersguides,dc=com
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: First Name
sn: Last Name
uid: testuser
uidNumber: 5000
gidNumber: 5000
homeDirectory: /home/testuser
loginShell: /bin/sh
gecos: Full Name
memberOf: cn=ldapgroup1,ou=groups,dc=tylersguides,dc=com

If you delete the groupOfNames entry, notice that the user entry no longer has the memberOf attribute.

[root@ldap openldap]# ldapdelete -Y EXTERNAL -H ldapi:///
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
cn=ldapgroup1,ou=groups,dc=tylersguides,dc=com
dn: uid=testuser,ou=users,dc=tylersguides,dc=com
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: First Name
sn: Last Name
uid: testuser
uidNumber: 5000
gidNumber: 5000
homeDirectory: /home/testuser
loginShell: /bin/sh
gecos: Full Name

Configuration

Configuring the memberOf overlay has two steps. Most of the time, you will need to load a module. In some cases, the overlay is compiled into slapd.

Load memberOf module

See if you have any modules already loaded:

[root@ldap openldap]# slapcat -n 0 | grep olcModuleLoad
olcModuleLoad: {0}back_mdb.la
olcModuleLoad: {1}pw-sha2.la
[root@ldap openldap]# 

If you have any output from the command above, use ldapmodify to load the module:

[root@ldap openldap]# ldapmodify -Q -Y EXTERNAL -H ldapi:///
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: memberof.la

modifying entry "cn=module{0},cn=config"

Otherwise, use ldapadd. Replace the highlighted portion with what is relevant to your environment. If you aren’t sure where your modules are located, consult the table below.

[root@ldap openldap]# ldapadd -Y EXTERNAL -Q -H ldapi:///
dn: cn=module,cn=config
cn: module 
objectClass: olcModuleList
olcModulePath: /opt/openldap-current/libexec/openldap
olcModuleLoad: memberof.la

adding new entry "cn=module,cn=config"
OS PATH
CentOS 7 /usr/lib64/openldap
openSUSE /usr/lib64/openldap
Debian (Stretch) /usr/lib/ldap
Source (Default) /usr/local/libexec/openldap
Source (Tyler’s Guides) /opt/openldap-current/libexec/openldap

Apply the Overlay

Use ldapadd to create entries in your configuration directory for each backend you wish to apply the overlay to.

[root@ldap openldap]# ldapadd -Y EXTERNAL -H ldapi:///
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcMemberOf
olcOverlay: memberof
olcMemberOfRefint: TRUE

The olcMemberOfRefint, the referential integrity option, helps maintain the consistency of your member and memberOf attributes. If you rename or delete an entry, it automatically fixes the member attribute of any groups the entry is a member of. The table below will help you understand the behavior of the overlay with and without the olcMemberOfRefint option set.

Action Without olcMemberOfRefint With olcMemberOfRefint
Add an entry to a group A memberOf attribute with the DN of the group is added to the entry. The same behavior as without olcMemberOfRefint.
Remove a member attribute from a group The corresponding memberOf attribute is removed from the entry. The same behavior as without olcMemberOfRefint.
Rename an entry that is in a group The member attribute retains the old DN. The member attribute is updated with the new DN.
Delete an entry that is in a group The member of all groups the entry was a member of remain. The member attributes of all relevant groups are removed.
Rename a group The memberOf attributes of all entries referenced by the group’s member attributes are updated with the groups new DN. The same behavior as without olcMemberOfRefint.
Delete a memberOf attribute The group referenced by the memberOf attribute retains the corresponding member attribute. The same behavior as without olcMemberOfRefint.
Change a memberOf attribute The group referenced by the memberOf attribute retains the original value in its corresponding member attribute. The same behavior as without olcMemberOfRefint.
Delete a group The memberOf attributes that referenced the deleted group are removed. The same behavior as without olcMemberOfRefint.

The attributes that memberOf maintains are configurable. See the slapo-memberof man page for details. The man page uses the configuration file parameters, so I included a table with the corresponding configuration directory attributes.

Configuration File Configuration Directory
memberof-group-oc olcMemberOfGroupOC
memberof-member-ad olcMemberOfMemberAD
memberof-memberof-ad olcMemberOfMemberOfAD
memberof-dn olcMemberOfDN
memberof-dangling olcMemberOfDangling
memberof-dangling-error olcMemberOfDanglingError
memberof-refint olcMemberOfRefInt

References