Friday, March 19, 2010

OIM AD Connector Enhancement for Deleting eSSO Enabled Accounts

This sample code is intended to enable AD connector (version prior to 9.1) to delete users that are eSSO enabled. Currently the connector cannot handle the scenario when eSSO stores the users configuration data under the respective user object. The code provided can enhance the connector to delete the leafs associated with the user, enabling the default connector code to delete the user object.

Please note that this issue has been addressed in the 9.1 version of the AD connector by adding the parameter isUserDeleteLeafNode in the IT Resource. By enabling this parameter, the delete operation will use the TreeDeleteControl (1.2.840.113556.1.4.805) to delete all the sub-leafs in one operation.

This fix is done for Bug 6407478 DEPROVISIONING OF AD USER RESOURCE FAILS WHEN THE USER OBJECT HAS LEAF NODES

Software Requirements/Prerequisites

To compile the code Java JDK is needed, the same as the JDK used by the Application Server running OIM.

Configuring the Sample Code

The ADESSOExtension class from this example extends com.thortech.xl.integration.ActiveDirectory.tcUtilADTasks class from the default AD connector, overriding deleteUser method.

1. Create the following folders in your development workspace:

OIM_AD_ESSO

OIM_AD_ESSO/com/custom/AD

OID_AD_ESSO/lib

2. Create the file ADESSOExtension.java in OIM_AD_ESSO/com/custom/AD

3. Copy xliActiveDirectory.jar and xlVO.jar to OIM_AD_ESSO/lib

(the files can be found under current Xellerate home directory)

4. Review the java file and compile it with the command (run the command from OIM_AD_ESSO folder)

javac -classpath lib/xliActiveDirectory.jar;lib/xlVO.jar com/custom/AD/*

5. Build a JAR file containing the class:

jar cvf ad_esso.jar com

6. Copy the JAR file created to OIM_HOME/xellerate/JavaTasks

Running the Sample Code

To configure the adapter to call the custom code perform the following actions:

1. Open Design Console and search for the adapter (AD Delete User) in Adapter Manager

2. Add a Java Task before "Delete user" task

2.1 Functional Task-> Java -> New Object Instance

2.2 Set task name as "Delete Leafs"

2.3 Select API Source as JavaTaskJar:ad_esso.jar

2.4 Select Method as com.custom.AD.ADESSOExtension.deleteUser(....) and click Save

2.5 Map constructor parameters as Adapter Variables -> ADServer (your resource name) in the order:

Server Address,RootContext, Admin FQDN,Admin Password,UseSSL,SSL Port Number,TargetLocale Language, TargetLocale Country

2.6 Map the method parameters as:

Output: Adapter Variables->Return Variable

Input: Adapter Task->Get Hierarchy

Input: Adapter Task->Get User Object Name

3. Save the adapter and re-build it

Caution

This sample code is provided for educational purposes only and not supported by Oracle Support Services. It has been tested internally, however, and works as documented. We do not guarantee that it will work for you, so be sure to test it in your environment before relying on it.

Proofread this sample code before using it! Due to the differences in the way text editors, e-mail packages and operating systems handle text formatting (spaces, tabs and carriage returns), this sample code may not be in an executable state when you first receive it. Check over the sample code to ensure that errors of this type are corrected.

package com.custom.AD; 

import java.util.Vector; 
import java.util.logging.Logger; 

public class ADESSOExtension extends com.thortech.xl.integration.ActiveDirectory.tcUtilADTasks { 

  public static Logger logger = Logger.getLogger("XL_INTG.ACTIVEDIRECTORY"); 

  public ADESSOExtension(String ad_server, String rootcon, String princDN, 
     String p_password, String pbSSL, String sslPort, String language, 
     String country) throws Exception { 
       super(ad_server, 
           rootcon, 
           princDN, 
           p_password, 
           pbSSL, 
          sslPort, 
          language, 
          country 
      ); 
  } 


  public boolean deleteUser(String hierarchy, String username) throws Exception { 
     hierarchy = checkHierarchy(hierarchy); 
     Vector v = getObjects("cn="+username + "," + "cn="+username + "," + hierarchy); 
     logger.info("Found " + v.size() + " leafs..."); 
     for (int i=v.size()-1;i>-1;i--){  


       logger.info("Found leaf: " + v.get(i).toString()); 
       String name = v.get(i).toString(); 
       if (!"".equals(name.trim()) && name.length()>3){ 
        super.deleteUser("cn="+username + "," + "cn="+username + "," + hierarchy,name.substring(3)); 
       } 
     } 

super.deleteUser("cn="+username + "," + hierarchy,username); 
     return true; 
  } 


Code Output

23:02:21,515 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\SupportTools\
23:02:24,937 INFO [STDOUT] Dec 3, 2007 11:02:24 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found 5 leafs...
23:02:25,031 INFO [STDOUT] Dec 3, 2007 11:02:25 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found leaf:
23:02:25,125 INFO [STDOUT] Dec 3, 2007 11:02:25 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found leaf: CN=D4B13D82-9279-4A89-AEEA-802FDDD45B87
23:02:25,218 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\
23:02:28,406 INFO [STDOUT] Dec 3, 2007 11:02:28 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found leaf: CN=SSOProvisioning
23:02:28,500 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\
23:02:31,703 INFO [STDOUT] Dec 3, 2007 11:02:31 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found leaf: CN=SyncState
23:02:31,796 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\
23:02:37,468 INFO [STDOUT] Dec 3, 2007 11:02:37 PM com.custom.AD.ADESSOExtensio n deleteUser
INFO: Found leaf: CN=208a5b4e-1c22-4cba-8f56-364ee6c126e3
23:02:37,578 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\
23:02:40,875 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\
23:02:45,906 INFO [STDOUT] Running Delete User
23:02:45,937 INFO [ACTIVEDIRECTORY] Certificate Path::C:\Program Files\Support Tools\

How to Change the Default Location (cn=Users,dc=domain,dc=com) for Creating Users in AD using OIM AD Connector?

How to create users in desired hierarchy (ou=Users.Provisioned\ou=Accounts\User1) other than the default hierarchy (cn=Users,dc=domain,dc=com.) on Active Directory server by the provisioning of "AD User" resource object.

To create users in desired hierarchy (ou=Users.Provisioned\Accounts\User1) on active directory server, Need to be create same organization hierarchy in OIM side also,while provisioning "AD User" Resource object need to be select that organization ou=Accounts under which hierarchy  user will create on AD side.

Please follow the below steps.



1)Create Organization Unit ou=Users.Provisioned on AD side under dc=domain,dc=com.



2)Create one more ou=Accounts under ou=Users.Provisioned(this is parent organization for

ou=Accounts).



3)Login in OIM webclient click on Organization>>Create menu .



4)Create Organization say Name=Users.Provisioned.



5)Again create an organization say Name=Accounts and select Parent Name= "Users.Provisioned".



6)Create new user say "User1" and provision with "AD User" resource object.



7)while provisioning AD User Resource Object, AD User process form will show up.



8)Click on Organization Name lookup>> select desire OU=Accounts.



9)Complete provisioning process.



Result :

Check AD side under ou=Users.Provisioned\ou=Accounts\user=User1 will stored.


 

Note : In AD server IT Resorce Information >>Root Context=(dc=domain,dc=com) should be contain only domain name .

Should the OIM AD Password Sync Connector be Installed on all the Active Directory Domain Controller Machines to Which a User can Bind to

Should the OIM AD Password Sync Connector be installed on all the Active Directory Domain Controllers to which users can connect to change their passwords or should it be installed only on the Primary Domain Controller?

If the user's password is changed on an Active Directory Domain Controller, that Domain Controller should have the OIM AD Password Sync connector package installed in order for it to propagate the new password to OIM.


If only the Primary Active Directory Domain controller has the OIM AD Password Sync connector installed and if the password is changed on the non primary domain controller (which does not have the AD Password Sync connector installed and configured) and then primary domain controller having AD Password Sync connector would never execute the change password to OIM even after it the two domain controllers sync. One would never know on which Domain Controller a user is authenticated and where their password was changed, that's why AD Password Sync connector should on any Domain Controller that a user could bind to.

How to Add a New Field to AN OIM Connector (Step by Step Guide on OID Connector)

This document describes the steps needed to add a custom field to a OIM Connector. The steps provided are targeted to the OID connector. However, same concepts can be used to other connectors as well.

There are two sections, first describes the operations needed for provisioning. The second section describes how to add the field for synchronization.

Solution

Section 1: Provisioning

=================

Step1: Adding the new field to the OID Process Form
--------------------------------------------------------
1. In Design Console open Development Tools -> Form Designer
2. In Table Name field type UD_OID_USR and press Search
3. Click "Create new version" and enter the label and click Save
4. Select the new form version
5. Click Add and enter the details for the new field in the table.
In this example we will use:
NAME: UD_OID_USR_SOID
VARIANT TYPE: String
LENGTH: 100
FIELD LABEL: Sample OID Field
FIELD TYPE: TextField
ORDER: 16
6. Save the form
7. On the Properties tab, click Add, select the field and set Visible Field to true.
8. Save the form
9. Click "Make version active"

Step2: Create a process task for the Sample OID Field
--------------------------------------------------------
1. In Design Console open Process Management -> Process Definition
2. In the Name field type "OID User" and click search
3. Click Add
4. Enter the name as "Sample OID Field Updated"
The name of the connector must follow the following naming convention:
"<Field Name> Updated"
OIM calls the connector based on this naming rule.
5. Enter a description and also check "Conditional" and "Allow Multiple Instances"
6. Save the process task
7. On the Integration tab, click Add -> Adapter and select adpOIDMODIFYUSER adapter.
8. Click Save.
9. Map the adapter variables to the following values:


Adapter return value <-> Response Code
SSLFlag <-> IT Resources - Server Address - LDAP Server - SSL
ServerAddress <-> IT Resources - Server Address - LDAP Server - Server Address
ServerPort <-> IT Resources - Server Address - LDAP Server - Port
RootContext <-> IT Resources - Server Address - LDAP Server - Root DN
AdminID <-> IT Resources - Server Address - LDAP Server - Admin Id
AdminPwd <-> IT Resources - Server Address - LDAP Server - Admin Password
AttrLookupCode <-> IT Resources - Server Address - LDAP Server - Prov Attribute Lookup Code
OrganizationDN <-> Literal - String - Empty value
XLOrgFlag <-> IT Resources - Server Address - LDAP Server - Use XL Org Structure
PDataOrg <-> Process Data - Organization DN
UserID <-> Process Data - User ID
AttrName <-> Literal - String - Sample OID Field
AttrValue <-> Process Data - Sample OID Field
ProcessInstKey <-> Process Data - Process Instance

Step3: Adding the field to the provisioning lookup definition
-------------------------------------------------------------
1. In Design Console open Administration -> Lookup definition
2. In Code field type "AttrName.Prov.Map.OID" and click search
3. Click Add and enter "Sample OID Field" in the Code Key.
4. In Decode type the name of the field in OID, for example "description"
5. Click Save


Step4: Testing provisioning
---------------------------
1. Login to the Web Administration Console
2. Create a new OIM User
3. Provision an OID Account to the OIM user
4. Notice in the process form the new field "Sample OID Field"
5. Edit the process form, add a value for Sample OID Field and click Save
6. Check the description field on the account created in OID

Step5: Linking the field to an OIM User UDF (optional)
---------------------------------------------------------
If the scenario requires to link the field with a User Defined Field in the OIM user form:

Let's consider there a field defined in Users form like in the example below:
(In Design Console -> Administration -> User Defined Field Definition -> Users)
Label : Sample OID Field
DataType : String
Field Type : Text Field
Column Name : USR_UDF_S_OID
Field Sise : 100


1. In Design Console open Process Management -> Process Definition
2. In the Name field type "OID User" and click search
3. Click Add
4. Enter the name as "Change Sample OID Field"
5. Enter a description and also check "Conditional" and "Allow Multiple Instances"
6. Save the process task
7. On the Integration tab, click Add -> Adapter and select adpOIDMODIFYUSER adapter.
8. Click Save.
9. Map the adapter variables to the following values:

Adapter return value <-> Response Code
SSLFlag <-> IT Resources - Server Address - LDAP Server - SSL
ServerAddress <-> IT Resources - Server Address - LDAP Server - Server Address
ServerPort <-> IT Resources - Server Address - LDAP Server - Port
RootContext <-> IT Resources - Server Address - LDAP Server - Root DN
AdminID <-> IT Resources - Server Address - LDAP Server - Admin Id
AdminPwd <-> IT Resources - Server Address - LDAP Server - Admin Password
AttrLookupCode <-> IT Resources - Server Address - LDAP Server - Prov Attribute Lookup Code
OrganizationDN <-> Literal - String - Empty value
XLOrgFlag <-> IT Resources - Server Address - LDAP Server - Use XL Org Structure
PDataOrg <-> Process Data - Organization DN
UserID <-> Process Data - User ID
AttrName <-> Literal - String - Sample OID Field
AttrValue <-> Process Data - Sample OID Field
ProcessInstKey <-> Process Data - Process Instance

10. Navigate to Administration - Lookup Definition
11. Enter "Lookup.USR_PROCESS_TRIGGERS" in the Code field and click Search
12. Click Add and enter the follwing values:
Code Key - USR_UDF_S_OID
Decode - Change Sample OID Field
Note: Code Key is the database column name for the UDF (as assumed in the begining of Step5).
Note: Decode is the process task name (as assumed in Step5->point4).
13. Save the Lookup definition.

Section 2: Reconciliation

==================

Step1: Add the Reconciliation Field to OID User Resource Object
--------------------------------------------------------------------
1. In Design Console open Resource Management -> Resource Object
2. Type "OID User" in Name and click Search
3. On Object Reconciliation tab, click Add Field
4. Enter "Sample OID Field" in the field name and select the type as String
5. Click Save

Step2: Add the Reconciliation Field Mappings
-----------------------------------------------
1. In Design Console open Process Management -> Process Definition
2. Type "OID User" in the name field and click Search
3. On the Reconciliation Field Mappings tab, click Add Field Map
4. Select:
Field Name : Sample OID Field
Field Type : String
Process Data Field : UD_OID_USR_SOID
5. Click Save

Step3: Add the field to the reconciliation lookup definition
----------------------------------------------------------
1. In Design Console open Administration -> Lookup definition
2. In Code field type "AttrName.Recon.Map.OID" and click search
3. Click Add and enter "Sample OID Field" in the Code Key.
4. In Decode type the name of the field in OID, for example "description"
5. Click Save

Step4: Testing reconciliation
-----------------------------
1. Login to OID with Oracle Directory Manager (OIDAdmin)
2. Modify the description field for a specific user account
3. Run the reconciliation task
4. Check the process form for the specific user account in OIM Administration interface
5. The field Sample OID Field should be updated accordingly


Note: when a reconciliation event is received, the Reconciliation Update Received task is called and the process form is updated. If the requirement is to synchronize data further, a custom task can be linked to Reconciliation Update Received. However, the custom task implementation will probably require custom code.