ICF 1.5.20.26

LDAP connector

The LDAP connector is based on the Java Naming and Directory Interface (JNDI), and can connect to any LDAPv3-compliant directory server, such as PingDS (DS), Active Directory, SunDS, Oracle Directory Server Enterprise Edition, IBM Security Directory Server, and OpenLDAP.

Because it is based on JNDI, the LDAP connector is restricted to the attribute types that are supported by JNDI. JNDI supports only strings and an array of bytes. If you attempt to use different attribute value types, the connector throws a malformed attribute value exception. Learn more in the corresponding JNDI documentation.

Install the LDAP connector

If you are looking for the Advanced Identity Cloud application for this connector, refer to:

You can download any connector from Backstage, but some are included in the default deployment for Advanced Identity Cloud, IDM, or RCS. When using an included connector, you can skip installing it and move directly to configuration.

Connector included in default deployment
Connector IDM RCS

Yes

Yes

Download the connector .jar file from Backstage.

  • If you are running the connector locally, place it in the /path/to/openidm/connectors directory, for example:

    mv ~/Downloads/ldap-connector-1.5.20.26.jar /path/to/openidm/connectors/
  • If you are using a remote connector server (RCS), place it in the /path/to/openicf/connectors directory on the RCS.

Configure the LDAP connector

Create a connector configuration using the IDM admin UI:

  1. From the navigation bar, click Configure > Connectors.

  2. On the Connectors page, click New Connector.

  3. On the New Connector page, type a Connector Name.

  4. From the Connector Type drop-down list, select LDAP Connector - 1.5.20.26.

  5. Complete the Base Connector Details.

    For a list of all configuration properties, refer to LDAP Connector Configuration
  6. Click Save.

When your connector is configured correctly, the connector displays as Active in the admin UI.

Refer to this procedure to create a connector configuration over REST.

Alternatively, configure the connector with a configuration file. IDM provides several sample LDAP connector configurations in the path/to/openidm/samples/example-configurations/provisioners/ directory. Copy one of the sample connector configurations to your project’s conf directory, and adjust it to match your LDAP environment:

  • provisioner.openicf-ldap.json—a sample LDAP connector configuration for a generic LDAP server.

  • provisioner.openicf-dsldap.json—a sample LDAP connector configuration for a PingDS (DS) server.

  • provisioner.openicf-adldap.json—a sample LDAP connector configuration for an Active Directory server.

You should be able to adapt one of these sample configurations for any LDAPv3-compliant server.

Sample LDAP connector configuration

This configuration shows the properties for an LDAP connector connecting to DS. For more information about the properties that affect synchronization, refer to Control what the LDAP connector synchronizes. For a complete list of the configuration properties for the LDAP connector, refer to LDAP Connector Configuration:

"configurationProperties" : {
    "host" : "localhost",
    "port" : 1389,
    "ssl" : false,
    "startTLS" : false,
    "privateKeyAlias" : null,
    "alternateKeyStore" : null,
    "alternateKeyStoreType" : null,
    "alternateKeyStorePassword" : null,
    "principal" : "uid=admin",
    "credentials" : "password",
    "baseContexts" : [
        "dc=example,dc=com"
    ],
    "baseContextsToSynchronize" : [
        "dc=example,dc=com"
    ],
    "accountSearchFilter" : null,
    "accountSynchronizationFilter" : null,
    "groupSearchFilter" : null,
    "groupSynchronizationFilter" : null,
    "removeLogEntryObjectClassFromFilter" : true,
    "modifiersNamesToFilterOut" : [ ],
    "changeLogBlockSize" : 100,
    "attributesToSynchronize" : [ ],
    "changeNumberAttribute" : "changeNumber",
    "filterWithOrInsteadOfAnd" : false,
    "objectClassesToSynchronize" : [
        "inetOrgPerson"
    ],
    "vlvSortAttribute" : "uid",
    "passwordAttribute" : "userPassword",
    "useBlocks" : false,
    "maintainPosixGroupMembership" : false,
    "failover" : [ ],
    "readSchema" : true,
    "accountObjectClasses" : [
        "top",
        "person",
        "organizationalPerson",
        "inetOrgPerson"
    ],
    "accountUserNameAttributes" : [
        "uid"
    ],
    "groupMemberAttribute" : "uniqueMember",
    "passwordHashAlgorithm" : null,
    "usePagedResultControl" : true,
    "blockSize" : 100,
    "uidAttribute" : "entryUUID",
    "maintainLdapGroupMembership" : false,
    "respectResourcePasswordPolicyChangeAfterReset" : false
},
host

The host name or IP address of the server on which the LDAP instance is running.

port

The port on which the LDAP server listens for LDAP requests. The sample configuration specifies a default port of 1389.

ssl

If true, the specified port listens for LDAPS connections.

For instructions on using the LDAP connector over SSL, refer to Configure the LDAP Connector to Use SSL and StartTLS.

startTLS

Specifies whether to use the startTLS operation to initiate a TLS/SSL session. To use startTLS, set "startTLS":true, and "ssl":false. Your connection should use the insecure LDAP port (typically 389 or 1389 for a DS server).

Specify the certificates that should be used for authentication, as described in Configure the LDAP Connector to Use SSL and StartTLS.

principal

The bind DN that is used to connect to the LDAP server.

credentials

The password of the principal that is used to connect to the LDAP server.

baseContexts

One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member. During reconciliation operations, IDM searches through the base contexts listed in this property for changes. For more information, refer to Control What the LDAP Connector Synchronizes.

baseContextsToSynchronize

One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. During liveSync operations, IDM searches through the base contexts listed in this property for changes. If no value is specified here, the values in listed in the baseContexts property are used. For more information, refer to Control What the LDAP Connector Synchronizes.

accountSynchronizationFilter

Used during synchronization actions to filter out LDAP accounts. For more information, refer to Control What the LDAP Connector Synchronizes.

accountObjectClasses

This property lists all the object classes that represent an account. If this property has multiple values, an AND filter is used to determine the affected entries. For example, if the value of this property is ["organizationalPerson", "inetOrgPerson"], any entry with the object class organizationalPerson AND the object class inetOrgPerson is considered as an account entry. You can override the value of this property by specifying the user object classes during the create operation.

If no object class is specified when you create a user, this property is used as the default list of object classes for the new entry.

accountSearchFilter

Search filter that user accounts must match. For more information, refer to Control What the LDAP Connector Synchronizes.

accountUserNameAttributes

Attributes holding the account’s user name. Used during authentication to find the LDAP entry matching the user name.

attributesToSynchronize

List of attributes used during object synchronization. IDM ignores change log updates that do not include any of the specified attributes. If empty, IDM considers all changes. For more information, refer to Control What the LDAP Connector Synchronizes.

blockSize

Block size for simple paged results and VLV index searches, reflecting the maximum number of entries retrieved at any one time.

changeLogBlockSize

Block size used when fetching change log entries.

changeNumberAttribute

Change log attribute containing the last change number.

failover

LDAP URLs specifying alternative LDAP servers to connect to if IDM cannot connect to the primary LDAP server specified in the host and port properties.

filterWithOrInsteadOfAnd

In most cases, the filter to fetch change log entries is AND-based. If this property is set, the filter ORs the required change numbers instead.

groupMemberAttribute

LDAP attribute holding members for non-POSIX static groups.

groupSearchFilter

Search filter that group entries must match.

maintainLdapGroupMembership

If true, IDM modifies group membership when entries are renamed or deleted.

Does not apply to Active Directory.

In the sample LDAP connector configuration, this property is set to false. This means that LDAP group membership is not modified when entries are renamed or deleted in IDM. To ensure that entries are removed from LDAP groups when the entries are deleted, set this property to true or enable referential integrity on the LDAP server. For information about configuring referential integrity in DS, refer to Referential Integrity in the Configuration Guide for PingDS.

maintainPosixGroupMembership

If true, IDM modifies POSIX group membership when entries are renamed or deleted.

modifiersNamesToFilterOut

Use this property to avoid loops caused by changes made to managed user objects being synchronized. For more information, refer to Control What the LDAP Connector Synchronizes.

objectClassesToSynchronize

IDM synchronizes only entries that have these object classes. For more information, refer to Control What the LDAP Connector Synchronizes.

passwordAttribute

Attribute to which IDM writes the predefined PASSWORD attribute.

passwordHashAlgorithm

Hash password values with the specified algorithm, if the LDAP server stores them in clear text. The only supported algorithm is WIN-AD (used when Active Directory is the target). A blank value indicates the system will not hash passwords. This will cause clear text passwords to be stored in LDAP, unless the LDAP server performs the hash.

readSchema

If true, read the schema from the LDAP server.

This property is used only during the connector setup, to generate the object types.

If this property is false, the LDAP connector provides a basic default schema that can manage LDAP users and groups. The default schema maps inetOrgPerson to the OpenICF __ACCOUNT__ property, and groupOfUniqueNames to the OpenICF __GROUP__ property. The following LDAP object classes are also included in the default schema:

  • organization

  • organizationalUnit

  • person

  • organizationalPerson

  • account

  • groupOfNames

removeLogEntryObjectClassFromFilter

If true, the filter to fetch change log entries does not contain the changeLogEntry object class, and IDM expects no entries with other object types in the change log. The default setting is true.

respectResourcePasswordPolicyChangeAfterReset

If true, bind with the Password Expired and Password Policy controls, and throw PasswordExpiredException and other exceptions appropriately.

uidAttribute

Specifies the LDAP attribute that should be used as the immutable ID for the entry. You can use a DN (or any unique attribute) for the id. As a best practice, you _should use an attribute that is both unique and immutable, such as the entryUUID. For a DS resource, you must use the entryUUID as the uidAttribute, otherwise you might encounter problems with synchronizing delete operations.

useBlocks

If useBlocks is false, no pagination is used. If useBlocks is true, the connector uses block-based LDAP controls, either the simple paged results control, or the virtual list view control, depending on the setting of the usePagedResultControl property.

usePagedResultControl

Taken into account only if useBlocks is true. If usePagedResultControl is false, the connector uses the virtual list view (VLV) control, if it is available. If usePagedResultControl is true, the connector uses the simple paged results control for search operations.

useTimestampsForSync

If true, use timestamps for liveSync operations, instead of the change log.

By default, the LDAP connector has a change log strategy for LDAP servers that support a change log, such as PingDS (DS) and Oracle Directory Server Enterprise Edition. If the LDAP server does not support a change log, or if the change log is disabled, liveSync for create and modify operations can still occur, based on the timestamps of modifications.

Regardless of the useTimestampsForSync value, the connector uses a timestamp strategy for liveSync for the following LDAP server types:

  • MS Active Directory Global Catalog

  • OpenLDAP

  • Unknown

    An LDAP server type is marked Unknown if it is anything other than PingDirectory, IBM, Novell, UnboundID, RedHat/Fedora 389, CA LDAP, OpenDS, PingDS, Sun DSEE Directory, Microsoft Active Directory, Microsoft Active Directory Lightweight Directory Services (LDS), Microsoft Active Directory Global Catalog, or OpenLDAP.
timestampSyncOffset

An optional offset, specified in seconds, that is negatively applied to the timestamp for timestamp-based sync operations. This setting is useful when there are replication delays between LDAP instances. The default value is 0, or no offset.

vlvSortAttribute

Attribute used as the sort key for virtual list view.

sendCAUDTxId

If true, propagate the Common Audit Transaction ID to a DS server.

LDAP remote connector

If you want to run this connector outside of PingOne Advanced Identity Cloud or IDM, you can configure the LDAP connector as a remote connector. Java Connectors installed remotely on a Java Connector Server function identically to those bundled locally within PingOne Advanced Identity Cloud or installed locally on IDM.

You can download the LDAP connector from here.

Refer to Remote connectors for configuring the LDAP remote connector.

Configure the LDAP connector to use SSL and StartTLS

To use the LDAP connector over SSL, update your connector configuration as follows:

  1. For a connection over SSL, set the ssl property to true and set the port to a secure port, for example, 636.

    To initiate a connection using startTLS, set "startTLS":true, and "ssl":false. Set the port to an insecure LDAP port, for example, 389.

  2. If you are using a CA-signed server certificate, add that certificate to the IDM truststore, for example:

    keytool \
     -importcert \
     -alias server-cert \
     -keystore /path/to/openidm/security/truststore \
     -storepass changeit \
     -file /path/to/server-cert.crt
  3. Specify the certificate that the LDAP connector will use to authenticate to the remote LDAP server.

    By default, the LDAP connector uses the self-signed certificate that is generated in the IDM keystore when IDM first starts up. You have two options to change this default behavior:

    • Set the privateKeyAlias to the alias of a certificate in the IDM keystore. The alias name is case-sensitive.

      If you set privateKeyAlias to null, no private key is sent during the SSL handshake, so only the server certificate is used. You must import the server certificate into the IDM truststore, as shown in the previous step.

      If privateKeyAlias is set to an alias within the IDM keystore, the connector uses that private key for SSL mutual authentication.

    • Specify a different keystore for the connector.

      If you do not want to use the default IDM keystore, set the following properties:

      • alternateKeyStore - specifies the full path to an alternate keystore.

      • alternateKeyStoreType - specifies alternate keystore type. Valid values are JKS, JCEKS and PKCS12.

      • alternateKeyStorePassword - specifies password for the alternate keystore.

  4. Enable hostname verification to prevent a third party from manipulating DNS entries or spoofing the LDAP Server IP.

    When hostname verification is enabled, the connector compares the hostname in the certificate subject and subjectAltName with a simple hostname pattern defined in the hostNameVerification property.

    To enable hostname verification, set "hostNameVerification" : true and set the hostNameVerification property to the hostname you want to match. If the pattern matches, the connector is initialized successfully. If the pattern does not match, connector initialization throws an error. The hostNameVerification property supports wild card matching.

    Assume, for example, a server certificate principal hostname of server1.example.com. With the following connector configuration, IDM starts up and the connector is initialized:

    "configurationProperties" : {
        ...
        "hostNameVerification" : true,
        "hostNameVerifierPattern" : "server1.example.com",
        ...
    }

    Similarly, with the following connector configuration, IDM starts up and the connector is initialized:

    "configurationProperties" : {
        ...
        "hostNameVerification" : true,
        "hostNameVerifierPattern" : "*.example.com",
        ...
    }

    With the following connector configuration, IDM starts up but connector initialization throws an error:

    "configurationProperties" : {
        ...
        "hostNameVerification" : true,
        "hostNameVerifierPattern" : "server2.example.com",
        ...
    }

    The error returned is similar to the following:

    The host name from the server certificate'CN=server1.example.com' does not match the provided pattern 'server2.example.com'

Control what the LDAP connector synchronizes

To control the set of LDAP entries that are affected by reconciliation and automatic synchronization operations, set the following properties in the provisioner configuration. Automatic synchronization includes liveSync (synchronization of changes from the LDAP server to IDM) and implicit sync (synchronization from IDM to the LDAP server). For more information, refer to Synchronization types.

accountSearchFilter

Only user accounts that match this filter are searched, and therefore affected by reconciliation and synchronization operations. If you do not set this property, all accounts within the base contexts specified previously are searched.

accountSynchronizationFilter

This property is used during reconciliation and automatic synchronization operations, and filters out any LDAP accounts that you specifically want to exclude from these operations.

attributesToSynchronize

During automatic synchronization operations, only the attributes listed here are considered for changes. Objects that include these attributes are synchronized. Objects that do not include these attributes are ignored. If this property is not set, IDM considers changes to all attributes specified in the mapping.

This attribute works only with LDAP servers that log changes in a change log, not with servers (such as Active Directory) that use other mechanisms to track changes.

baseContexts

The starting points in the LDAP tree that are used when searching the directory tree; for example, dc=example,dc=com. These base contexts must include the set of users and the set of groups that must be searched during reconciliation operations.

baseContextsToSynchronize

The starting points in the LDAP tree that are used to determine if a change should be synchronized. This property is used only for automatic synchronization operations. Only entries that fall under these base contexts are considered during synchronization operations.

modifiersNamesToFilterOut

This property lets you define a list of DNs. During synchronization operations, the connector ignores changes made by these DNs.

When a managed user object is updated, and that change is synchronized to the LDAP server, the change made on the LDAP server is recorded in the change log. A liveSync operation picks up the change, and attempts to replay the change on the managed user object, effectively resulting in a loop of updates.

To avoid this situation, you can specify a unique user in your LDAP directory, that will be used only for the LDAP connector. The unique user must be something other than uid=admin; for example, cn=idmuser. You can then include that user DN as the value of modifiersNamesToFilterOut. When a change is made through the LDAP connector, and that change is recorded in the change log, the modifier’s name (cn=idmuser) is flagged, and IDM does not attempt to replay the change back to the managed user repository. So, you are effectively indicating that IDM should not synchronize changes back to managed user that originated from managed user, thus preventing the update loop.

This attribute works only with LDAP servers that log changes in a change log, not with servers (such as Active Directory) that use other mechanisms to track changes.

objectClassesToSynchronize

During automatic synchronization operations, only the object classes listed here are considered for changes. IDM ignores change log updates (or changes to managed objects) which do not have any of the object classes listed here.

Use the LDAP connector with Active Directory

The LDAP connector provides functionality specifically for managing Active Directory users and groups. The connector can handle the following operational attributes to manage Active Directory accounts:

__ENABLE__

Uses the userAccountControl attribute to get or set the account status of an object.

The LDAP connector reads the userAccountControl to determine if an account is enabled or disabled. The connector modifies the value of the userAccountControl attribute if IDM changes the value of __ENABLE__.

__ACCOUNT_EXPIRES__

Sets the accountExpires attribute of an Active Directory object to reset an expired account, or to set a future expiration date.

To set an account that never expires, set "__ACCOUNT_EXPIRES__": "0".

To set an expiration date, set "__ACCOUNT_EXPIRES__": "date", where date is in ISO8601 format. For example:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--header "Content-Type: application/json" \
--request PUT \
--data '{
  "__ACCOUNT_EXPIRES__": "2020-12-31T00:00:00Z"
}' \
"http://localhost:8080/openidm/system/AD/account/e1418d64-096c-4cb0-b903-ebb66562d99d"
{
    "sn": "jensen",
    "__LOCK_OUT__": false,
    "__ENABLE__": true,
    "objectGUID": "e1418d64-096c-4cb0-b903-ebb66562d99d",
    "dn": "CN=bjensen,OU=create,DC=example,DC=com",
    "accountExpires": "2020-12-31T00:00:00Z"
}
__LOCK_OUT__

Uses the msDS-User-Account-Control-Computed system attribute to check if a user account has been locked.

If IDM sets __LOCK_OUT__ to FALSE, the LDAP connector sets the Active Directory lockoutTime to 0 to unlock the account.

If IDM sets __LOCK_OUT__ to TRUE, the LDAP connector ignores the change and logs a message.

__PASSWORD_EXPIRED__

Uses the msDS-User-Account-Control-Computed system attribute to check if a user password has expired.

To force password expiration (that is, to force a user to change their password when they next log in), set pwdLastSet to 0. The LDAP connector sets pwdLastSet to 0, if IDM sets __PASSWORD_EXPIRED__ to TRUE.

To remove password expiration, set pwdLastSet to 0 and then to -1. This sets the value of pwdLastSet to the current time. The LDAP connector sets pwdLastSet to -1 if IDM sets __PASSWORD_EXPIRED__ to FALSE.

Active Directory does not allow you to create an enabled account with an expired password. If you are using __PASSWORD_EXPIRED__ to force a new user to change their password when they next log in, you can create the user account as disabled initially (__ENABLE__=false). You can then patch the new user account to enable it. You can use the same workaround for synchronization operations, creating new user accounts as disabled, then issuing an openidm.patch call in a postCreate script to enable the account.
__CURRENT_PASSWORD__

For a password change request, the connector supplies the __CURRENT_PASSWORD__, along with the new password. The connector can also do a password reset where only the new password is supplied.

The sample connector configuration file (openidm/samples/example-configurations/provisioners/provisioner.openicf-adldap.json) includes these operational attributes. Note that the passwordAttribute property in this provisioner file is set to unicodePwd. This property specifies the attribute in Active Directory that holds the user password. When a user’s password is changed, the new value is set in this attribute.

Manage Active Directory users with the LDAP connector

If you create or update users in Active Directory, and those user entries include passwords, you must use the LDAP connector over SSL. You cannot create or update an Active Directory user password in clear text. To use the connector over SSL, follow the instructions in Configure the LDAP Connector to Use SSL and StartTLS.

The following command adds an Active Directory user. The output shows the operational attributes described in the previous section:

curl \
--header "Content-Type: application/json" \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
--data '{
  "dn": "CN=Brian Smith,CN=Users,DC=example,DC=com",
  "cn": "Brian Smith",
  "sAMAccountName": "bsmith",
  "userPrincipalName": "bsmith@example.com",
  "userAccountControl": "512",
  "givenName": "Brian",
  "mail": "bsmith@example.com",
  "__PASSWORD__": "Passw0rd"
}' \
"http://localhost:8080/openidm/system/ad/account?_action=create"
{
  "_id": "e1418d64-096c-4cb0-b903-ebb66562d99d",
  "mobile": null,
  "postalCode": null,
  "st": null,
  "employeeType": [],
  "objectGUID": "e1418d64-096c-4cb0-b903-ebb66562d99d",
  "cn": "Brian Smith",
  "department": null,
  "l": null,
  "description": null,
  "info": null,
  "manager": null,
  "sAMAccountName": "bsmith",
  "sn": null,
  "whenChanged": "20151217131254.0Z",
  "userPrincipalName": "bsmith@example.com",
  "userAccountControl": "512",
  "__ENABLE__": true,
  "displayName": null,
  "givenName": "Brian",
  "middleName": null,
  "facsimileTelephoneNumber": null,
  "lastLogon": "0",
  "countryCode": "0",
  "employeeID": null,
  "co": null,
  "physicalDeliveryOfficeName": null,
  "pwdLastSet": "2015-12-17T13:12:54Z",
  "streetAddress": null,
  "homePhone": null,
  "__PASSWORD_NOTREQD__": false,
  "telephoneNumber": null,
  "dn": "CN=Brian Smith,CN=Users,DC=example,DC=com",
  "title": null,
  "mail": "bsmith@example.com",
  "postOfficeBox": null,
  "__SMARTCARD_REQUIRED__": false,
  "uSNChanged": "86144",
  "__PASSWORD_EXPIRED__": false,
  "initials": null,
  "__LOCK_OUT__": false,
  "company": null,
  "employeeNumber": null,
  "accountExpires": "0",
  "c": null,
  "whenCreated": "20151217131254.0Z",
  "uSNCreated": "86142",
  "division": null,
  "groups": [],
  "__DONT_EXPIRE_PASSWORD__": false,
  "otherHomePhone": []
}
  • Previous versions of the LDAP connector appended <GUID= to the GUID for Active Directory objects. This behavior ensured compatibility with the legacy .NET connector.

    The LDAP connector no longer appends <GUID= to the object GUID. The new GUID format is compatible with objects created using the AD PowerShell connector; for example, e1418d64-096c-4cb0-b903-ebb66562d99d. In existing deployments, this could mean your links are incompatible with the new GUID format. To update links to the new format, run a reconciliation operation. To retain the legacy behavior, set "useOldADGUIDFormat" : true in your provisioner file.

  • You cannot sort by _id when you return results from an Active Directory (or Active Directory LDS) server. The _id attribute used by default is the objectGUID, which is a binary attribute, and cannot be used for sorting.

  • When you page and sort query results (using the sortKeys parameter), the pagedResultsCookie applies only to the first connection that makes the sorted, paginated query. Active Directory (and AD LDS) build a cached index for sorted searches, which is attached to the original connection.

Note that the command sets the userAccountControl to 512, which is an enabled account. The value of the userAccountControl determines the account policy. The following list describes the common values for the userAccountControl.

512

Enabled account.

514

Disabled account.

544

Enabled account, password not required.

546

Disabled account, password not required.

66048

Enabled account, password does not expire.

66050

Disabled account, password does not expire.

66080

Enabled account, password does not expire and is not required.

66082

Disabled account, password does not expire and is not required.

262656

Enabled account, smartcard required.

262658

Disabled account, smartcard required.

262688

Enabled account, smartcard required, password not required.

262690

Disabled account, smartcard required, password not required.

328192

Enabled account, smartcard required, password does not expire.

328192

Enabled account, smartcard required, password does not expire.

328194

Disabled account, smartcard required, password does not expire.

328224

Enabled account, smartcard required, password does not expire and is not required.

328226

Disabled account, smartcard required, password does not expire and is not required.

Manage Active Directory groups with the LDAP connector

The following command creates a basic Active Directory group with the LDAP connector:

curl \
--header "Content-Type: application/json" \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
--data '{
  "dn": "CN=Employees,DC=example,DC=com"
}' \
"http://localhost:8080/openidm/system/ad/group?_action=create"
{
  "_id": "240da4e9-59d8-1547-ad86-29f5b2b5114d"
}

The LDAP connector exposes two special attributes to handle Active Directory group scope and type: GROUP_SCOPE and GROUP_TYPE.

The GROUP_SCOPE attribute is defined in the provisioner configuration as follows:

...
"__GROUP_SCOPE__" : {
    "type" : "string",
    "nativeName" : "__GROUP_SCOPE__",
    "nativeType" : "string"
},

The value of the GROUP_SCOPE attribute can be global, domain, or universal. If no group scope is set when the group is created, the scope is global by default. For more information about the different group scopes, refer to the corresponding Microsoft documentation.

The GROUP_TYPE attribute is defined in the provisioner configuration as follows:

...
"__GROUP_TYPE__" : {
 "type" : "string",
 "nativeName" : "__GROUP_TYPE__",
 "nativeType" : "string"
 },

The value of the GROUP_TYPE attribute can be security or distribution. If no group type is set when the group is created, the type is security by default. For more information about the different group types, refer to the corresponding Microsoft documentation.

The following example creates a new distribution group, with universal scope:

curl \
--header "Content-Type: application/json" \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
--data '{
  "dn": "CN=NewGroup,DC=example,DC=com",
  "__GROUP_SCOPE__": "universal",
  "__GROUP_TYPE__": "distribution"
}' \
"http://localhost:8080/openidm/system/ad/group?_action=create"
{
  "_id": "f189df8a-276f-9147-8ad5-055b1580cbcb"
}

Support for nested Active Directory groups

By default, Active Directory does not return members of a nested group when querying the parent group. Some additional configuration is required to return members of a nested Active Directory group.

To include members of a nested group, create a new nestedMembers attribute in your provisioner file:

"nestedMembers" : {
    "type" : "array",
    "items" : {
        "type" : "string",
        "nativeType" : "string"
    },
    "nativeName" : "memberOf:1.2.840.113556.1.4.1941:",
    "nativeType" : "string",
    "flags" : [
        "NOT_CREATABLE",
        "NOT_UPDATEABLE",
        "NOT_RETURNED_BY_DEFAULT"
    ]
},

Note that the nativeName property includes 1.2.840.113556.1.4.1941, which is the OID of LDAP_MATCHING_RULE_IN_CHAIN and LDAP_MATCHING_RULE_TRANSITIVE_EVAL. This is what tells Active Directory to include members of nested groups.

Querying this attribute will return results that include members of any nested groups of the queried group. For example:

curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"http://localhost:8080/openidm/system/ad/account?_queryFilter=nestedMembers+eq+"CN=ParentGroup,DC=example,DC=com"&_fields=cn"

Handle Active Directory dates

Most dates in Active Directory are represented as the number of 100-nanosecond intervals since January 1, 1601 (UTC). For example:

pwdLastSet: 130698687542272930

IDM generally represents dates as an ISO 8601-compliant string with yyyy-MM-dd’T’HH:mm:ssZ format. For example:

2015-03-02T20:17:48Z

The generic LDAP connector therefore converts any dates from Active Directory to ISO 8601 format, for fields such as pwdLastSet, accountExpires, lockoutTime, and lastLogon.

Multiple Active Directory domains

In a multi-domain Active Directory Domain Services (AD DS) forest, the global catalog (GC) provides a read-only (searchable) representation of every object in the forest. Each domain controller (DC) in the forest stores a writable replica of the objects in its domain. Therefore, a DC can locate only the objects in its domain.

If your Active Directory deployment has only one domain controller, you can configure the connector to connect to that single domain controller. If your deployment spans multiple domains, you must configure the connector to connect to the Global Catalog (GC) to have a comprehensive view of all the domains.

Using a GC as the authoritative data source has the following limitations:

  • Only a subset of attributes is replicated from other domains to the GC.

    Certain attributes required by the LDAP connector might be missing. To avoid this problem, modify the Active Directory schema to ensure that the required attributes are replicated to the GC.

  • Delete operations are not detected immediately.

    A liveSync operation will therefore not update IDM with the result of a delete operation. Delete operations are detected by a reconciliation operation, so data stores are only temporarily "out of sync" with regard to deletes.

  • Not all group types are supported.

    Group membership information is replicated to the GC for universal groups only. You must therefore use universal groups if your directory service has more than one domain.

You can use the USN value for liveSync but must connect to the GC in this case, and ensure that you never failover to a different GC or to a DC. Using the USN for liveSync instead of the timestamp mechanism is generally preferred, because of the issue with detecting delete operations.

LDAP search filters

The LDAP connector constructs an LDAP search filter using a combination of filters, in the following order:

(& (native filter) (user filter) (object class filter) )

The filter components are as follows:

Native Filter

The native filter is the query filter that has been translated to an LDAP query. For example, uid+eq+"user123" is translated to uid=user123.

This part of the filter is processed first.

User Filter

You can define a user filter with the properties accountSearchFilter and groupSearchFilter in the connector configuration.

These properties enable you to construct a more granular or specific search filter. If a user filter is specified, the connector does not use the object class filter. If no user filter is specified, (accountSearchFilter and groupSearchFilter set to null or absent from the connector configuration), the connector uses the object class filter.

Object Class Filter

This part of the filter includes the object classes that the entry must have in order to be returned by the search.

The __ACCOUNT__ and __GROUPS__ object classes are defined by the properties accountObjectClasses and groupObjectClasses in the connector configuration. For example, the following configuration indicates that the accountObjectClasses include the LDAP object classes top, person, organizationalPerson, and inetOrgPerson:

"configurationProperties" : {
    ...
    "accountObjectClasses" : [
        "top",
        "person",
        "organizationalPerson",
        "inetOrgPerson"
    ],
    ...
}

With this configuration, the search filter for accounts is constructed as follows:

(&(objectClass=top)(objectClass=person)(objectClass=organizationalPerson)(objectClass=inetOrgPerson))

If no accountObjectClasses or groupObjectClasses are defined in the connector configuration, the connector uses the name of the ICF ObjectClass in the filter. For example, an object of type organizationUnit will result in:

(&(objectClass=organizationUnit)

OpenICF Interfaces Implemented by the LDAP Connector

The LDAP Connector implements the following OpenICF interfaces. For additional details, see ICF interfaces:

Authenticate

Provides simple authentication with two parameters, presumed to be a user name and password.

Create

Creates an object and its uid.

Delete

Deletes an object, referenced by its uid.

Resolve Username

Resolves an object by its username and returns the uid of the object.

Schema

Describes the object types, operations, and options that the connector supports.

Script on Connector

Enables an application to run a script in the context of the connector.

Any script that runs on the connector has the following characteristics:

  • The script runs in the same execution environment as the connector and has access to all the classes to which the connector has access.

  • The script has access to a connector variable that is equivalent to an initialized instance of the connector. At a minimum, the script can access the connector configuration.

  • The script has access to any script arguments passed in by the application.

Search

Searches the target resource for all objects that match the specified object class and filter.

Sync

Polls the target resource for synchronization events, that is, native changes to objects on the target resource.

Test

Tests the connector configuration.

Testing a configuration checks all elements of the environment that are referred to by the configuration are available. For example, the connector might make a physical connection to a host that is specified in the configuration to verify that it exists and that the credentials that are specified in the configuration are valid.

This operation might need to connect to a resource, and, as such, might take some time. Do not invoke this operation too often, such as before every provisioning operation. The test operation is not intended to check that the connector is alive (that is, that its physical connection to the resource has not timed out).

You can invoke the test operation before a connector configuration has been validated.

Update

Updates (modifies or replaces) objects on a target resource.

LDAP Connector Configuration

The LDAP Connector has the following configurable properties:

Configuration properties

Property Type Default Encrypted(1) Required(2)

filterWithOrInsteadOfAnd

boolean

false

Normally the filter used to fetch change log entries is an and-based filter retrieving an interval of change entries. If this property is set, the filter will or together the required change numbers instead.

objectClassesToSynchronize

String[]

['inetOrgPerson']

The object classes to synchronize. The change log is for all objects; this filters updates to just the listed object classes. You should not list the superclasses of an object class unless you intend to synchronize objects with any of the superclass values. For example, if only "inetOrgPerson" objects should be synchronized, but the superclasses of "inetOrgPerson" ("person", "organizationalperson" and "top") should be filtered out, then list only "inetOrgPerson" here. All objects in LDAP are subclassed from "top". For this reason, you should never list "top", otherwise no object would be filtered.

baseContextsToSynchronize

String[]

[]

One or more starting points in the LDAP tree that will be used to determine if a change should be synchronized. The base contexts attribute will be used to synchronize a change if this property is not set.

attributesToSynchronize

String[]

[]

The names of the attributes to synchronize. This ignores updates from the change log if they do not update any of the named attributes. For example, if only "department" is listed, then only changes that affect "department" will be processed. All other updates are ignored. If blank (the default), then all changes are processed.

timestampSyncOffset

int

0

An optional offset, specified in seconds to be negatively applied to the timestamp for Timestamp based Sync operations. Default value is 0, or no offset.

changeNumberAttribute

String

changeNumber

The name of the change number attribute in the change log entry.

modifiersNamesToFilterOut

String[]

[]

The list of names (DNs) to filter from the changes. Changes with the attribute "modifiersName" that match entries in this list will be filtered out. The standard value is the administrator name used by this adapter, to prevent loops. Entries should be of the format "cn=Directory Manager".

credentials

GuardedString

null

Yes

No

Password for the principal.

changeLogBlockSize

int

100

The number of change log entries to fetch per query.

useTimestampsForSync

boolean

false

If true, the connector will use the createTimestamp and modifyTimestamp system attributes to detect changes (Create/Update) on the directory instead of native change detection mechanism (cn=changelog on OpenDJ or Update Sequence Number -USN- on Active Directory for instance). Default value is false.

accountSynchronizationFilter

String

null

An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.

removeLogEntryObjectClassFromFilter

boolean

true

If this property is set (the default), the filter used to fetch change log entries does not contain the "changeLogEntry" object class, expecting that there are no entries of other object types in the change log.

alternateKeyStorePassword

GuardedString

null

Yes

No

Password to use for the alternate keystore.

groupSynchronizationFilter

String

null

An optional LDAP filter for the objects to synchronize. Because the change log is for all objects, this filter updates only objects that match the specified filter. If you specify a filter, an object will be synchronized only if it matches the filter and includes a synchronized object class.

groupMemberAttribute

String

uniqueMember

No

The name of the group attribute that will be updated with the distinguished name of the user when the user is added to the group.

accountSearchFilter

String

null

No

An optional LDAP filter to control which accounts are returned from the LDAP resource. If no filter is specified, only accounts that include all specified object classes are returned.

privateKeyAlias

String

null

No

Specifies the name of a private key alias from the keystore that should be used for SSL mutual authentication. If null, no private key is sent during SSL handshake so only server cert is used. This alias name is case sensitive.

ssl

boolean

false

No

Select the check box to connect to the LDAP server using SSL.

maintainPosixGroupMembership

boolean

false

No

When enabled and a user is renamed or deleted, update any POSIX groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.

checkAliveMinInterval

long

60

No

The minimum interval (seconds) at which the target directory is polled when a connection is reused from the pool. Defaults to 60 seconds.

groupSearchFilter

String

null

No

An optional LDAP filter to control which groups are returned from the LDAP resource. If no filter is specified, only groups that include all specified object classes are returned.

referralsHandling

String

follow

No

Defines how to handle LDAP referrals. Possible values can be follow, ignore or throw.

host

String

null

No

The name or IP address of the host where the LDAP server is running.

maintainLdapGroupMembership

boolean

false

No

When enabled and a user is renamed or deleted, update any LDAP groups to which the user belongs to reflect the new name. Otherwise, the LDAP resource must maintain referential integrity with respect to group membership.

resetSyncToken

String

never

No

Connector can reset the sync token if ever the value of the sync token is greater than the last change number in the directory changelog. Defaults to "never" (no reset). If set to "first" it will reset the sync token to the value of the firstChangeNumber changelog attribute. If set to "last" it will reset the sync token to the value of the lastChangeNumber changelog attribute.

vlvSortAttribute

String

uid

No

Specify the sort attribute to use for VLV indexes on the resource.

convertGTToISO8601

String[]

['whenCreated', 'whenChanged']

No

Converts the Greenwich Time to ISO8601 format.

baseContexts

String[]

[]

No

One or more starting points in the LDAP tree that will be used when searching the tree. Searches are performed when discovering users from the LDAP server or when looking for the groups of which a user is a member.

hostNameVerification

boolean

false

No

If true, the connector will verify the hostname in the certificate (subject + alternative subject) against the defined hostNameVerifierPattern.

blockSize

int

100

No

The maximum number of entries that can be in a block when retrieving entries in blocks.

groupObjectClasses

String[]

['top', 'groupOfUniqueNames']

No

The default list of object classes that will be used when creating new group objects in the LDAP tree. This can be overridden by specifying the group object classes during the Create operation.

accountUserNameAttributes

String[]

['uid', 'cn']

No

Attribute or attributes which holds the account’s user name. They will be used when authenticating to find the LDAP entry for the user name to authenticate.

failover

String[]

[]

No

List all servers that should be used for failover in case the preferred server fails. If the preferred server fails, JNDI will connect to the next available server in the list. List all servers in the form of "ldap://ldap.example.com:389/", which follows the standard LDAP v3 URLs described in RFC 2255. Only the host and port parts of the URL are relevant in this setting.

port

int

389

No

TCP/IP port number used to communicate with the LDAP server.

convertADIntervalToISO8601

String[]

['pwdLastSet', 'accountExpires', 'lockoutTime', 'lastLogon']

No

Converts the AD Interval to ISO8601.

hostNameVerifierPattern

String

null

No

A simple pattern used to match the hostname from the certificate. It can contains * character (server1.example.com, *.example.com).

passwordAttribute

String

userPassword

No

The name of the LDAP attribute that holds the password. When changing a users password, the new password is set to this attribute.

useDNSSRVRecord

boolean

false

No

If true, the connector will do a DNS query to find SRV records associated with the value set for host property ("_ldap._tcp.example.com" for example). Defaults to false.

getGroupMemberId

boolean

false

No

Specifies whether to add an extra _memberId attribute to get the group members UID. CAUTION: Setting this property to true can incur a large performance cost on group handling.

lastCheckAlive

long

1732889017477

No

The last time the connector was checked to see if it was alive

ldapGroupsUseStaticGroups

boolean

false

No

When set to true, The ldapGroups attribute will search group membership through static groups only. If false, it will leverage the "memberOf" attribute of an object (defaults to true).

startTLS

boolean

false

No

Specifies whether to use the startTLS operation to initiate a TLS/SSL session.

allowTreeDelete

boolean

false

No

Connector can delete an entry (node) with leaf entry if this value is set to true (defaults to false). The LDAP control LDAP_SERVER_TREE_DELETE_OID (1.2.840.113556.1.4.805) is used.

respectResourcePasswordPolicyChangeAfterReset

boolean

false

No

When this resource is specified in a Login Module (i.e., this resource is a pass-through authentication target) and the resource’s password policy is configured for change-after-reset, a user whose resource account password has been administratively reset will be required to change that password after successfully authenticating.

uidAttribute

String

entryUUID

No

The name of the LDAP attribute that is mapped to the OpenICF UID attribute.

principal

String

null

No

The distinguished name with which to authenticate to the LDAP server.

accountObjectClasses

String[]

['top', 'person', 'organizationalPerson', 'inetOrgPerson']

No

The default list of object classes that will be used when creating new user objects in the LDAP tree. This can be overridden by specifying the user object classes during the Create operation.

alternateKeyStoreType

String

null

No

Defines the type of the alternate key store. Valid values are JKS, JCEKS and PKCS12.

passwordHashAlgorithm

String

null

No

Indicates the algorithm that the Identity system should use to hash the password. The only supported value is WIN-AD (for when Active Directory is the target). A blank value indicates that the system will not hash passwords. This will cause clear text passwords to be stored in LDAP unless the LDAP server performs the hash (as Forgerocks OpenDJ does, for example).

alternateKeyStore

String

null

No

Defines the filename of an alternate keystore. If specified, the connector will not use the default keystore specified by the javax.net.ssl.keyStore property.

authType

String

simple

No

The authentication mechanism to use: Simple, EXTERNAL (mTLS) or SASL-GSSAPI (Kerberos). Defaults to "simple".

connectionTimeout

int

30000

No

The timeout (in ms) before the connection attempt is aborted.

customOctetStringAttributes

String[]

[]

No

A list of custom octet string attributes to be declared so that the LDAP connector manipulates these attributes as byte arrays.

useBlocks

boolean

false

No

Specifies whether to use block-based LDAP controls, like the simple paged results or VLV control. When performing search operations on large numbers of entries, the entries are returned in blocks to reduce the amount of memory used by the operation.

readSchema

boolean

true

No

If true, the connector will read the schema from the server. If false, the connector will provide a default schema based on the object classes in the configuration. This property must be true in order to use extended object classes.

usePagedResultControl

boolean

false

No

When enabled, the LDAP Paged Results control is preferred over the VLV control when retrieving entries. If disabled, paged queries will be ignored.

useOldADGUIDFormat

boolean

false

No

The connector used to transform the AD ObjectGUID in the form <GUID=xxxxxx>. It now used dashed notation (xxxx-xx-xx-xxxx-xxxxxx) by default. Set to true to keep the old format.

sendCAUDTxId

boolean

false

No

Connector can send the Common Audit Transaction Id (if present) to the target OpenDJ server when this value is set to true (defaults to false). The LDAP control TransactionIdControl (1.3.6.1.4.1.36733.2.1.5.1) is used.

gssapiLoginContext

String

null

No

Defines the name used in the JAAS configuration file to define the JAAS login configuration. If null, it defaults to "org.identityconnectors.ldap.LdapConnector".

(1) Whether the property value is considered confidential, and is therefore encrypted in IDM.

(2) A list of operations in this column indicates that the property is required for those operations.