Synchronize posixGroup to groupOfNames¶
Presentation¶
In a standard LDAP directory, you can have several kind of groups, each one represented by a specific object class, for example:
posixGroup
groupOfNames
groupOfUniqueNames
groupOfURLs
You may need to have both of them, for example posixGroup and groupOfNames, as posixGroup entries will be used for system authentication (PAM or SSSD) and groupOfNames for web applications authorizations.
This tutorial will explain how to sync members between a posixGroup entry and a groupOfNames entry, so you just have to edit one entry to manage membership.
Let’s go¶
This tutorial is an adaptation of Synchronize OpenLDAP groups to Active Directory groups, with these differences:
We sync posixGroup to groupOfNames instead of groupOfUniqueNames to AD group
There is only one directory (so only one connection), groups can be in different branches or in the same one
We suppose that all users are in ou=users branch, and that the RDN is based on uid attribute
Task¶
Create a task group
as a standard LSC task:
<task>
<name>group</name>
<bean>org.lsc.beans.SimpleBean</bean>
...
</task>
Services¶
We define here a source service that will read POSIX groups, and a destination service that will manage standard groups:
<ldapSourceService>
<name>group-source-service</name>
<connection reference="openldap" />
<baseDn>ou=groups,dc=example,dc=com</baseDn>
<pivotAttributes>
<string>cn</string>
</pivotAttributes>
<fetchedAttributes>
<string>cn</string>
<string>memberUid</string>
</fetchedAttributes>
<getAllFilter><![CDATA[(objectClass=posixGroup)]]></getAllFilter>
<getOneFilter><![CDATA[(&(objectClass=posixGroup)(cn={cn}))]]></getOneFilter>
<cleanFilter><![CDATA[(&(objectClass=posixGroup)(cn={cn}))]]></cleanFilter>
</ldapSourceService>
<ldapDestinationService>
<name>group-dst-service</name>
<connection reference="openldap" />
<baseDn>ou=groups,dc=example,dc=com</baseDn>
<pivotAttributes>
<string>cn</string>
</pivotAttributes>
<fetchedAttributes>
<string>cn</string>
<string>member</string>
<string>objectClass</string>
</fetchedAttributes>
<getAllFilter><![CDATA[(objectClass=groupeOfNames)]]></getAllFilter>
<getOneFilter><![CDATA[(&(objectClass=groupOfNames)(cn={cn}))]]></getOneFilter>
</ldapDestinationService>
Properties¶
We will now define properties:
<propertiesBasedSyncOptions>
...
</propertiesBasedSyncOptions>
Main properties¶
We define mainIdentifier and conditions:
<mainIdentifier>js:"cn=" + javax.naming.ldap.Rdn.escapeValue(srcBean.getDatasetFirstValueById("cn").toLowerCase()) + ",ou=groups,dc=example,dc=com"</mainIdentifier>
<defaultDelimiter>;</defaultDelimiter>
<defaultPolicy>FORCE</defaultPolicy>
<conditions>
<create>true</create>
<update>true</update>
<delete>true</delete>
<changeId>true</changeId>
</conditions>
Object Class¶
We force the values of objectClass attribute:
<dataset>
<name>objectclass</name>
<policy>KEEP</policy>
<createValues>
<string>"groupOfNames"</string>
<string>"top"</string>
</createValues>
</dataset>
member¶
We convert uid values into DN:
<dataset>
<name>member</name>
<policy>FORCE</policy>
<forceValues>
<string>
<![CDATA[rjs:
var membersSrcUid = srcBean.getDatasetValuesById("memberUid");
var membersDstDn = new java.util.ArrayList();
for (var i=0; i<membersSrcUid.size(); i++) {
var memberSrcUid = membersSrcUid.get(i);
var dn = "uid=" + memberSrcUid + ",ou=users,dc=example,dc=com";
membersDstDn.add(dn);
}
membersDstDn
]]>
</string>
</forceValues>
</dataset>
Some explanations on this script:
We get uid of members in source in
membersSrcUid
For each value, the corresponding DN is built with a simple concatenation
The DN is inserted into
membersDstDn
arrayThe
membersDstDn
array is returned to LSC