This chapter contains generic instructions for synchronizing Oracle Internet Directory with a third-party directory. It contains these topics:
Note:
This chapter assumes that you are familiar with Chapter 16, "Third-Party Directory Integration Concepts and Considerations".See Also:
The following chapters for step-by-step instructions about configuring integration between Oracle Internet Directory and a specific third-party directory:To prepare for synchronization between Oracle Internet Directory and a third-party directory:
Verify that Oracle Internet Directory and your third-party directory are running.
Create a user account in the third-party directory with sufficient privileges to read and write the relevant entries in the containers that will be synchronized. If the directory supports tombstone, the account should also have sufficient privileges to read tombstone entries.
For Import Operations from a Third-Party Directory: Grant the user account read access privileges to the subtree root. The user account must be able to read all objects under the source container (subtree root) in the third-party directory that are to be synchronized with the Oracle Directory Integration Platform. To verify whether a third-party directory user account has the necessary privileges to all objects to be synchronized with Oracle Internet Directory, use the command-line ldapsearch
utility to perform a subtree search, as follows:
$ORACLE_HOME/bin/ldapsearch -h directory host-p directory port \ -b "DN of subtree" -s sub -D binddn "objectclass=*" -q
Note:
You will be prompted for the password for the privileged directory user.The return results from the ldapsearch
utility should include all objects of interest, including all attributes and values that will be synchronized.
For Export Operations to a Third-Party Directory: Grant the user account the following privileges to the subtree root that is the parent of all the containers to which the Oracle Directory Integration Platform will export users:
Write
Create all child objects
Delete all child objects
See Also:
Your third-party directory documentation for information how to grant privileges to user accountsYou must also ensure that Oracle Internet Directory is running with change logging enabled, and that the change log purge duration is set to a minimum of seven days.
See Also:
The Oracle Internet Directory server administration tools chapter of the Oracle Identity Management User Reference for instructions on how to start an Oracle directory server with change logging enabled
The orclPurgeTargetAge
section of the Oracle Identity Management User Reference for instructions on how to set the change log purge duration
The expressSyncSetup
command located in the ORACLE_HOME/bin directory allows you to perform the initial migration of data between a connected directory and Oracle Internet Directory for a synchronization profile.
Notes:
Best security practice is to provide a password only in response to a prompt from the command.
You must set the WLS_HOME
and ORACLE_HOME
environment variables before executing any of the Oracle Directory Integration Platform commands
The Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed must be configured for SSL to execute this command in SSL mode. Refer to the Configuring SSL chapter in Oracle Fusion Middleware Securing Oracle WebLogic Server for more information.
expressSyncSetup -h HOST -p PORT -D wlsuser -pf PROFILE -conDirType CONNECTED_DIRECTORY_TYPE -conDirURL CONNECTED_DIRECTORY_URL -conDirBindDN CONNECTED_DIRECTORY_BIND_DN -conDircontainer SYNC_CONTAINER [-ssl -keystorePath PATH_TO_KEYSTORE -keystoreType TYPE] [-enableProfiles {true | false}] [-help]
Oracle WebLogic Server host where Oracle Directory Integration Platform is deployed.
Listening port of the Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed.
Oracle WebLogic Server login ID
Note:
You will be prompted for the Oracle WebLogic Server login password. You cannot provide the password as a command-line argument. Best security practice is to provide a password only in response to a prompt from the command. If you must executeexpressSyncSetup
from a script, you can redirect input from a file containing the Oracle WebLogic Server login password. Use file permissions to protect the file and delete it when it is no longer necessary. If you must provide more than one password to expressSyncSetup
, put each on a separate line in the file, in the following order: connected directory bind DN password, then Oracle WebLogic Server login password.Profile name. Specify the name of the profile in ASCII characters only, as non-ASCII characters are not supported in the profile name.
Connected directory type. Supported values are ActiveDirectory
, EDirectory
, iPlanet
, OpenLDAP
, ADAM
, Tivoli
, OID
, and ExchangeServer2003
.
URL where the connected directory is running. The format is host:port.
Connected directory server bind DN. For example:
cn=orcladmin
, cn=Directory Manager
Note:
You will be prompted for the connected directory bind DN password. You cannot provide the password as a command-line argument. Best security practice is to provide a password only in response to a prompt from the command. If you must executeexpressSyncSetup
from a script, you can redirect input from a file containing the connected directory bind DN password. Use file permissions to protect the file and delete it when it is no longer necessary. If you must provide more than one password to expressSyncSetup
, put each on a separate line in the file, in the following order: connected directory bind DN password, then Oracle WebLogic Server login password.The synchronization container. For example:
ou=sales,dc=us,dc=com
OU=Groups,DC=imtest,DC=com
CN=Users,DC=imtest,DC=com
Executes the command in SSL mode.
Note:
The Oracle WebLogic Managed Server where Oracle Directory Integration Platform is deployed must be configured for SSL to execute this command in SSL mode. Refer to the Configuring SSL chapter in Oracle Fusion Middleware Securing Oracle WebLogic Server for more information.The full path to the keystore.
The type of the keystore identified by -keystorePath
. For example: -keystorePath jks
or -keystorePath PKCS12
Specify true
to enable created profiles, false
if not.
Provides command usage help.
expressSyncSetup -h myhost.mycompany.com -p 7005 -D login_ID -pf myProfile \ -conDirType ACTIVEDIRECTORY -conDirUrl server.mycompany.com:5432 \ -conDirBindDN [email protected] -conDirContainer ou=sales,dc=us,dc=com \ -enableProfiles false \
expressSyncSetup -help
The expressSyncSetup
command allows you to create two synchronization profiles, one for import and one for export, using predefined assumptions. If the Oracle Directory Integration Platform is already running, then after enabling the profile, you can immediately begin synchronizing users and groups between the containers in which users and groups are stored in the third-party directory and cn=users,
default_realm
/ cn=groups,
default_realm
in Oracle Internet Directory.
To simplify the configuration, the expressSyncSetup
command assumes the following:
Entries for users of the default realm in Oracle Internet Directory are located in the container cn=users,
default_realm_DN
.
Entries for groups of the default realm in Oracle Internet Directory are located in the container cn=groups,
default_realm_DN
The Oracle Directory Integration Platform master mapping rules files created during installation are located in $ORACLE_HOME/ldap/odi/conf.
Master domain mapping rules are located in the $ORACLE_HOME/ldap/odi/conf/ directory.
The logon credential is that of a Oracle Directory Integration Platform administrator with sufficient privileges to configure a profile, a realm, and access controls on the Users container in the Oracle directory server. Members of the Oracle Directory Integration Platform Administrators group (cn=dipadmingrp,cn=dipadmin,cn=directory integration platform,cn=products,cn=oraclecontext
) have the necessary privileges.
Perform the following steps to run the expressSyncSetup
command and verify that users and groups are synchronizing between cn=users,default_naming_context
in the third-party directory and cn=users,
default_realm
in Oracle Internet Directory:
Run express configuration using "Syntax for expressSyncSetup".
The expressSyncSetup
command creates two profiles named profile_name
Import
and profile_name
Export
. By default, both profiles are disabled. Enable the profile_name
Import
profile if you need to synchronize from a third-party directory to Oracle Internet Directory and enable the profile_name
Export
profile if you need to synchronize from Oracle Internet Directory to a third-party directory. Enable the profile by using the manageSyncProfiles command with the activate
operation.
Start the Oracle Directory Integration Platform.
Wait until the scheduling interval has elapsed and verify that synchronization has started by entering the following command. After executing the command, you will be prompted for the password for privileged directory user.
$ORACLE_HOME/bin/ldapsearch -h OID host -p OID port \ -D binddn -q \ -b "orclodipagentname=import profile,cn=subscriber profile,cn=changelog subscriber,cn=oracle internet directory" -s base "objectclass=*" orclodipsynchronizationstatus orclodiplastsuccessfulexecutiontime
Note:
The default scheduling interval is 60 seconds (1 minute). You can use Oracle Enterprise Manager Fusion Middleware Control to change the default scheduling interval. See Chapter 7, "Managing Directory Synchronization Profiles" for information on using Oracle Enterprise Manager Fusion Middleware Control.When synchronization is successfully started:
The value of the Synchronization Status
attribute is Synchronization Successful
.
The value of the Last Successful Execution Time
attribute is the specific date and time of that execution. Note that this must be close to the current date and time.
An example of a result indicating successful synchronization is:
Synchronization successful 20060515012615
Note:
The date and time must be close to current date and time
When running the ldapsearch
command, you need the dipadmin password, which, as established at installation, is the same as orcladmin password
After verifying that synchronization has started, examine the entries in Oracle Internet Directory and the third-party directory to confirm that users and groups are synchronizing between cn=users,default_naming_context
in the third-party directory and cn=users,
default_realm
in Oracle Internet Directory.
Note:
While customizing the synchronization profiles for your environment, you may need to add test users and groups to facilitate your deployment effort. Be sure to remove any test users and groups when your are finished customizing and testing your synchronization profiles.CAUTION:
In order to successfully customize your import and export synchronization profiles, do not enable SSL until you have finished with all other configuration tasks.
When you install Oracle Directory Integration Platform, sample import and export synchronization profiles are automatically created for each of the supported third-party directories. The import and export synchronization profiles created during the install process or with the expressSyncSetup
command are only intended as a starting point for you to use when deploying your integration of Oracle Internet Directory and a third-party directory. Because the default synchronization profiles are created using predefined assumptions, you must further customize them for your environment, as described in these topics:
Configuring the Third-Party Directory Connector for Synchronization in SSL Mode
Enabling Password Synchronization from Oracle Internet Directory to a Third-Party Directory
See Also:
The individual third-party directory integration chapters for information on the sample synchronization profiles that were created during the installation processBefore customizing the sample synchronization profiles that were created during the installation process, be sure to copy them with the copy
operation of the manageSyncProfiles command, then enable the copies with the activate
operation of the manageSyncProfiles command.
To configure the realm, do the following:
Choose the realm DN structure as described in the section "Choose the Structure of the Directory Information Tree", and, more specifically, in the section "Planning the Deployment".
Select the attribute for the login name of the user. This attribute contains the name of the attribute used for logging in. By default, it is uid
. For more information, see the section "Select the Attribute for the Login Name".
If you are integrating with Microsoft Active Directory, and the userprincipalname
attribute is used for logging in, then you would map userprincipalname
to the uid
attribute in Oracle Internet Directory
If you are integrating with Novell eDirectory or OpenLDAP, and the mail
attribute is used for logging in, then you would map mail
to the uid
attribute in Oracle Internet Directory
Set up the usersearchbase
and groupsearchbase
values in Oracle Internet Directory. These values indicate to the various Oracle components where to look for users and groups in Oracle Internet Directory. They are set to default values during installation. However, you may need to reset these values so that they correspond to the DIT structures in the two directories. Be sure to set them correctly. Otherwise, even if the synchronization seems to function properly, components still may be unable to access users and groups in Oracle Internet Directory.
To illustrate how you might configure the user search base and group search base: In the example in , the value of usersearchbase
should be set to cn=users,dc=us,dc=MyCompany,dc=com
or one of its parents. Similarly, assuming there is a subtree named groups
in the DIT, the multivalued groupsearchbase
attribute should be set to both of the following:
cn=groups,dc=us,dc=MyCompany,dc=com
or one of its parents
cn=users,dc=us,dc=MyCompany,dc=com
To configure the user search base and group search base, use the Oracle Internet Directory Self-Service Console.
Set up the usercreatebase
and groupcreatebase
values in Oracle Internet Directory. These values indicate to the various Oracle components where users and groups can be created. They are set to default values during installation.
To illustrate how to configure the user create base and group create base: In the example in , the value of usercreatebase
should be set to cn=users,dc=us,dc=MyCompany,dc=com
or one of its parents. Similarly, the groupcreatebase
should be set to cn=groups,dc=us, dc=MyCompany,dc=com
or one of its parents.
To configure the user create base and group create base, use the Oracle Internet Directory Self-Service Console.
See Also:
The section about modifying configuration settings for an identity management realm in Oracle Fusion Middleware Guide to Delegated Administration for Oracle Identity ManagementThis section discusses how to customize ACLs for import profiles, export profiles, and for other Oracle components. It contains these topics:
The import profile is the identity used by the Oracle Directory Integration Platform to access Oracle Internet Directory. ACLs must enable the import profile to add, modify, and delete objects in either the users and groups containers or the subtree where entries are accessed. By default, import profiles are part of the Realm Administrators group (cn=RealmAdministrators, cn=groups,cn=OracleContext
,realm_DN
) in the default realm. This group has privileges to perform all operations on any entry under the DN of the default realm.
You should not need to customize the ACLs for import synchronization with the default realm that is installed with Oracle Internet Directory Release 11g Release 1 (11.1.1). If you are upgrading from an earlier version of Oracle Internet Directory, or if the synchronization is with a nondefault Oracle Internet Directory realm, then be sure that the necessary privileges in the proper subtree or containers are granted to the import profiles handling the synchronization.
For an ACL template in LDIF format, see the file $ORACLE_HOME/ldap/schema/oid/oidRealmAdminACL.sbs. If you have not changed the ACLs on the default realm, then this template file can be applied directly after instantiating the substitution variables, replacing %s_SubscriberDN%
with the default realm DN in Oracle Internet Directory and replacing %s_OracleContextDN%
with cn=OracleContext
,default_realm_DN
respectively. For example, if realmacl.ldif
is the instantiated file, then you can upload it by using the following ldapmodify command. After executing the command, you will be prompted for the password for privileged directory user.
$ORACLE_HOME/bin/ldapmodify -h OID host -p OID port -D binddn -q -v -f realmacl.ldif
See Also:
The chapter about access controls in Oracle Fusion Middleware Administrator's Guide for Oracle Internet DirectoryTo enable the Oracle Directory Integration Platform to access a third-party directory, you must create an identity in third-party directory. This identity is configured in each export profile.
Default ACLs enable you to create, modify, and delete users and groups, but only in the users and groups containers under the default realm. To synchronize objects in other containers, you must customize the ACLs.
There are sample ACL files that you can use to customize ACLs for Oracle Components. These sample files are installed in the $ORACLE_HOME/ldap/schema/oid directory. They are:
oidUserAdminACL.sbs
—Grants necessary rights to the subtree for Oracle components to manage and access users
oidGroupAdminACL.sbs
—Grants necessary rights to the subtree for Oracle components to manage and access groups
oidUserAndGroupAdminACL.sbs
—Grants the privileges for Oracle components to manage and access users and groups in the subtree.
You can customize your ACL policy to grant privileges on a container-by-container basis with the required rights.
See Also:
The chapter about access controls in Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory for instructions on customizing ACLsMapping rules, an important part of the synchronization profile, determine the directory information to be synchronized and how it is to be transformed when synchronized. You can change mapping rules at run time to meet your requirements.
Each sample synchronization profile includes default mapping rules. These rules contain a minimal set of default user and group attributes configured for out-of-the-box synchronization.
Note:
When a synchronization is underway, it relies on the mapping rules configured prior to any changes in the directory. To ensure consistent mapping, you may need to remove an already synchronized entry or perform a full synchronization.Mapping rules govern the way data is transformed when a source directory and a destination directory are synchronized. Customize the default mapping rules found in the sample profiles when you need to do the following:
Change distinguished name mappings. The distinguished name mappings establish how the third-party directory DIT maps to the Oracle Internet Directory DIT.
Change the attributes that need to be synchronized.
Change the transformations (mapping rules) that occur during the synchronization.
You can perform any mapping if the resulting data in the destination directory conforms to the schema in that directory.
See Also:
The section "Configuring Mapping Rules" for a full discussion of mapping rules
The section "Supported Attribute Mapping Rules and Examples" for examples of how attribute values are transformed when synchronized from one directory to another
The file $ORACLE_HOME/ldap/odi/conf/activeimp.map.master for an example of import mapping rules
Once you have established a working synchronization between Oracle Internet Directory and a third-party directory, you can customize the attribute mapping rules for your synchronization profiles to meet the needs of your deployment.
To customize the attribute mapping rules for your synchronization profiles:
Make a duplicate of the sample mapping rules file. The sample mapping rules files are stored in the $ORACLE_HOME/ldap/odi/conf directory with the extension of map.master for the various profiles.
Edit the sample mapping rules file to make the previously discussed modifications. You can find instructions for editing mapping rules in "Configuring Mapping Rules".
After the changes are made, use the update
operation of the manageSyncProfiles command to update the profile. For example, the following command updates a profile name myImportProfile with a properties file named myPropertiesFile:
manageSyncProfiles update -profile profile_name -file myPropertiesFile
See Also:
The manageSyncProfiles section in the Oracle Directory Integration Platform tools chapter of the Oracle Identity Management User ReferenceWait until the scheduling interval has elapsed, and then check the synchronized users and groups to ensure that the attribute mapping rules meet your requirements.
Tip:
You may find it helpful to add test users and groups to Oracle Internet Directory or the third-party directory when customizing attribute mapping rules.By default, SSL is not enabled for the import and export synchronization profiles created with the expressSyncSetup
command. Whether or not you synchronize in the SSL mode depends on your deployment requirements. For example, synchronizing public data does not require SSL, but synchronizing sensitive information such as passwords does. To synchronize password changes between Oracle Internet Directory and a third-party directory, you must use SSL server authentication mode.
Note:
Be sure that you can successfully synchronize users in non-SSL mode before attempting to configure your synchronization profiles for SSL.Securing the channel requires:
Enabling SSL between Oracle Internet Directory and the Oracle Directory Integration Platform
Enabling SSL between the Oracle Directory Integration Platform and the third-party directory
Although you can enable SSL either between Oracle Internet Directory and the Oracle Directory Integration Platform or between that server and the third-party directory, Oracle recommends that you completely secure the channel before you synchronize sensitive information. In certain cases, such as password synchronization, synchronization can occur only over SSL.
Configuring SSL requires the following:
Running the Oracle directory server in SSL mode as described in the chapter on Secure Sockets Layer (SSL) in Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory.
Running the Oracle Directory Integration Platform in the SSL mode as described in Chapter 2, "Security Features in Oracle Directory Integration Platform". The SSL mode for Directory Integration Platform must be the same mode used when the Oracle Internet Directory server started. SSL mode 1 is no authentication and SSL mode 2 is server authentication.
Running the third-party directory server in SSL mode. Communication with a third-party directory over SSL requires SSL server authentication. This requires that both Oracle Internet Directory and the Oracle Directory Integration Platform be run in SSL server authentication mode.
Perform the following steps to configure communication with a connected directory in SSL mode:
Generate a certificate for the connected directory. Only the trust point certificate from the server is required. Put the certificate in the connected directory's certificate store.
Export the trusted Certificate Authority (CA) certificates to Base 64 encoded format.
Import the trusted CA certificates to the Java KeyStore (JKS) using the keytool command. If Oracle Directory Integration Platform is already using an existing JKS, identify the location of it using the -keystore
PATH_TO_JKS
option. If Oracle Directory Integration Platform does not already have a JKS to use, keytool will create one at the location identified by the -keystore
PATH_TO_JKS
option.
For example:
keytool –importcert –trustcacerts –alias mycert –file PATH_TO_CERTIFICATE \ -keystore PATH_TO_JKS
If this is the first time you are using the JKS identified by the -keystore
PATH_TO_JKS
option, you must provide its password and also perform the following steps a and b:
Update the Directory Integration Platform configuration with the location and password used in step 3 by using the manageDIPServerConfig
command. For example:
manageDIPServerConfig set -h HOST –p PORT -D WLS_USER \ -attribute keystorelocation -value PATH_TO_CERTIFICATE
Update the credential in the Credential Store Framework (CSF) using the following WLST command and replacing the PASSWORD variable with the password used when the keystore was created:
createCred(map="dip", key="jksKey", user="jksUser",
password="PASSWORD",desc="jks password")
Modify the third-party directory connection information, including the host name, profile, and connectedDirectoryURL
attribute, using the modify operation of the manageSyncProfiles command.
manageSyncProfiles update -profile profile_name -file myMapFile
When you configure the connectedDirectoryURL
attribute, use the following format:
host:port:sslmode
Supported values for sslmode
are as follows:
Table 17-1 Supported Values for sslmode in connectedDirectoryURL Attribute
Supported sslmode Value | Description |
---|---|
0 |
No SSL mode. Supported for all directory types. |
1 |
No Authentication mode. No certificate. Supported only for Oracle Internet Directory. |
2 |
Server-Only Authentication mode. Requires certificate. Supported for all directory types. |
If you used a new JKS in step 3, you must restart the Oracle Directory Integration Platform in SSL mode. If you used an existing JKS in step 3, go to step 6 now.
Add a test user and verify that it synchronizes successfully. If the test user does not synchronize successfully, then troubleshoot your SSL configuration.
Note:
The Oracle Directory Integration Platform does not support SSL in client/server authentication mode.To synchronize passwords from Oracle Internet Directory to a third-party directory, you must enable the password policy and you may have to enable reversible password encryption in the Oracle Internet Directory server.
Enable reversible password encryption in the Oracle Internet Directory server only if the hashing algorithm between Oracle Internet Directory and the third-party directory is incompatible or unsupported.
For example, IBM Tivoli Directory Server and Sun Java System Directory Server support similar hashing algorithms as Oracle Internet Directory. Therefore, to synchronize passwords from Oracle Internet Directory to IBM Tivoli Directory Server or Sun Java System Directory Server, you must enable only the password policy in the Oracle Internet Directory server.
However, to synchronize passwords from Oracle Internet Directory to Microsoft Active Directory or Novell eDirectory, which both do not support similar hashing algorithms as Oracle Internet Directory, you must enable the password policy and reversible password encryption in the Oracle Internet Directory server.
Note:
As of Oracle Internet Directory 10g (10.1.4.0.1), Oracle Internet Directory supports multiple password policies in each realm, commonly known as Fine-Grained Password Policies.Refer to the Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory for more information about Fine-Grained Password Policies.
To enable the password policy, assign a value of 1
to the orclPwdPolicyEnable
attribute in the appropriate container. To enable reversible password encryption in the Oracle Internet Directory server, assign a value of 1
to the orclpwdEncryptionEnable
attribute in the appropriate container.
For example, to enable the password policy and reversible password encryption on the default policy for a realm, assign a value of 1
to the orclPwdPolicyEnable
and orclpwdEncryptionEnable
attributes in the following entry:
cn=default,cn=PwdPolicyEntry,cn=common,cn=products,cn=oraclecontext,Realm_DN
You can do this by using ldapmodify
and uploading an LDIF file containing the following entries:
dn: cn=default,cn=PwdPolicyEntry,cn=common,cn=products,cn=oraclecontext,Realm_DN
changetype: modify
replace: orclpwdpolicyenable
orclpwdpolicyenable: 1
-
replace: orclpwdencryptionenable
orclpwdencryptionenable: 1
See Also:
Oracle Fusion Middleware Administrator's Guide for Oracle Internet Directory for information on managing Oracle Internet Directory password policies.Oracle Directory Integration Platform supports Java-based external authentication plug-ins. Oracle recommends that you use the Java plug-ins instead of the older, PL/SQL-based plug-ins, which only support Microsoft Active Directory and Sun Java System Directory Server.
The configuration tool for the plug-ins is a Java program called oidexcfg
. You use it to configure Java-based external authentication plug-ins for Microsoft Active Directory, Sun Java System Directory Server, Novell eDirectory, IBM Tivoli Directory Server, and OpenLDAP.
Note:
Theoidexcfg
tool configures an external authentication plug-in to work only with a single domain. You must perform the steps described in "Configuring External Authentication Against Multiple Domains" to set up an external authentication plug-in to work with multiple domains.To configure an external authentication plug-in, perform the following steps:
(Optional) Perform this step only if you want to use SSL to secure the communication between the authentication plug-in and the external LDAP directory. If you do not want to secure the communication, proceed to step 2 now.
To secure the communication between the authentication plug-in and the external LDAP directory using SSL, a trusted certificate from the external, authenticating directory must reside in a wallet on the file system. When you configure the plug-in using oidexcfg
in step 3, you will be prompted to enter information about the external LDAP directory configuration and you can identify the location of this wallet.
If you want to use SSL, put the certificate in a new or existing wallet now.
Note:
The certificate enables SSL to secure the communication between the authentication plug-in and the external LDAP directory—it does not secure the communication with Oracle Internet Directory when you executeoidexcfg
in step 3.Include oidexcfg.jar and ldapjclnt11.jar in the java CLASSPATH environment variable. To set the environment variable:
In UNIX/Linux environments:
setenv CLASSPATH=$ORACLE_HOME/jlib/oidexcfg.jar:$ORACLE_HOME/ldap/jlib/ldapjclnt11.jar:$CLASSPATH
In Windows environments:
set CLASSPATH=%ORACLE_HOME%/jlib/oidexcfg.jar;%ORACLE_HOME%/ldap/jlib/ldapjclnt11.jar;%CLASSPATH%
Configure the plug-in using oidexcfg
by executing the following command. You will be prompted to enter information about the external LDAP directory configuration, including the location of the wallet containing the trusted certificate required for SSL.
Note:
You must identify the location of the wallet file using a fully-qualified path, for example:/etc/ORACLE_HOME/wallets/ewallet.p12
Execute the following command to configure the plug-in using oidexcfg
:
java -classpath $CLASSPATH oracle.ldap.extplg.oidexcfg -h OID_Host -p OID_Port -D BindDN -w password -t Directory_Type
The -t option that identifies the directory type supports the following values:
ad
for Microsoft Active Directory
adam
for Microsoft Active Directory Application Mode
iplanet
for Sun Java System Directory Server
edirectory
for Novell eDirectory
openldap
for OpenLDAP
tivoli
for IBM Tivoli Directory Server
To set up an external authentication plug-in to work with multiple external authentication domains, you must perform some manual instructions after you run the external configuration tool. Proceed as follows:
Configure the external authentication plug-in as described in "Configuring External Authentication Plug-ins".
Search for the plug-in configuration entries created by the configuration tool in step 1, and redirect the search output to a file. Use an ldapsearch
command similar to this:
ldapsearch -p 3060 -D binddn -q -s sub -L \
-b "cn=plugin,cn=subconfigsubentry" cn="oidexplg_*_ad" >> output.ldif
Note:
You will be prompted for the password.The example shows an Microsoft Active Directory cn
. Use the correct plug-in cn
for the type of plug-in you configured, as shown in Table 17-2. You can use *
as a wildcard, as shown in the example.
Table 17-2 Distinguished Names of External Authentication Plug-ins
Plug-in Type | DN |
---|---|
Microsoft Active Directory |
|
Sun Java System Directory Server |
|
Novell eDirectory |
|
OpenLDAP |
|
Examine the output file. For an Microsoft Active Directory plug-in, the output file resembles the following:
dn: cn=oidexplg_compare_ad,cn=plugin,cn=subconfigsubentry cn: oidexplg_compare_ad objectclass: orclPluginConfig objectclass: top orclpluginname: oidexplg.jar orclplugintype: operational orclpluginkind: Java orclplugintiming: when orclpluginldapoperation: ldapcompare orclpluginsecuredflexfield;walletpwd: password orclpluginsecuredflexfield;walletpwd2: password orclpluginversion: 1.0.1 orclpluginisreplace: 1 orclpluginattributelist: userpassword orclpluginentryproperties: (!(&(objectclass=orcladobject)(objectclass=orcluserv2))) orclpluginflexfield;host2: host.domain.com orclpluginflexfield;port2: 636 orclpluginflexfield;isssl2: 1 orclpluginflexfield;host: host.domain.com orclpluginflexfield;walletloc2: /location/wallet orclpluginflexfield;port: 389 orclpluginflexfield;walletloc: /tmp orclpluginflexfield;isssl: 0 orclpluginflexfield;isfailover: 0 orclpluginclassreloadenabled: 0 orclpluginenable: 0 orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com dn: cn=oidexplg_bind_ad,cn=plugin,cn=subconfigsubentry cn: oidexplg_bind_ad objectclass: orclPluginConfigobjectclass: top orclpluginname: oidexplg.jar orclplugintype: operational orclpluginkind: Java orclplugintiming: when orclpluginldapoperation: ldapbind orclpluginversion: 1.0.1 orclpluginisreplace: 1 orclpluginentryproperties: (!(&(objectclass=orcladobject)(objectclass=orcluserv2))) orclpluginclassreloadenabled: 0 orclpluginflexfield;walletloc2: /location/wallet orclpluginflexfield;port: 389 orclpluginflexfield;walletloc: /tmp orclpluginflexfield;isssl: 0 orclpluginflexfield;isfailover: 0 orclpluginflexfield;host2: host.domain.com orclpluginflexfield;port2: 636 orclpluginflexfield;isssl2: 1 orclpluginflexfield;host: host.domain.com orclpluginenable: 0 orclpluginsecuredflexfield;walletpwd: password orclpluginsecuredflexfield;walletpwd2: password orclpluginsubscriberdnlist: cn=users,dc=us,dc=oracle,dc=com
Create a new LDIF file from the output file as follows:
Change the entry names. In the example shown in the previous step, you would change cn=oidexplg_compare_ad,cn=plugin, cn=subconfigsubentry
to cn=oidexplg_compare_
ad1
, cn=plugin,cn=subconfigsubentry
and cn=oidexplg_bind_ad, cn=plugin,cn=subconfigsubentry
to cn=oidexplg_bind_
ad1
, cn=plugin,cn=subconfigsubentry
.
Change the value for orclpluginenable
. Use value 1
if you want to enable it, and use value 0
if you want to disable it.
Change the values for orclpluginflexfield;host
and orclpluginflexfield;port
for the external directory host name and port number.
Change the value for orclpluginflexfield;isssl
. Use value 1
if you want to enable the SSL connection against the external directory, and use value 0
if you want to disable. If you use value 1
, you will also need to change the value of orclpluginflexfield;walletloc
and orclpluginsecuredflexfield;walletpwd
for the wallet location and password.
Change orclpluginflexfield;isfailover
. Use value 1
if to set up the failover against a backup external directory. If you use value 1
, then you must also change the value of orclpluginflexfield;host2
, orclpluginflexfield;port2
for the host name and port number. To use an SSL connection against the backup directory server, you must to change the value for orclpluginflexfield;walletloc2
and orclpluginsecuredflexfield;walletpwd2
.
Modify orclpluginsubscriberdnlist
for the plug-in invocation naming context.
Modify orclPluginRequestGroup
for the plug-in request group. If this attribute is missing in the search out put, then just add the attribute and value in the LDIF file.
Add the modified plug-in configuration entries to the Oracle Internet Directory server. Use a command similar to the following:
$ORACLE_HOME/ldap/bin/ldapadd -h host -p port -D binddn -q \ -v -f input.ldif
Note:
You will be prompted for the password.Oracle Directory Integration Platform supports custom synchronization connectors. This topic provides information to help you write custom connectors and contains the following sections:
Perform the following steps to write an inbound connector:
Implement the Reader. The Reader generally extends the target system connector class and implements the DISReadInterface. The different methods of the DISReadInterface are specified in its the javadoc. Refer to "Sample Reader" to see an example Reader implementation.
Create a sample config file. The following is a typical config file:
[INTERFACEDETAILS]
Reader: Complete_classname_including_packageName
SkipErrorToSyncNextChange: false
SearchDeltaSize: 500
UpdateSearchCount: 100
Create a mapfile containing a set of mapping rules.
Create a properties file by setting the configfile, mapfile, and filter parameters.
To test the inbound connector:
Create a test profile using the register operation of the manageSyncProfiles command. Refer to "Managing Synchronization Profiles Using manageSyncProfiles" for more information.
Verify your logging messages.
Verify synchronization occurred by examining Oracle Internet Directory to see if the appropriate entries were created.
package oracle.ldap.odip.gsi; import oracle.ldap.odip.engine.AttrHandler; import oracle.ldap.odip.engine.ChangeRecord; import oracle.ldap.odip.engine.Connector; import oracle.ldap.odip.engine.ConfigReader; import oracle.ldap.odip.engine.Constants; import oracle.ldap.odip.engine.DISReadInterface; import oracle.ldap.odip.engine.DISFilterInterface; import oracle.ldap.odip.engine.ODIException; import oracle.ldap.odip.engine.Debug; import oracle.ldap.odip.map.MapRules; import oracle.ldap.odip.map.OrclFilter; import oracle.ldap.odip.util.Utils; //Imports added for ODLLogger import oracle.core.ojdl.logging.ODLLogger; import oracle.dms.context.ExecutionContext; import oracle.core.ojdl.logging.ODLLevel; import oracle.core.ojdl.logging.ODLHandler; import java.util.logging.Handler; import java.util.logging.Level; import oracle.ldap.odip.DIPLogger; public class SampleReader implements DISReadInterface { /* ** Member variables used */ protected NamingEnumeration mEnumerate; protected Attributes mAttribs; protected Attribute mAttrib; protected Attribute mAttribAllValues; protected SearchResult mResult; protected MapRules mMapRules; /* ** Vector to store the list of required attributes */ protected Vector mReqAttrList = new Vector(); /* ** List of source attributes whose changes need to be mapped */ protected Vector mSrcAttrList = new Vector(); protected String mMapFilter; protected int mAppliedChangeNum = 0; protected int mAvailableChangeNum = 700; protected DISFilterInterface mFilter; /* ** LastChangeNumber that is read */ protected String mReadChangeNum; /* ** List of attributes to be returned in changelog LDAPSearch */ protected String[] mRetAttribs; private int mErrorCode = 0; /* ** Constructor */ public SampleReader() { } /** ** Constructor with the connector */ public SampleReader( Connector conn ) { super(conn); } /** ** Get the last change key value ** * @param boolean Operation is success/failure * @return Object lastkeyvalue to be stored */ public Object getLastChangeKey(boolean val) { if ( val == false ) { int nval = Integer.parseInt(mReadChangeNum); if ( nval > 0 ) { nval--; } mReadChangeNum = String.valueOf(nval); } return (mReadChangeNum); } /** ** Initializes required values from hashtable passed from Profile ** ** @param Connector connection details with credentials ** @param Hashtable with the required parameters ** @throws ODIException Indicating connection failure */ public void initialise(Connector conn,Hashtable pHash) throws ODIException { m_logger.finest ( "Entry: SampleReaders.initialise"); setValues(conn); mMapRules = (MapRules)pHash.get(Constants.MAPRULE_STR); readCtx = connect(); pHash.put("READCONTEXT", readCtx); pHash.put(Constants.READERCHANGEKEY_STR, Constants.CHANGE_NUM); String key = (String)pHash.get(Constants.LASTAPPLIEDCHG_STR); String val = null; if ( key != null ) val = (String)pHash.get(key); if ( val != null ) mAppliedChangeNum = Integer.parseInt((String)pHash.get(key)); mReadChangeNum = (String)pHash.get(key); pHash.put(key, mReadChangeNum); mFilter = (DISFilterInterface)pHash.get(Constants.MATCHRULE_STR); mAvailableChangeNum = Integer.parseInt(initAvailableChgKey()); mSaveLastChgNum = mAppliedChangeNum; try { SearchControls pControls = new SearchControls(); pControls.setSearchScope(SearchControls.OBJECT_SCOPE); pControls.setReturningAttributes(mRetAttribs); pControls.setTimeLimit(3000000); mEnumerate = mLdapCtx.search("","objectclass=*",pControls); while ( mEnumerate.hasMoreElements() ) { mResult = (SearchResult)mEnumerate.nextElement(); mAttribs = mResult.getAttributes(); } // END INFEASIBLE ConfigReader configInfo = (ConfigReader) pHash.get(Constants.CONFINFO_STR); if (configInfo != null) { mUpdateSearchCount = configInfo.getUpdateSearchCount(); mSearchDelta = configInfo.getSearchDeltaSize(); } } catch (Exception ex) // BEGIN INFEASIBLE { throw new ODIException(ODIException.LDAP_INITIALIZATION_EXCEPTION,ex); } // END INFEASIBLE m_logger.finest ( "Exit: SampleReaders.initialise"); } /** ** Search the changelog ** @throws ODIException */ public int searchChanges() throws ODIException { int temp; int searchDelta = (int) mSearchDelta; if ( mAvailableChangeNum <= mAppliedChangeNum ) return -1; int minChgNum = mAppliedChangeNum+1; if ( mAvailableChangeNum - mAppliedChangeNum >= searchDelta) temp = mAppliedChangeNum + searchDelta; else temp = mAvailableChangeNum; String searchF = ""; if ( mFilter != null ) { searchF = mFilter.getSearchFilter(); m_logger.log(ODLLevel.NOTIFICATION,"SEARCHF", searchF ); } StringBuffer filter = new StringBuffer(300); /** * SearchChanges is called to get all changes * */ try { mEnumerate = mReadCtx.search( filter.toString()); } catch ( Exception ex ) // BEGIN INFEASIBLE { throw ( new ODIException(ODIException.LDAP_SEARCH_EXCEPTION, ex) ); } finally { m_logger.log(ODLLevel.NOTIFICATION, "SEARCH_SUCCESSFUL" ,new Integer( temp )); mAppliedChangeNum = temp; return mErrorCode; } public boolean hasMore() throws ODIException { boolean retval = false; int count =0; try { if ( mEnumerate.hasMoreElements() ) { retval = true; } else { while ( mAvailableChangeNum > mAppliedChangeNum ) { if ( count >= mUpdateSearchCount ) break; searchChanges(); count++; if (mEnumerate.hasMoreElements()) { retval = true; break; } else mReadChangeNum = String.valueOf(mAppliedChangeNum); } } } catch( Exception ex ) // BEGIN INFEASIBLE { throw (new ODIException(ODIException.LDAP_HASMORE_EXCEPTION,ex)); } // END INFEASIBLE if (retval == false) { // no more results mReadChangeNum = (new Integer(mAvailableChangeNum)).toString(); } return retval; } /** ** Read the next change from the source ** ** @return Object the header part of the changes read. */ public Object getNextChange() throws ODIException { try { if ( mEnumerate.hasMoreElements() ) { mResult = (SearchResult)mEnumerate.nextElement(); mAttribs = mResult.getAttributes(); } catch ( Exception e ) // BEGIN INFEASIBLE { throw (new ODIException (ODIException.LDAP_GETNEXT_EXCEPTION, e)); } // END INFEASIBLE return mAttribs; } /** ** Create the change record from the data read from the file. ** ** @returns ChangeRecord */ public ChangeRecord createChangeRecord(String dn) throws ODIException { // Create the changerecord based on the mAttribs which contains all the attributes. } public String initAvailableChgKey() throws ODIException { // set the available changekey value. This reads the value equivalent to the latest changelog number in the ldap world. } }
Perform the following steps to write an outbound connector:
Implement the Writer. The Writer generally extends the target system connector class and implements the DISWriteInterface. The different methods of the DISWriteInterface are specified in its the javadoc. Refer to "Sample Writer" to see an example Reader implementation.
Create a sample config file. The following is a typical config file:
[INTERFACEDETAILS]
Reader: Complete_classname_including_packageName
SkipErrorToSyncNextChange: false
SearchDeltaSize: 500
UpdateSearchCount: 100
Create a mapfile containing a set of mapping rules.
Create a properties file by setting the configfile, mapfile, and filter parameters.
To test the outbound connector:
Create a test profile using the register operation of the manageSyncProfiles command. Refer to "Managing Synchronization Profiles Using manageSyncProfiles" for more information.
Verify your logging messages.
Verify synchronization occurred by examining Oracle Internet Directory to see if the appropriate entries were created.
*/ import oracle.ldap.odip.engine.AttrHandler; import oracle.ldap.odip.engine.ChangeRecord; import oracle.ldap.odip.engine.ConfigReader; import oracle.ldap.odip.engine.Connector; import oracle.ldap.odip.engine.Constants; import oracle.ldap.odip.engine.DISWriteInterface; import oracle.ldap.odip.engine.ODIException; import oracle.ldap.odip.map.MapRules; import oracle.ldap.odip.util.Utils; import oracle.core.ojdl.logging.ODLLogger; import oracle.core.ojdl.logging.ODLLevel; import oracle.core.ojdl.logging.ODLHandler; import java.util.logging.Handler; import java.util.logging.Level; import oracle.ldap.odip.DIPLogger; public class SampleWriter implements DISWriteInterface { protected Hashtable mProfile; protected int mErrorCode = 0; protected String mLastKeyValue; protected String mLastWrittenKey; protected Vector mWriteFilter = new Vector(); protected MapRules mMapRules; protected String mNamingContext = ""; private String mOrigDstDn = ""; protected boolean mHandleModAsAdd = false; /* Constructor */ public LDAPWriter() { } public LDAPWriter(Connector conn) { super(conn); } public void initialise(Connector conn, Hashtable pHash) throws ODIException { m_logger.finest("Entry: LDAPWriter.initialise"); setValues(conn); mProfile = pHash; mMapRules = (MapRules) pHash.get(Constants.MAPRULE_STR); connect(); ConfigReader configInfo = (ConfigReader) pHash.get(Constants.CONFINFO_STR); if (configInfo != null) { //mSearchDelta = configInfo.getSearchDeltaSize(); mHandleModAsAdd = configInfo.getHandleModAsAdd(); } mLastWrittenKey = (String) pHash.get(Constants.READERCHANGEKEY_STR); pHash.put("WRITECONTEXT", mLdapCtx); NamingEnumeration filter = (NamingEnumeration) pHash.get("WriteFilter"); try { while (filter.hasMoreElements()) { mWriteFilter.add((String) filter.next()); } } catch (Exception ex) { //System.out.println("Error in initializing filter"); } /* ** Get the lastapplied changekey value from the profile ** and use that string to determine the 'lastappliedchangenum' ** or lastappliedchangetime to be stored as the 'lastkeyvalue' ** ** Each of the insert/modify/delete routines, if the operation is ** successful, that lastkeyvalue is updated correspondingly. Otherwise ** it has the previous successful operation value */ m_logger.finest ( "Exit: LDAPWriter.initialise" ); } public void setChanges(ChangeRecord chgrec) { mChanges = chgrec; } public ChangeRecord getChanges() { return mChanges; } public String getLastChangeKey() { return mLastKeyValue; } public int writeChanges() throws ODIException { m_logger.finest("Entry: LDAPWriter.writeChanges"); mErrorCode = 0; m_logger.log(ODLLevel.FINE, "\n Output ChangeRecord " + mChanges.toString()); String dn = mChanges.getChangeKey(); if ( mHandleModAsAdd && (mChanges.getChangeType() == Constants.CHGTYPE_MODIFY)) { try { mLdapCtx.getAttributes( mChanges.getChangeKey() ); } catch (NameNotFoundException nnfe) { m_logger.log(ODLLevel.ERROR,"ERROR_DN_CONN_DIR"); mChanges.setChangeType(Constants.CHGTYPE_MODRADD); } catch (NamingException ne) { m_logger.log(ODLLevel.ERROR,"LDAP_WNAMING_EXCEPTION" , ne); } } m_logger.log(ODLLevel.FINE, "Changetype is " + mChanges.getChangeType()); mChanges.setChangeKey(ndn); if (dn.length() > 1) { //testnew(dn); switch (mChanges.getChangeType()) { case Constants.CHGTYPE_ADD: if (mChanges.size() > 0) { insert(); } break; case Constants.CHGTYPE_MODIFY: // non-changelog-based changes if (mChanges.size() > 0) { modify(); } else { mErrorCode = -1; } break; case Constants.CHGTYPE_DELETE: delete(); break; case Constants.CHGTYPE_MODRADD: // non-changelog-based changes if (mChanges.size() > 0) { modifyRadd(); } break; case Constants.CHGTYPE_MODRDN: modRDNchangelog(dn); break; case Constants.CHGTYPE_MODDN: m_logger.log(ODLLevel.FINE, "Processing moddn"); modDNchangelog(dn); break; default: //INFEASIBLE break; } } else // BEGIN INFEASIBLE { m_logger.log(ODLLevel.ERROR, "ENTRY_NOT_EXISTS_DELETE"); m_logger.log(ODLLevel.FINE, "Synchrozing a deletion, entry to delete is not found. Ignore."); mErrorCode = 99; return mErrorCode; } // END INFEASIBLE Object chgInfo = mChanges.getChangeInfo(); try { if (chgInfo instanceof Attributes) { Attributes attrs = (Attributes) chgInfo; mLastKeyValue = (String) ((Attribute) attrs.get(mLastWrittenKey)).get(); } } catch (Exception ex) { //System.out.println("Caught the exception here " + mErrorCode); if (mErrorCode != 0) { m_logger.log(ODLLevel.ERROR, "EXCEPTION_FOR_DN", new Object [] { dn, new Integer ( mErrorCode ) , ex.toString()}); } } mChanges.setChangeKey(mOrigDstDn); return mErrorCode; } public void insert() throws ODIException { m_logger.finest("Entry: LDAPWriter.insert"); String dn = mChanges.getChangeKey(); Enumeration attrdtls = mChanges.getAll(); m_logger.log(ODLLevel.FINE, "Processing Insert Operation .."); while (attrdtls.hasMoreElements()) { AttrHandler temp = (AttrHandler) attrdtls.nextElement(); attr = attrHandlerToAttr((AttrHandler) temp); if (attr != null && temp.getAttrChgType() != Constants.ATTRCHGTYPE_DELETE) { attrs.put(attr); } } createEntry(dn, attrs); m_logger.finest("Exit: LDAPWriter.insert"); } public void modify() throws ODIException { m_logger.finest("Entry: LDAPWriter.modify"); String attrname = mChanges.getChangeKey(); m_logger.log(ODLLevel.FINE, "Processing Modify Operation .."); int pos = attrname.indexOf('='); String naming = null; if (pos > 0) { naming = attrname.substring(0, pos).trim(); } } /** * Delete the entry */ public void delete() { m_logger.finest("Entry: LDAPWriter.delete"); try { m_logger.log(ODLLevel.FINE, "Processing Delete Operation .."); } /** ** Handle the ModRDN operation ** ** @throws ODIException */ protected void modDNchangelog(String newDn) throws ODIException { String newDN = null; m_logger.log(ODLLevel.FINE, "Processing change log based ModRDN operation .." + " DN passed in: " + newDn); String dn = mChanges.getChangeKey(); } /** ** Handle the ModRDN operation ** ** @throws ODIException */ protected void modRDNchangelog(String newDn) throws ODIException { } protected void performModDN(String oldDN, String newDN) throws ODIException { } /* ** First check whether the 'dn' already exists. ** If exists, ** do a modify. ** else ** construct objectclasses and do a add */ // public void modifyRadd(boolean rdn) throws ODIException public void modifyRadd() throws ODIException { m_logger.finest("Entry: LDAPWriter.modifyRadd"); } /** ** Compare the value with the old value, and replace it, if the new value ** is different from the old value */ public void checkNReplace(String dn, Attributes attrs) throws ODIException { } //BEGIN INFEASIBLE public int getErrorCode() { return mErrorCode; } public int getChangeType() { return mChanges.getChangeType(); } public String getEventType() { return ""; } //END INFEASIBLE }