This chapter contains generic instructions for synchronizing the Oracle back-end directory with a connected directory. It contains these topics:
Note:
This chapter assumes that you are familiar with Chapter 19, "Connected Directory Integration Concepts and Considerations".See Also:
The following chapters for step-by-step instructions about configuring integration between the Oracle back-end directory and the following connected directories:To prepare for synchronization between the Oracle back-end directory and a connected directory, do the following:
Verify that the Oracle back-end directory and the other directory are running.
Create a user account in the connected 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 Connected 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 connected directory that are to be synchronized with the Oracle Directory Integration Platform. To verify whether a connected directory user account has the necessary privileges to all objects to be synchronized with the Oracle back-end 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 Connected 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:
The connected directory documentation for information about how to grant privileges to user accountsYou must also ensure that the Oracle back-end directory is running with change logging enabled, and that the change log purge duration is set to a minimum of seven days.
See Also:
"Oracle Internet Directory Administration Tools" in the Oracle Fusion Middleware Reference for Oracle Identity Management for instructions about how to start an Oracle directory server with change logging enabled.
"orclPurgeTargetAge" in the Oracle Fusion Middleware Reference for Oracle Identity Management for instructions about how to set the change log purge duration.
”Replicating Directory Data” in the Oracle Fusion Middleware Administering Oracle Unified Directory.
”Directory Server Replication” chapter in Oracle Fusion Middleware Administrator's Guide for Oracle Directory Server Enterprise Edition.
The expressSyncSetup
command located in the ORACLE_HOME/bin
directory allows you create import and export synchronization profiles for express synchronization.
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. The 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:
administrator@idm2003.net
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.
Specify unlimited
as the entries size limit, if Oracle Directory Server Enterprise Edition is the back-end directory.
expressSyncSetup -h myhost.mycompany.com -p 7005 -D login_ID -pf myProfile \
-conDirType ACTIVEDIRECTORY -conDirUrl server.mycompany.com:5432 \
-conDirBindDN administrator@idm2003.net -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 connected directory and the container in the Oracle back-end 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 you are finished customizing and testing your synchronization profiles.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
, whereas users of the default realm in Oracle Unified Directory and Oracle Directory Server Enterprise Edition are located in the container cn=users,
default_metadata_suffix
.
Entries for groups of the default realm are located in the container cn=groups,
default_realm_DN
for Oracle Internet Directory, and in the container default_metadata_suffix for Oracle Unified Directory and Oracle Directory Server Enterprise Edition.
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 an 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 dipadmingrp have the necessary privileges.
In Oracle Internet Directory, the Oracle Directory Integration Platform Administrators group is as follows:
cn=dipadmingrp,cn=dipadmins,cn=directory integration platform,cn=products,cn=oraclecontext
In Oracle Unified Directory and Oracle Directory Server Enterprise Edition, the Oracle Directory Integration Platform Administrators group is as follows:
cn=dipadmingrp,cn=dipadmins,cn=directory integration platform,<suffix>
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 connected directory, and cn=users,
default_realm
in the Oracle back-end 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 connected directory to the Oracle back-end directory and enable the profile_name
Export
profile if you need to synchronize from the Oracle back-end directory to a connected directory. Enable the profile by using the manageSyncProfiles
command with the activate
operation.
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 10, "Managing Directory Synchronization Profiles" for information about using Oracle Enterprise Manager Fusion Middleware Control.When synchronization is successfully started:
The value of the Synchronization Status
attribute is orclodipsynchronizationstatus
.
The value of the Last orclodiplastsuccessfulexecutiontime
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:
orclodiplastsuccessfulexecutiontime 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 the Oracle back-end directory and the connected directory to confirm that users and groups are synchronizing between cn=users,default_naming_context
in the connected directory, and cn=users,
default_realm
in the Oracle back-end directory.
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 Oracle and third-party connected 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 the Oracle back-end directory and a connected 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 Connected Directory Connector for Synchronization in SSL Mode
Enabling Password Synchronization from the Oracle Back-end Directory to a Connected Directory
See Also:
The individual connected 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.
Note:
If your Oracle back-end directory is Oracle Unified Directory or Oracle Directory Server Enterprise Edition, the default container in those directories is the metadata suffix. Consequently, you may need to addcn=users,
<metadata_suffix> and cn=groups,
<metadata_suffix> entries and update the domain mapping rules as needed.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 the Oracle back-end 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 the Oracle back-end directory.
Set up the usersearchbase
and groupsearchbase
values in the Oracle back-end directory. These values indicate to the various Oracle components where to look for users and groups in the Oracle back-end 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 the Oracle back-end 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
Configure the user search base and group search base using the Oracle Directory Services Manager (For Oracle Unified Directory and Oracle Internet Directory) or Directory Service Control Center (For Oracle Directory Server Enterprise Edition).
Set up the usercreatebase
and groupcreatebase
values in the Oracle back-end 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.
Configure the user create base and group create base using the Oracle Directory Services Manager (For Oracle Unified Directory and Oracle Internet Directory) or Directory Service Control Center (For Oracle Directory Server Enterprise Edition).
This section discusses how to customize ACLs for import profiles, export profiles, and for other Oracle components. It contains these topics:
The import profile uses the identity used by the Oracle Directory Integration Platform to access the Oracle back-end 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 DIP Administrator group (cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext
) and of the import profile group (cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext
). Those groups have appropriate privileges on cn=oraclecontext suffix but they need to be given appropriate privileges to perform the required actions for an import profile.This group has privileges to perform all operations on any entry under the DN of the default realm.
Customizing an ACL for Oracle Unified Directory or Oracle Directory Server Enterprise Edition Back-end Directories
If your Oracle back-end directory is either Oracle Unified Directory or Oracle Directory Server Enterprise Edition, the import profile can add, modify, and delete users and groups under the DN of the metadata suffix. For a non-metadata suffix, the ACL has to be set as follows so that the containers can import the users and groups from the other source:
dn: <Container DN> changeType: modify add: aci aci: (target="ldap:///<Container DN>")(version 3.0; acl "Entry-level DIP permissions"; allow (all,proxy) groupdn="ldap:///cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; allow (all,proxy) groupdn="ldap:///cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; ) - add: aci aci: (targetattr="*")(version 3.0; acl "Attribute-level DIP permissions"; allow (all,proxy) groupdn="ldap:///cn=dipadmingrp,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext"; allow (all,proxy) groupdn="ldap:///cn=odipigroup,cn=DIPadmins,cn=Directory Integration Platform,cn=Products,cn=OracleContext";)
Customizing an LDIF ACL for Oracle Unified Directory or Oracle Directory Server Enterprise Edition Back-end Directories
Refer to the ACL example given above. As needed, replace <Container DN>
with the DN under which the operations are to be performed.
You can upload an LDIF file using the following ldapmodify
command:
$ORACLE_HOME/bin/ldapmodify -h <backend-host> -p <backend-port> -D <binddn> -f <ldif-file>
After executing the command, you will be prompted for the password for privileged directory user.
Customizing an ACL for an Oracle Internet Directory Back-end Directory
If your Oracle back-end directory is Oracle Internet Directory, 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.
See Also:
The chapter about access controls in Oracle Fusion Middleware Administrator's Guide for Oracle Internet DirectoryCustomizing an LDIF ACL for an Oracle Internet Directory Back-end Directory
For an ACL template in LDIF format, see the file $ORACLE_HOME/ldap/schema/oid/oidRealmAdminACL.sbs
. If your Oracle back-end directory is Oracle Internet Directory and 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:
$ORACLE_HOME/bin/ldapmodify -h <backend-host> -p <backend-port> -D <binddn> -f <ldif-file>
After executing the command, you will be prompted for the password for privileged directory user.
To enable the Oracle Directory Integration Platform to access a connected directory, you must create an identity in the connected directory. This identity is configured in each export profile.
To Customize the ACL to Support the Synchronization of User Records Located Outside of the Default Realm
If your Oracle back-end directory is Oracle Internet Directory and you need to synchronize user records located outside of the Oracle Internet Directory default realm, modify the ACL using an LDIF file as follows.
Note:
This ACL change is required to export OID user passwords that are outside of the default realm to connected directories using DIP sync.Query the ACIs in the root-directory specific entry, and save the output to an LDIF file as a backup:
ldapsearch -h OID host -p port -D cn=orcladmin -w password -s base -L -b "" objectclass=* orclaci orclentrylevelaci > /tmp/orig-root-acis.ldif
Find the following ACI:
orclaci: access to attr=(userpkcs12,orclpkcs12hint,userpassword,pwdhistory,orclrevpwd) by group="cn=OracleUserSecurityAdmins,cn=Groups,cn=OracleContext" (search,read,write,compare) by self (search,read,write,compare) by * (none)
Modify the ACI to include the DIP DN and save the file as new-root-acis.ldif
.
Your modified file should look like this:
orclaci: access to attr=(userpkcs12,orclpkcs12hint,userpassword,pwdhistory,orclrevpwd) by group="cn=OracleUserSecurityAdmins,cn=Groups,cn=OracleContext" (search,read,write,compare) by self (search,read,write,compare) by dn="cn=odisrv,cn=Registered Instances,cn=Directory Integration Platform,cn=products,cn=oraclecontext" (search,read)* by * (none)
Add the following two lines after the first line of the file:
changetype: modify replace: orclaci
The top of your file should read as follows:
dn: Container DN
changetype: modify
replace: orclaci
orclaci: access to
...
Use the ldapmodify
command to apply the modified ACI:
$ORACLE_HOME/bin/ldapmodify -h <backend-host> -p <backend-port> -D <binddn> -f <ldif-file>
Mapping 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 connected directory DIT maps to the Oracle back-end 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 the Oracle back-end directory and a connected 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 Fusion Middleware Reference for Oracle Identity Management.Wait 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 the Oracle back-end directory or the connected 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 the Oracle back-end directory and a connected 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 the Oracle back-end directory and the Oracle Directory Integration Platform
Enabling SSL between the Oracle Directory Integration Platform and the connected directory
Although you can enable SSL either between the Oracle back-end directory and the Oracle Directory Integration Platform, or between that server and the connected 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 the Oracle back-end directory server started. SSL mode 1 is no authentication and SSL mode 2 is server authentication.
Note:
Oracle Directory Integration Platform only supports the No Authentication SSL mode (SSL mode 1) if your Oracle back-end directory is Oracle Internet Directory. If Oracle Unified Directory or Oracle Directory Server Enterprise Edition is your Oracle back-end directory, SSL Server Authentication (SSL mode 2) is your only SSL option.Running the connected directory server in SSL mode. Communication with a connected directory over SSL requires SSL server authentication. This requires that both the Oracle back-end 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_JKS \ -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_JKS
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 connected 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 20-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.For more information, see Section 9.8, "Password Synchronization.".
Oracle Internet Directory 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 Oracle Directory Server Enterprise Edition / 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, Oracle Directory Server Enterprise Edition (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 the Oracle back-end 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/ldap/jlib/oidexcfg.jar:$ORACLE_HOME/ldap/jlib/ldapjclnt11.jar:$CLASSPATH
In Windows environments:
set CLASSPATH=%ORACLE_HOME%/ldap/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 Oracle Directory Server Enterprise Edition and 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 20-2. You can use *
as a wildcard, as shown in the example.
Table 20-2 Distinguished Names of External Authentication Plug-ins
Plug-in Type | DN |
---|---|
Microsoft Active Directory |
|
Oracle Directory Server Enterprise Edition |
|
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 output, 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 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 }