Пример внедрения ILM 2007

29 мая 2009 г.
Comments

В предыдущих постах я описывал как связать разные службы каталогов при помощи ILM 2007. Здесь я объединю все заметки этой теме воедино.

Что из себя представляет ILM (Microsoft Identity Lifecycle Manager)?  Состоит он из  основных компонентов:

MIIS components

  • Connected data source (подключаемые источники данных);
  • Management Agents (агенты управления);
  • Сonnector Spaces (пространства подключения);
  • Metaverse (Метабаза).

и основные функции ILM:

  • синхронизация каталогов;
  • управление паролями и их синхронизация;
  • управление группами;
  • инициализация учетных записей;
  • публикация сертификатов.

За более подробной информацией можно обраться к материалам  на TechNet.

 

И так…, у нас есть Avtive Direcory (учетные записи пользователей для доступа к ресурсам  Windows) – Sun One Direcory (доступ к почтовому серверу) – NetWare (доступ к ресурсам NetWare)

image

Не буду останавливаться на конфигурации агентов управления (MA),их можно посмотреть в предыдущих постах по этой теме. Приведу лишь пример исходных кодов DLL, которые мы будем использовать.

Metaverse Rules Extensions MVExtension.dll:

 

Imports Microsoft.MetadirectoryServices
Imports System
Imports System.Text
Imports System.IO
Imports ActiveDs.ADS_USER_FLAG
Public Class MVExtensionObject
    Implements IMVSynchronization
    Public Sub Initialize() Implements IMVSynchronization.Initialize
        ' TODO: Add initialization code here
    End Sub
    Public Sub Terminate() Implements IMVSynchronization.Terminate
        ' TODO: Add termination code here
    End Sub
    Private Sub SetNovellPW(ByRef csentry As CSEntry, ByVal pw As String)
        ' TODO: Setting an Initial Password in eDirectory
        Dim password() As Byte
        password = New System.Text.UTF8Encoding(False, False).GetBytes(pw)
        ReDim Preserve password(UBound(password) + 2)
        csentry("userPassword").Values.Add(password)
    End Sub
    Private Sub SetSunDirPW(ByRef csentry As CSEntry, ByVal pw As String)
        ' TODO: Setting an Initial Password in SUN Directory Servers
        Dim password() As Byte
        password = New System.Text.UTF8Encoding(False, False).GetBytes(pw)
        csentry("userPassword").Values.Add(password)
    End Sub
    Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
        Dim adMA As ConnectedMA
        Dim csentry As CSEntry
        Dim dn As ReferenceValue
        Dim ExceptionMessage As String
        Const eDir_OU = "ou=Account,o=tree"
        Const eDir_MA = "MA_Novell"
        Const AD_MA = "MA_Active_Directory"
        Const ACTIVE_OU_AD = "OU=Branch,OU=Accounts,DC=dn,DC=local"
        Const INACTIVE_OU_AD = "OU=Disabled,OU=Accounts,DC=dn,DC=local"
        Const Sun_MA = "MA_Sun_Dir"
        Const SUN_OU = "ou=People,dc=dn,dc=local"
        Dim Connectors As Integer
        Dim Container As String
        If Not mventry("uid").IsPresent Then
            ExceptionMessage = "The attribute cn was unexpectedly not present on the metaverse object."
            Throw New UnexpectedDataException(ExceptionMessage)
            Exit Sub
        End If
        ' ======================================= '
        '            eDirectory                   '
        ' ======================================= ' 
        adMA = mventry.ConnectedMAs(eDir_MA)
        Container = eDir_OU
        Connectors = adMA.Connectors.Count
        dn = adMA.EscapeDNComponent("cn=" + mventry("uid").Value).Concat(Container)
        'Throw New UnexpectedDataException("cn=" & mventry("cn").Value)
        If 0 = Connectors Then
            If ("cn=" + mventry("cn").Value + "," + ACTIVE_OU_AD).ToLower = mventry("DistinguishedName").Value.ToLower Then
                Select Case mventry.ObjectType.ToLower()
                    'Case "group"
                    '   csentry = adMA.Connectors.StartNewConnector("groupOfNames")
                    '  csentry.DN = dn
                    ' csentry.CommitNewConnector()
                    Case "person"
                        csentry = adMA.Connectors.StartNewConnector("inetOrgPerson")
                        csentry.DN = dn
                        csentry("groupMembership").Values.Add("cn=Everyone,ou=Account,o=tree")
                        csentry("securityEquals").Values.Add("cn=Everyone,ou=Account,o=tree")
                        csentry("messageServer").Values.Add("cn=SR-NetWare,o=tree")
                        SetNovellPW(csentry, "1Qaz2wsx")
                        csentry.CommitNewConnector()
                End Select
            End If
        ElseIf 1 = Connectors Then
            csentry = adMA.Connectors.ByIndex(0)
            If csentry.DN.ToString.ToLower <> dn.ToString.ToLower Then
                'Throw New UnexpectedDataException("cn=" & mventry("cn").Value)
                '                csentry.Deprovision()
                csentry.DN = dn
            End If
        Else
            Throw New UnexpectedDataException("multiple connectors:" + Connectors.ToString)
        End If
        ' ======================================= '
        '           SUN ONE Directory             '  
        ' ======================================= '
        adMA = mventry.ConnectedMAs(Sun_MA)
        Connectors = adMA.Connectors.Count
        If 0 = Connectors Then
            Dim objClass As ValueCollection
            Select Case mventry.ObjectType.ToLower()
                Case "person"
                    'If mventry("mail").IsPresent Then
                    Container = SUN_OU
                    dn = adMA.EscapeDNComponent("uid=" + mventry("uid").Value).Concat(Container)
                    csentry = adMA.Connectors.StartNewConnector("inetOrgPerson")
                    csentry.DN = dn
                    SetSunDirPW(csentry, "1Qaz2wsx")
                    csentry.CommitNewConnector()
                    objClass = Utils.ValueCollection(csentry.ObjectClass.ToStringArray())
                    objClass.Add("mailRecipient")
                    csentry.ObjectClass = objClass
                    'End If
                Case "group"
                    If ("cn=" + mventry("cn").Value + ",OU=Groups,DC=dn,DC=local").ToLower = mventry("DistinguishedName").Value.ToLower Then
                        Container = "ou=Groups," + SUN_OU
                        dn = adMA.EscapeDNComponent("cn=" + mventry("uid").Value.ToLower).Concat(Container)
                        csentry = adMA.Connectors.StartNewConnector("groupOfUniqueNames")
                        csentry.DN = dn
                        csentry.CommitNewConnector()
                        objClass = Utils.ValueCollection(csentry.ObjectClass.ToStringArray())
                        objClass.Add("mailRecipient")
                        csentry.ObjectClass = objClass
                    End If
            End Select
        ElseIf 1 = Connectors Then
            Select Case mventry.ObjectType.ToLower()
                Case "group"
                    Container = "ou=Groups," + SUN_OU
                    dn = adMA.EscapeDNComponent("cn=" + mventry("uid").Value.ToLower).Concat(Container)
                Case "person"
                    Container = SUN_OU
                    dn = adMA.EscapeDNComponent("uid=" + mventry("uid").Value).Concat(Container)
            End Select
            csentry = adMA.Connectors.ByIndex(0)
            If csentry.DN.ToString.ToLower <> dn.ToString.ToLower Then
                'Throw New UnexpectedDataException("cn=" & mventry("cn").Value)
                '                csentry.Deprovision()
                csentry.DN = dn
            End If
        Else
            Throw New UnexpectedDataException("multiple connectors:" + Connectors.ToString)
        End If
        ' ======================================= '
        '           Active Directory              '    
        ' ======================================= '
        adMA = mventry.ConnectedMAs(AD_MA)
        Connectors = adMA.Connectors.Count
        Select Case mventry.ObjectType.ToLower()
            Case "person"
                If mventry("msDS-UserAccountDisabled").IsPresent AndAlso mventry("msDS-UserAccountDisabled").BooleanValue Then
                    Container = INACTIVE_OU_AD
                    dn = adMA.EscapeDNComponent("cn=" + mventry("displayName").Value).Concat(Container)
                    If adMA.Connectors.Count = 1 Then
                        'Check if rename needed
                        csentry = adMA.Connectors.ByIndex(0)
                        If csentry.DN.ToString.ToLower <> dn.ToString.ToLower Then
                            csentry.DN = dn
                        End If
                    End If
                End If
        End Select
    End Sub
    Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
        Throw New EntryPointNotImplementedException()
    End Function
End Class








Metaverse Rules Extensions для MA Active Directory ADExtension.dll:









Imports Microsoft.MetadirectoryServices
Imports System
Imports System.Text
Imports System.IO
Imports ActiveDs.ADS_USER_FLAG
Public Class MAExtensionObject
    Implements IMASynchronization
    Public Sub Initialize() Implements IMASynchronization.Initialize
        ' TODO: Add initialization code here
    End Sub
    Public Sub Terminate() Implements IMASynchronization.Terminate
        ' TODO: Add termination code here
    End Sub
    Public Function ShouldProjectToMV(ByVal csentry As CSEntry, ByRef MVObjectType As String) As Boolean Implements IMASynchronization.ShouldProjectToMV
        ' TODO: Remove this throw statement if you implement this method
        
        Throw New EntryPointNotImplementedException()
    End Function
    Public Function FilterForDisconnection(ByVal csentry As CSEntry) As Boolean Implements IMASynchronization.FilterForDisconnection
        ' TODO: Add connector filter code here
        Throw New EntryPointNotImplementedException()
    End Function
    Public Sub MapAttributesForJoin(ByVal FlowRuleName As String, ByVal csentry As CSEntry, ByRef values As ValueCollection) Implements IMASynchronization.MapAttributesForJoin
        ' TODO: Add join mapping code here
        Throw New EntryPointNotImplementedException()
    End Sub
    Public Function ResolveJoinSearch(ByVal joinCriteriaName As String, ByVal csentry As CSEntry, ByVal rgmventry() As MVEntry, ByRef imventry As Integer, ByRef MVObjectType As String) As Boolean Implements IMASynchronization.ResolveJoinSearch
        ' TODO: Add join resolution code here
        Throw New EntryPointNotImplementedException()
    End Function
    Public Sub MapAttributesForImport(ByVal FlowRuleName As String, ByVal csentry As CSEntry, ByVal mventry As MVEntry) Implements IMASynchronization.MapAttributesForImport
        ' TODO: write your import attribute flow code
        Const ADS_UF_ACCOUNTDISABLE As Integer = &H2    'Disable user account
        Const ADS_UF_NORMAL_ACCOUNT As Integer = &H200  'Typical user account
        Select Case FlowRuleName
            Case "nsAccountLock"
                If (csentry("userAccountControl").IntegerValue And ADS_UF_ACCOUNTDISABLE) = ADS_UF_ACCOUNTDISABLE Then
                    'Account is disabled
                    mventry("nsAccountLock").Value = "true"
                Else
                    'Account is enabled
                    mventry("nsAccountLock").Value = "false"
                End If
            Case "UserAccountControl"
                mventry("msDS-UserAccountDisabled").BooleanValue = (csentry("userAccountControl").IntegerValue And ADS_UF_ACCOUNTDISABLE) = ADS_UF_ACCOUNTDISABLE
            Case "Mail to Other Mailboxes"
                Dim csAttr As String = csentry("mail").Value.Replace("@domain1", "@domain2")
                mventry("otherMailbox").Value = csAttr
        End Select
    End Sub
    Public Sub MapAttributesForExport(ByVal FlowRuleName As String, ByVal mventry As MVEntry, ByVal csentry As CSEntry) Implements IMASynchronization.MapAttributesForExport
        Const ADS_UF_ACCOUNTDISABLE As Integer = &H2
        Const ADS_UF_NORMAL_ACCOUNT As Integer = &H200
        Select Case FlowRuleName
            Case "employeeStatus"
                Dim currentValue As Long
                If csentry("userAccountControl").IsPresent Then
                    currentValue = csentry("userAccountControl").IntegerValue
                Else
                    currentValue = ADS_UF_NORMAL_ACCOUNT
                End If
                Select Case mventry("employeeStatus").Value
                    Case "active"
                        csentry("userAccountControl").IntegerValue = (currentValue Or ADS_UF_NORMAL_ACCOUNT) _
                                                                    And (Not ADS_UF_ACCOUNTDISABLE)
                    Case "inactive"
                        csentry("userAccountControl").IntegerValue = currentValue _
                                                                    Or ADS_UF_ACCOUNTDISABLE
                End Select
        End Select
        ' TODO: Add export attribute flow code here
        'Throw New EntryPointNotImplementedException()
    End Sub
    Public Function Deprovision(ByVal csentry As CSEntry) As DeprovisionAction Implements IMASynchronization.Deprovision
        
        Throw New EntryPointNotImplementedException()
    End Function
End Class








Теперь у нас синхронизируются 3-ри службы каталогов…