Cool Solution - Sync Users and Groups into a second Domain

This article describes how to import users, simple authentication accounts and groups from one domain into another through a synchronization system. The implementation keeps the target system in sync with the source system (One-Way Synchronization).

For this setup to work, the external target system can be unable to reach the internal source system. However, the internal source system must be able to gain SSH access to the target. This solution is especially helpful to keep a server in the DMZ up-to-date with changes to users and groups in an internal, inaccessible UCS environment. Both systems are allowed to have different LDAP bases.

Warning: Existing users, simple authentication account and groups on the target system might be overwritten by this synchronization system. This solution offers a One-Way Synchronization Service, which means that objects created locally inside the target LDAP system are not protected.

Prerequisites

Please note that the target system needs the same Mail Domains to be able to import Users with set E-Mail addresses. These can be easily created through the UMC module Mail with the Mail domain object type.

Also all Containers and Organisational Units containing to be synced objects have to be manually created on the target system.

If needed, it is additionally possible to synchronize User Certificates from the Cool Solution - Creation and management of user and Windows certificates. For this to work, the target system at minimum needs the package 'univention-ldap-usercert’ installed. Additionally, the feature has to be enabled through UCR attribute ldap/sync/certificates on the target system.

Note that, by default, the following attributes are synchronized:

  • Birthdate
  • Description
  • Display name
  • First name
  • Last name
  • Primary e-mail address
  • Password
  • Title
  • User name
  • User Certificate (see above)

Installation

To install the packages you first need to enable the Cool Solution repository.

For the basic functionality there are two packages. One on the source and one on the destination system.

Install the destination package on the target UCS system:

univention-install univention-user-group-sync-dest

This package will create a local service user called ‘ucs-sync’, which the leading UCS system will transfer it’s data through. A password will be generated and written to /etc/univention-user-group-sync-dest.secret, as the leading system needs to create a SSH connection during it’s package installation for one time. Afterwards, the password isn’t needed anymore. The leading UCS system will authorize itself through an identity key.

Now, install the source package on the leading UCS system. Please refer to “Installation on DC Slave or Member” now if you want to install the source package on such a system.
If you want the package to determine which objects to sync by a specific LDAP attribute added to user and group objects, instead of either syncing all or using a LDAP filter, read and execute the steps in this paragraph Activate sync for objects by LDAP attribute first.

univention-install univention-user-group-sync-source

After the installation the hostname or IP address of the target UCS system has to be configured. Further, the SSH identity file of the user ‘ucs-sync’ has to be transferred to the destination system to enable the sync mechanism.

Copy the identity file. Replace with the IP or hostname of your destination host. You will be prompted for the password of the user ucs-sync on the destination host, which can be found in the file /etc/univention-user-group-sync-dest.secret on the destination host. This command must be executed on the source host.

ssh-copy-id -i /var/lib/univention-user-group-sync/.ssh/id_rsa -o StrictHostKeyChecking=no -o PubkeyAuthentication=no ucs-sync@"DESTINATION HOST"

Set the destination the sync mechanism shall use. This has to be executed on the source host. Replace “DESTINATION HOST” with the IP or hostname of your destination host.

ucr set ldap/sync/destination="DESTINATION HOST"

After successful installation and configuration, the univention-directory-listener service will automatically create files for all user and group objects below the LDAP base. Afterwards, every object change will be tracked.

These files are automatically transferred by a cron job of the leading UCS system and imported again through another cron job of the target UCS system. Both cron jobs are executed every 5 minutes, which can be changed below.

The temporary files can be found in folder /var/lib/univention-user-group-sync/, if needed.

Installation on DC Slave or Member

If you installed the package on a UCS DC slave or member server, please run the joinscripts manually:

univention-run-join-scripts

Advanced Configuration

Add Attributes to be synchronized

By default, only the above mentioned attributes will be synchronized. It is possible to define additional attributes for user accounts, even custom created ones.
For this we need to configure a mapping of the LDAP attribute name to UDM name, as these can be different and are not known by the package .

Use the following UCR variable on the destination system to configure a comma-separated mapping list of attributes to be added (Mapping format: “LDAP-Attribute:UDM-Attribute”):

ucr set ldap/sync/add/user/attribute="o:organisation,univentionFreeAttribute1:JobTitle"

Note that these attribute names are case-sensitive.

Filter the LDAP objects to be synchronized

By default, all user and group objects below the LDAP base will be synchronized. It is possible to limit the range to be synchronized with an LDAP filter set through the UCR attribute ldap/sync/filter. Note: The LDAP filter set won’t replace the default filter, but append to it as a second filter.

The default filter: (&(|(&(objectClass=posixAccount)(objectClass=shadowAccount))(objectClass=univentionMail)(objectClass=sambaSamAccount)(objectClass=simpleSecurityObject)(objectClass=inetOrgPerson)(objectClass=univentionGroup))(!(objectClass=univentionHost))(!(univentionObjectFlag=hidden))(!(uidNumber=0))(!(uid=*$))).

Activate sync for objects by LDAP attribute

There is a schema extension which adds a boolean attribute to users and groups. This appears in the UMC in the tab Advanced settings as a checkbox. It can be used to activate certain objects for the sync without modifying the configured LDAP filter every time.

Please note that if the checkbox is activated after an object has been created, a resync for the univention-user-group-sync listener module is performed and saving the object will therefore take a bit longer than usual. Resync means that all objects relevant for the univention-user-group-sync listener module are fed to it again. This is required because the listener module would otherwise not know of an Add operation for the object that was just activated for the sync, only of an Modify operation. Of course this Modify would fail on the destination system because the object has not yet been created there. So with this resync we make sure that all objects are actually created before the script tries to modify them with new values.

Please note also that you don’t need to install univention-user-group-sync-source-schema on the destination system. The attribute and objectClass contained in this package are removed from the objects before they are written to the destination LDAP.

To use this feature a new package must be installed on the UCS DC Master and the LDAP filter used by univention-user-group-sync-source must be modified on the source system:

univention-install univention-user-group-sync-source-schema

Run the joinscript

univention-run-join-scripts

Set the filter

ucr set ldap/sync/filter="(univentionUserGroupSyncEnabled=TRUE)"

Remove attributes/objectClasses before sync

If you have LDAP schemata that aren’t installed in the destination domain in your source domain, you might want to remove attributes and object classes of these schemata from objects before they’re being synced. The import of objects with attributes or object classes from schemata that aren’t installed will fail in the destination domain.

Blacklist

Use the following UCR variables on the source system to configure a comma-separated list of attributes/object classes to be removed (blacklist):

ucr set ldap/sync/remove/objectClass="foo,bar"
ucr set ldap/sync/remove/attribute="foo,bar"

Whitelist

Alternatively, you can also define a whitelist:

ucr set ldap/sync/whitelist/objectClass="foo,bar"
ucr set ldap/sync/whitelist/attribute="foo,bar"

Map source LDAP base(s) to destination OU(s)

By default all objects are created in the destination system in the same position in the LDAP tree as on the source system. Only the LDAP base is changed.
You can also configure a mapping of source LDAP bases to OUs on the destination system to have the objects from a certain LDAP base created below an OU. This mechanism is configured via UCR on the destination system:

ucr set ldap/sync/mapping/base2ou/=""

Note that dc= must be removed and ,dc= must be changed to a dot. E.g.:

dc=ucs,dc=foobar becomes ucs.foobar

So to create objects coming from the LDAP base dc=ucs,dc=foobar in the OU “foobar” in the destination LDAP tree you’d have to create a variable as follows:

ucr set ldap/sync/mapping/base2ou/ucs.foobar="foobar"

Please note that you need to create the OUs and also any CNs where objects are synced from below the OU manually in the destination LDAP tree. By default those CNs are users and groups.

Add prefix to user and group names

By default users and groups have the exact same name (uid/cn) in the destination system as in the source system. This can be a problem, if you want to sync users from multiple sources into one destination and can’t guarantee that there won’t be collisions/duplicates. To ensure that there won’t be duplicates you can add a prefix to user and group names in the source system using UCR:

ucr set ldap/sync/prefix='myPrefix_'

The prefix must only contain these characters:

a-z A-Z 0-9 . - _

This prefix will now be added to every user and group processed by univention-user-group-sync-source. Note that existing users and groups in the destination will not be renamed! Instead new users and groups with the prefixed name will be created. Therefore it is highly recommended to configure a prefix right from the start and not add it at a later point when users and groups might have already been synchronized to the destination.
To rename users and groups below an OU used in a LDAP base to OU mapping, the following commands can be used:

#Set these two accordingly
sourceDomain=ucs.foobar
prefix="myPrefix_"

ou=$(ucr get ldap/sync/mapping/base2ou/${sourceDomain})
base=$(ucr get ldap/base)
DNs=$(univention-ldapsearch -LLL -b "ou=${ou},${base}" uid=* dn | grep dn: | sed 's/dn:\ //')

for dn in ${DNs}; do oldUsername=$(univention-ldapsearch -LLL -b ${dn} uid | grep uid: | sed 's/uid:\ //'); newUsername="${prefix}${oldUsername}"; echo "Setting new username ${newUsername} for object with DN ${dn}"; udm users/user modify --dn ${dn} --set username="${newUsername}"; done

Adjust the synchronization times

The synchronization processes for data transfer and data import are executed every five minutes on both systems. This means, that it can - in theory - take almost up to 10 minutes for an object to be existent on the destination system after it’s initial creation.

The process timings can be adjusted through UCR attributes. Attribute cron/ldap-sync-src/time is available on the source UCS system to adjust the data transfer process.

The data import process timing can be adjusted through UCR attribute cron/ldap-sync-dest/time.

Resynchronize all Users and Groups

The following command can be used on the source system to regenerate all files for all user and group objects. Please replace the LDAP filter for users= and groups= if you don’t use univention-user-group-sync-source-schema!

univention-directory-listener-ctrl resync univention_user_group_sync_source_generate

Errors

Object class violation

On the destination system this error can happen during the import of files. It means that there is a difference between the object classes in the LDAP object from the file currently being imported and the object in the LDAP of the destination system. The reason for this is usually that there are attributes set only on the source or only the destination but not on the respective other system.

For example on the destination system a user might have the objectClass classOne, which comes from the attribute attributeOne being set. The user is being synced by univention-user-group-sync. On the source system the user does not have this attribute set. Therefore both the attribute and objectClass are missing in the files coming from the source for this user. This results in the destination trying to modify the object classes and removing classOne. Since attributeOne is still set and not being removed because it simply does not appear in the imported file at all, LDAP won’t allow the modification and throw an object class violation.

Find out which objectClass the error refers to by checking the log /var/log/univention/user-group-sync.log for messages starting with Different objectClasses detected. The problematic ones are the ones only showing up in one of the logged lists.

Then add the problematic objectClass(es) to UCR on the destination as follows. The UCR variable has values assigned by default, therefore we add these at the end of the ucr set command, to make sure we append classOne instead of overwriting the variable with it.

 ucr set ldap/sync/ignore_error/objectClass_difference=classOne,$(ucr get ldap/sync/ignore_error/objectClass_difference)

“ldap.DECODING_ERROR”

This error occurs if an object couldn’t be created in the destination system because of a malformed DN. The cool solution currently only allows the following characters in user and group names. There probably was a character outside this range in the source file. The path to the file and the DN should be printed along with the error, allowing you to debug it.

a-z A-Z 0-9 . - _ *SPACE*

“LDAP_Error: No such object”

This error occurs if an object couldn’t be created, because a container is missing in the structure below. The object path that was last tried to create can be found either in the log file /var/log/univention/user-group-sync.log or in the first temporary file in folder /var/lib/univention-user-group-sync/
Please manually create all missing container objects in the object’s path.

“LDAP_Error: Invalid syntax”

This error occurs if an object contains an unknown attribute or objectClass. This happens for all extended ones that aren’t implemented on the destination host.
Those attributes/objectClasses can be removed before sync as detailed further above.

Figuring out which objectClass is responsible for this error might be a bit difficult, if it only mentions something like “objectClass: value #3”. See “Decode files for debugging” for a way to find out which objectClass the error refers to.

Decode files for debugging

The following code can be used to decode the given temporary file. This can help identifying which objectClass the error refers to (The path to the temporary file has to be replaced before execution):

/usr/bin/python
path = "/var/lib/univention-user-group-sync/TEMPORARY.FILE"
from pprint import pprint
import cPickle as pickle
raw_data = open(path, 'rb').read()
data = pickle.loads(raw_data)
pprint(data)
exit()
Mastodon