This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm

Background information
Many Line of Business applications (LOB) utilize Oracle user accounts as a means of authentication. This blog explores the possibility of utilizing MIIS for the purposes of synchronizing passwords between Active Directory and Oracle databases. More specifically as users change their passwords in Active Directory this password change should propagate to Oracle database and thus keeping those two passwords in sync.

Prerequisites
The most important prerequisite for this solution is the establishment of a link between Metaverse Person object and Oracle User record. As part of implementing this solution we will need to create a new Management Agent that will connect to Oracle and import all Oracle User objects into MIIS. It may also be possible to utilize existing connection to the Oracle database if MIIS already synchronizes data with the LOB that utilizes Oracle, as long as we can add ORACLE USERNAME attribute to the view. This document assumes that a new connection will be established for the purposes of password synchronization.
One possible solution is to use Oracle DBA_USERS view as a source of import into Metaverse. Since DBA_USERS does not contain employeeID field, which would an ideal anchor, we need to either choose another field to act as an anchor or create another view which will link DBA_USERS with a view or a table that has employeeID field.
Note: we assume that employeeID is an attribute that uniquely identifies an identity within your environment.
For the purposes of this document we will assume that USERNAME field in DBA_USERS view would match samAccountName (your user name in AD) field in Metaverse, and we will conduct the join based on this assumption. We understand that this may not be the case in the production environment and the option of creating a different view (other then DBA_USERS) may need to be explored.

Second prerequisite: setup and configuration of Microsoft Password Change Notification Service on all Domain Controllers. For details on this procedure see MIIS 2003 Password Synchronization Step by Step walkthrough. http://www.microsoft.com/downloads/details.aspx?FamilyId=15032653-D78E-4D9D-9E48-6CF0AE0C369C&displaylang=en


Password Change Flow

Password Sync Flow Diagram

Implementation Steps

We assume here that Oracle Client is already installed and configured to connect to the appropriate database.

1. Download and install Oracle Developer Tools for Visual Studio on MIIS server
http://www.oracle.com/technology/software/tech/dotnet/utilsoft.html

2. Create a new Class Extension Library (VB.NET was used for the purposes of this document)

New DLL Library

3. Add References to Microsoft.MetadirectoryServices and Oracle.DataAccess
The corresponding DLLs are located in
C:\Program Files\Microsoft Identity Integration Server\bin\assemblies
C:\oracle\product\10.1.0\Client_1\bin
Note: This assumes default installation of the products

References

4. Modify the properties of Oracle.DataAccess references to create a local copy during the build process

Copy Local

5. Paste the content of the Appendix 1 into the workspace
6. Point the output of the project build to C:\Program Files\Microsoft Identity Integration Server\Extensions

Build Path

7. Build the project

8. Create a new Management Agent for Oracle Database which contains User accounts for students

See Screen-shots below for details on configuring the connector

Connect to DB

For the purposes of this paper we used Oracle system account to connect to the database. In production environment I would recommend creating a dedicated account that would have only read access to DBA_USERS view, thus following the principle of least privileges.

 

Configure Columns

 

Make sure to specify USER_ID field as an anchor attribute

 

Configure Filters

Do not specify any filters

Join

This paper assumes that samAccountName matches Oracle USERNAME. We also assumed that samAccountName attribute has been added to MIIS schema.

Attribute Flow

This step is optional, but may simplify troubleshooting when you need to determine a link to an Oracle user by looking at the Metaverse Person object.
You will also need to extend Metaverse Schema by adding OracelID attribute.

 

 Deprovisioning

Password Extension DLL


Enable Password management for this connector
Under Extension Name specify the name of the DLL that we built in step 7
Under supported password operations select Set Only
Click on Settings for Connection Information
 

Connection Information

Specify Service name and Account credentials for connecting to Oracle database. Note: the account you specify should have sufficient privileges to reset user passwords. In production environment do not use system account, but rather create a dedicated account with required privileges.
Save the Management Agent. Save the Management Agent.

9. Open Properties of the Active Directory Connector

Switch to the Configure Directory Partitions section and ensure that this partition is enabled as a password synchronization source.

 

AD Password Source

10. Click on Targets

Enable Oracle Management Agent as a target.
Save the changes.

Make Target

11. Create a Full Import and a Full Sync run profile for the new Oracle Management Agent. Run this profile.
12. Validate that Metaverse now has links to Oracle User Accounts by examining Metaverse Objects.
 

Check Link

13. Initiate a password change in Active Directory for a test user
14. Check application event log on domain controllers, you should see a similar event. Finally validate that the Oracle password is now in sync with AD password.

Check Event Log

 

Appendix 1: Sample Password Extension for Oracle

This code has been developed as a proof of concept, and therefore does not implement error checking and logging that would be required for production environment.

Imports Microsoft.MetadirectoryServices
Imports Oracle.DataAccess.Client


Public Class OraclePasswordExtension
    Implements Microsoft.MetadirectoryServices.IMAPasswordManagement

    Private OracleConnection As New OracleConnection

    Public Sub BeginConnectionToServer(ByVal connectTo As String, ByVal user As String, ByVal password As String) Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.BeginConnectionToServer

        Dim ConnectionString As String = "User Id=" & user & ";" & "Password=" & password & ";" & "Data Source=" & connectTo
        OracleConnection.ConnectionString = ConnectionString
        OracleConnection.Open()
       
    End Sub

    Public Sub ChangePassword(ByVal csentry As Microsoft.MetadirectoryServices.CSEntry, ByVal OldPassword As String, ByVal NewPassword As String) Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.ChangePassword

    End Sub

    Public Sub EndConnectionToServer() Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.EndConnectionToServer
        'Close and Dispose OracleConnection
        OracleConnection.Close()
        OracleConnection.Dispose()
    End Sub

    Public Function GetConnectionSecurityLevel() As Microsoft.MetadirectoryServices.ConnectionSecurityLevel Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.GetConnectionSecurityLevel
        Return ConnectionSecurityLevel.NotSecure
    End Function

    Public Sub RequireChangePasswordOnNextLogin(ByVal csentry As Microsoft.MetadirectoryServices.CSEntry, ByVal fRequireChangePasswordOnNextLogin As Boolean) Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.RequireChangePasswordOnNextLogin

    End Sub

    Public Sub SetPassword(ByVal csentry As Microsoft.MetadirectoryServices.CSEntry, ByVal NewPassword As String) Implements Microsoft.MetadirectoryServices.IMAPasswordManagement.SetPassword

        Dim cmd As New OracleCommand
        Dim UserName As String = csentry("USERNAME").Value
        Dim Password As String = NewPassword

        Dim SQLString As String = "alter user " & UserName & " identified by " & Password

        cmd.CommandText = SQLString
        cmd.Connection = OracleConnection
        cmd.ExecuteNonQuery()
        cmd.Dispose()

    End Sub

End Class