ActiveDirectory & LDAP provisioning
The Memority’s ActiveDirectory & LDAP connector can be used to provision an ActiveDirectory or any LDAP directory. However, some prerequisites must be respected to be able to provision the application.
This page explains how the provisioning works in Memority and prerequisites to be able to provision an application.
Definitions
What is a provisioning ?
Provisioning is used to automatically create, update and deactivate/delete accounts in target application and ensure that data are consistent between Memority (the authoritative source) and the application (the target).
It means that once Memority provisions your application, you shouldn't perform any creation, modification or deactivation/deletion of accounts directly in the application, it will be done automatically for you.
Memority ActiveDirectory & LDAP connector
The Memority ActiveDirectory & LDAP connector is used to create, update and at the end deactivate/delete objects in a target application (user accounts, groups or organizations) thanks to LDAPS commands.
The ActiveDirectory & LDAP connector, like any of others Memority connectors, computes delta between Memority data and target data at each event occurring on the Memority object to determine the action to perform:
- Create an new object 
- Link an existing object 
- Update an existing object 
- Delete / Deactivate an existing object 
To perform these actions, the Memority ActiveDirectory & LDAP connector works thanks to 5 methods that must be defined in the configuration : SEARCH, GET, CREATE, UPDATE and DELETE.
When an event is detected on an object, and that event impacts the provisioning because it has been defined in mapped attributes, then the following process will be triggered:
- If an application’s object is already linked to the Memority’s object, then the connector use GET method to check if there is delta between Memority and application object 
- If a Memority’s object to provision is not linked to an existing application' object, then the connector use SEARCH method to check if there is already an existing application object matching SEARCH method 
- Whenever an action method is called (CREATE, PATCH or DELETE), a GET action is performed after that to validate the provisioning worked well. It means there 3 requests for each action performed by the connector. 
- When the identity authorization is removed, the connector will use the DELETE method to deactivate or delete the account in the application. 
Memority accesses to the schema of the directory and so is able to provision custom attributes.
The correlation key between Memority and ActiveDiretory account is the ObjectID, so even if the ActiveDirectory account is moved or modified locally, Memority will be able to find it and overwrite modifications.
The correlation key between Memority and LDAP account is the DN, so even if the ActiveDirectory account is moved or modified locally, Memority will be able to find it and overwrite modifications through the search method.

The Memority REST connector provisioning process
ActiveDirectory & LDAP authentication prerequisites
To be able to requests directory actions, Memority’s connector need to authenticate against the application. The ActiveDirectory & LDAP connector bind to targeted directory in LDAPS thanks to an IPSec tunnel set between Memority’s network and client’s network.
To be able to set the LDAPS binding, Memority must trust the whole certificate chain that generated the directory SSL certificate. So any private root certificate must be added to the dedicated Synchronization service setting sync.ssl.trust.trustStore to be trusted.
The connector bind with an account that should have administration rights on the account. The provisioning account’s password shouldn’t expire to avoid any issue.
| ID | Pre-requisites | 
|---|---|
| AUTH1 | An IPSec tunnel must be set between Memority’s network and client’s directory network. | 
| AUTH2 | SSL Root & Intermediate AC certificates must be trusted by Memority when using LDAPS protocol. | 
| AUTH3 | A provisioning account must be created with a password to authenticate (the connector uses DN as login and the password). | 
| AUTH4 | The provisioning account must have domain administrator rights, or at least these rights: · Create, delete and manage user accounts · Reset user passwords and force password change at next logon · Read all user information · Create, delete and manage groups · Modify the membership of a group · Create, delete and manage inetOrgPerson accounts · Reset inetOrgPerson accounts and force password change at next logon · Read all inetOrgPerson information | 
| AUTH5 | The provisioning account’s password must have an entropy greater than 150 bits and shouldn’t automatically expire to avoid provisioning outage. | 
ActiveDirectory configuration prerequisites
Memority ActiveDirectory connector officially supports versions since Windows Server 2019.
The schema must be readable by the provisioning account to be able to get existing attributes.
| ID | Pre-requisites | 
|---|---|
| CONF1 | The ActiveDirectory version should be Windows Server 2019 or latest. | 
| CONF2 | The schema must be readable by the provisioning account. | 
| CONF3 | The Global Catalog URL is required in case of a forest setup. | 
Configuration
Connector configuration
To be able to provision or import data from an ActiveDirectory or a LDAP directory, you first need to configure a connector to establish a connection to it.
This chapter will give you information about ActiveDirectory & LDAP connector configuration, you can get global information about connector configurations in Application Connector.

Example of ActiveDirectory & LDAP connetor configuration
Bear in mind that if your directory is not published on internet, you will need to first request an IPSec tunnel setup to be able to join the directory from Memority as explained in prerequisite AUTH1.
More information in Memority Support Portal
Binding configuration
To configure the connector, you will need to define a set of properties specified below.
We strongly advise to use settings to specify these properties and be able to switch them per environment.
To use a setting in a connector, set the value as “settings:” + the setting’s identifier.

Example of property set with a setting
| Property | Description | Example | 
|---|---|---|
| host | The FQDN of the server to bind. | 
 | 
| port | The port to bind, usually 636, or 389 for non-production testing. See SSL configuration for more information. | 636 | 
| servers (multi-valued) | List of secondary servers. Their purpose may be: 
 A server syntax is typically:  For a multi-Domain Active Directory Environment, a server syntax is typically:  In fact, every configuration parameter (host, port, bindDn, baseContext, etc.) can be overridden in a “server” definition, using the syntax:  Since  
        CODE
      | 
 
 | 
| bindDn | The provisioning account DN to use for binding. It must respects prerequisites AUTH3, AUTH4 and AUTH5 | 
 | 
| bindPassword | The provisioning account password. Use a secret setting to store it securely. | *** | 
| baseContext | Used as base context for all LDAP searches. Objects out of the base context scope cannot be managed, including groups to be assigned to accounts. Use a large scope and filter it if necessary. | 
 | 
| connectTimeout | The TCP connect and read timeouts in milliseconds. Set to 5000 by default. If a LDAP search takes time, it may be necessary to increase it. | 5000 | 
TLS configuration
The connector can be configured to use TLS or not. Both alternatives are described below.
The TLS is mandatory for production environments.
ActiveDirectory doesn’t allow account’s password provisioning if the TLS connection is not set.
Without TLS
To configure the connector, you will need to define a set of properties specified below.
To bind to the directory without TLS, the port 389 is typically used. The IPSec tunnel must be configured to allow connections to the 389 port.
| Property | Description | Example | 
|---|---|---|
| port | The port to bind (usually 389) | 389 | 
| connectionSecurity | The security to use for the binding, in this context it must be set to “none” | none | 
With TLS
To configure the connector, you will need to define a set of properties specified below.
To bind to the directory with TLS, the port 636 is typically used. The IPSec tunnel must be configured to allow connections to the 636 port.
To be able to authenticate, the connector must be able to validate the server’s TLS certificate chain. If the certificate has been generated from a custom authoritative certification, you need to set the Root and intermediate certificate in SYNC service setting sync.ssl.trust.trustStore.

Setting sync.ssl.trust.trustStore setting to add root and intermediate certificate
| Property | Description | Example | 
|---|---|---|
| port | The port to bind (usually 636) | 636 | 
| connectionSecurity | The security to use for the binding, in this context it must be set to “ssl” | ssl | 
| allowUntrustedSsl | Boolean to indicate if the certificate’s chain must be validated. Set to false for production environments. | false | 
Custom attributes
The LDAP connector refers to the LDAP schema corresponding to the LDAP class configured in the Application’s ObjectSchema, e.g. inetOrgPerson for users. This means that only those LDAP attributes explicitly associated with the LDAP class inetOrgPerson will be visible from the LDAP connector. If it is necessary to fetch/write other LDAP attributes that are not explicitly associated with the LDAP class, those other attributes must be configured using the operationalAttributes property, as shown below:
| Property | Description | Example | 
|---|---|---|
| operationalAttributes | The list of attributes complementing the LDAP schema, separated by commas | objectClass,customAttribute1,customAttribute2 | 
Additional Search Filter
By default, when importing objects into Memority from a LDAP source, all LDAP objects matching the configured LDAP class are searched under baseDn. This scope may be too wide, and yield too many entries. To narrow this scope, it is possible to configure a search filter that is systematically added to all LDAP search performed by the connector. This property is described below:
| Property | Description | Example | 
|---|---|---|
| additionalSearchFilter | A LDAP filter to filter objects to retrieve. | (objectCategory=person) | 
Next chapters will give you some common configurations examples.
Object filter is apply on imports/account discovery tasks and on provisioning. Any object outside the scope cannot be managed by the connector, included groups to assigned to accounts.
If you want different scopes for provisioning and imports/account discovery, you can use objectIgnoredCondition in application configuration (Object Schema Mapping Definition) or duplicate the connector configuration.
Filter on user account only
You can use the following filter on objectCategory attribute to get only user accounts from an ActiveDirectory.
(objectCategory=person)Filter on organizational units
You can use the following filter on msDs-parentdistname attribute to get objects from a specific organization unit from an ActiveDirectory (it must be specified with its DN).
(msDs-parentdistname=OU=Users,DC=internal,DC=my,DC=com)Filter on group assigned
You can use the following filter on memberOf attribute to get accounts directly assigned to a group from an ActiveDirectory (it must be specified with its DN).
(memberOf=CN=MyApp-User,OU=applications,DC=internal,DC=my,DC=com)
To get any account assigned to the group, even through nested groups, you need to filter on memberOf:1.2.840.113556.1.4.1941: (memberOf:1.2.840.113556.1.4.1941:=CN=MyApp-User,OU=applications,DC=internal,DC=my,DC=com)
Application configuration
To be able to provision or import data from an ActiveDirectory or a LDAP directory, you need to configure a data model mapping.
This chapter will give you information about ActiveDirectory & LDAP specific attribute mapping , you can get global information about application configurations in Application.
Distinguished Name definition
The Distinguished Name (DN) is a mandatory attribute that should be unique in the directory.
The distinguished name attribute is used as correlation key, so you need to define the target attribute to __NAME__.
The value can be set directly thanks to a simple or a custom mapping, but you can also use the built in constructDnFromRdnOpenAm normalization rule.
The connector handle automatically object move in case of DN modification, there is no particular action to do.
<attributeMappingDefinition>
	<targetAttributeId>__NAME__</targetAttributeId>
	<targetAttributeType>STRING</targetAttributeType>
	<mandatory>true</mandatory>
	<simpleAttributeMappingStrategyDefinition>
		<inputAttributeId>id</inputAttributeId>
		<normalizeRule class="constructDnFromRdnOpenAm">
			<config xsi:type="dmn:ConstructDnFromRdnOpenAmRuleConfigurationType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
				<baseDn>ou=Users,dc=internal,dc=my,dc=com</baseDn>
				<rdnAttributeName>uid</rdnAttributeName>
			</config>
		</normalizeRule>
	</simpleAttributeMappingStrategyDefinition>
	<multiValued>false</multiValued>
</attributeMappingDefinition>Account status
The account status is managed in ActiveDirectory thanks to attribute userAccountControl. This attribute is a bit mask to determine account status and more information such as password expiration (UserAccountControl property flags - Windows Server | Microsoft Learn)
To manage the account status, you can set the default value according to enable status (512 for active accounts, 514 for inactive accounts).
<attributeMappingDefinition>
	<targetAttributeId>userAccountControl</targetAttributeId>
	<targetAttributeType>INTEGER</targetAttributeType>
	<mandatory>true</mandatory>
	<secret>false</secret>
	<customAttributeMappingStrategyDefinition>
		<computeRule>
			<script><![CDATA[
					return IDM_OBJECT.enabled as Boolean ? "512" : "514"
				]]></script>
		</computeRule>
		<computeRuleAttributeDependencies>
			<dependency>enabled</dependency>
		</computeRuleAttributeDependencies>
	</customAttributeMappingStrategyDefinition>
	<multiValued>false</multiValued>
</attributeMappingDefinition>You can also use mask computation to enable and disable the account without modifying other flags.
<attributeMappingDefinition>
	<targetAttributeId>userAccountControl</targetAttributeId>
	<targetAttributeType>INTEGER</targetAttributeType>
	<mandatory>true</mandatory>
	<secret>false</secret>
	<customAttributeMappingStrategyDefinition>
		<computeRule>
			<script><![CDATA[
					def userAccountControl = SHADOW.userAccountControl as int
					def enabled = IDM_OBJECT.enabled as boolean
					def disabledMask = 2
					def accountEnabled = ((userAccountControl & disabledMask) != disabledMask)
					// If account status == memority status, return the userAccountControl as is
					if (enabled == accountEnabled) {
						LOG.debug("Provisioning AD User - userAccountControl - {} - No status modification", IDM_OBJECT.id)
						return userAccountControl
					}
					// If account account should be disabled, return userAccountControl + disable mask
					if (!enabled) {
						LOG.debug("Provisioning AD User - userAccountControl - {} - Disable account", IDM_OBJECT.id)
						return (userAccountControl | disabledMask)
					}
					// If account account should be enabled, return userAccountControl - disable mask
					if (enabled) {
						LOG.debug("Provisioning AD User - userAccountControl - {} - Enable account", IDM_OBJECT.id)
						return (userAccountControl ^ disabledMask)
					}
				]]></script>
		</computeRule>
		<computeRuleAttributeDependencies>
			<dependency>enabled</dependency>
		</computeRuleAttributeDependencies>
	</customAttributeMappingStrategyDefinition>
	<multiValued>false</multiValued>
</attributeMappingDefinition>Password management
Password are managed in ActiveDirectory with attribute unicodePwd. You can also use attribute pwdLastSet to force the password modification on first connection.
These attributes can be set with a mappingStrength option set to WEAK to be applied only on account creation. Thanks to this, users will be able to manage their passwords autonomously.
The Memority password can be used directly, or you can use a new attribute to generate and store a dedicated password. In this case, be sure to set the attributeDefinition as secret and encrypted and use PASSWORD binding to generate it.
Set the unicodePwd mapping as secret to hide the password in audit, logs and reports.
The password modification requests a SSL binding due to ActiveDirectory policies.
<attributeMappingDefinition>
	<targetAttributeId>unicodePwd</targetAttributeId>
	<targetAttributeType>STRING</targetAttributeType>
	<mandatory>false</mandatory>
	<secret>true</secret>
	<simpleAttributeMappingStrategyDefinition>
		<inputAttributeId>password</inputAttributeId>
	</simpleAttributeMappingStrategyDefinition>
	<multiValued>false</multiValued>
	<mappingStrength>WEAK</mappingStrength>
</attributeMappingDefinition>
<attributeMappingDefinition>
	<targetAttributeId>pwdLastSet</targetAttributeId>
	<targetAttributeType>INTEGER</targetAttributeType>
	<mandatory>false</mandatory>
	<secret>false</secret>
	<customAttributeMappingStrategyDefinition>
		<computeRule>
			<script><![CDATA[
				// Set the value to 0 to force password modification on first connection
				return 0
				]]></script>
		</computeRule>
		<computeRuleAttributeDependencies/>
	</customAttributeMappingStrategyDefinition>
	<multiValued>false</multiValued>
	<mappingStrength>WEAK</mappingStrength>
</attributeMappingDefinition>Migrating Users From Active Directory Domains Within the Same Forest
This section describes the Memority Active Directory connector configuration enabling to migrate users from one Active Directory Domain to another within the same Forest. Only “intra Forest” migration is currently supported, i.e. Domains must all belong to the same Forest. “Inter Forest” migration (involving several Forests) is not supported for now.
Furthermore, only users can be migrated; computers and other resources cannot be migrated for now.
So, the Active Directory Domain migration feature has the following limitations:
- intra-Forest (same Forest) 
- for users only 
Prerequisites
Some technical prerequisites are required to migrate users from AD Domains: ADMT and OpenSSH.
ADMT
It is not possible to move a user from Windows Domains with the LDAP protocol, more precisely with the ModifyDNRequest LDAP command specified by RFC 2251. The Active Directory Migration Tool (ADMT) version 3.2 must be used to migrate users from Domains. ADMT also enables to preserve Domain permissions and user passwords, ensuring “user continuity” upon Domain migration.
When users are migrated from a source Domain to a target Domain, ADMT 3.2 must be installed on each target Domain Controller. ADMT does not need to be installed on a source Domain Controller, unless it later becomes a migration target.
This guide does not provide the ADMT installation procedure, one must refer to the Microsoft documentation.
OpenSSH
The Memority AD connector executes remotely ADMT on each Domain Controller, using the ssh protocol. OpenSSH must thus be enabled on Domain Controllers, and its port (usually 22) must be accessible from the Memority AD connector.
OpenSSH is now a standard service of Windows Server, one must refer to the Microsoft documentation to enable it.
Memority AD Connector Configuration
The following table lists AD Connector properties pertaining to the AD Domain migration. They come in addition to the AD connector properties described in the previous sections.
Some properties such as host are repeated here, to emphasis their specific role regarding the Domain migration.
In this example, a root Domain memority.local has 2 child Domains: child1.emority.local and child2.memority.local.
The Administrator account memority.local\Administrator can manage all Domains of the Forest.
| Property | Type | Description | Mandatory | Default Value | Example | 
|---|---|---|---|---|---|
| host | string | A Domain Controller host belonging to the Forest’s root Domain. | Yes | N/A | memority.local | 
| port | integer | The port of the Domain Controller host belonging to the Forest’s root Domain. | No | 389 | N/A | 
| baseDn | string | The Forest root Domain | Yes | N/A | DC=memority,DC=local | 
| bindDn | string | The LDAP account used by the AD connector | Yes | N/A | CN=Administrator,CN=Users,DC=memority,DC=local | 
| globalCatalogServers | multi string | One more Forest Global Catalog. Their syntax is the same as  | Yes | N/A | host=memority.local;port=3269 | 
| servers | multi string | Yes | N/A | baseContext=DC=child1,DC=memority,DC=local;host=child1.memority.local;port=636 baseContext=DC=child1,DC=memority,DC=local;host=child2.memority.local;port=636 | |
| searchWithGlobalCatalog | boolean | Whether to use the Global Catalog when searching entries. This does not concern searches by GUID or by DN. | No | 
 | N/A | 
| allowDomainMigration | boolean | Whether to allow migration of users from Domains. | No | 
 | N/A | 
| ADMTPath | string | The absolute path to admt.exe. Not needed with a standard ADMT install. | No | 
 | C:\Windows\ADMT\admt.exe | 
| keepSameGroupsOnDomainMigration | boolean | Whether groups are retained upon Domain migration. | No | 
 | N/A | 
| sshPort | integer | The ssh port. | No | 22 | N/A | 
| sshAuthenticationMethod | string | The ssh authentication method. Possible values:  Only  | No | 
 | N/A | 
| sshUsername | string | The ssh username used to authenticate to the remote Domain Controllers to execute PowerShell commands. If not configured, it is constructed using the LDAP credentials configured in  | No | <root domain>\<bindDn> | memority.local\Administrator | 
| sshPassword | string | The ssh authentication password. | No | Same value as  | N/A | 
| sshKeyExchangeAlgorithms | multi string | ssh key exchange algorithms, for example: "ecdh-sha2-nistp521". The advertised key exchange algorithms can be obtained via the command:  The possible values are all listed in the “Default Value” column. | No | diffie-hellman-group1-sha1 diffie-hellman-group14-sha1 diffie-hellman-group14-sha256 diffie-hellman-group16-sha512 diffie-hellman-group18-sha512 diffie-hellman-group-exchange-sha1 diffie-hellman-group-exchange-sha256 ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 | ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 | 
| sshKeyAlgorithms | multi string | Host ssh key algorithms (aka server key type), for example: "ecdsa-sha2-nistp384" The advertised key exchange algorithms can be obtained via the command:  The possible values are all listed in the “Default Value” column. | No | ssh-rsa ssh-dss rsa-sha2-51 rsa-sha2-256 ssh-ed25519 ecdsa-sha2-nistp521 | ecdsa-sha2-nistp384 | 
