GALSync: How to Extend GALSync to Provision Target Objects in Sub OUs Using a Configuration File

Introduction

The GALSync setup is fully documented in the MIIS 2003 Walkthrough Scenarios.

The walkthrough contains documents on GALSync:

  • MIIS 2003: Global Address List (GAL) Synchronization (MIIS_2003_GAL_Synchronization.doc)
  • MIIS 2003 Walkthrough: Global Address List Synchronization (MIIS_2003_GAL_synchronization_Step_by_step.doc)

Both are used as base to implement the GAL Sync.

 

Default Configuration

For this Wiki document, the MIIS agent configuration is kept as default as possible.

Full detail on default configuration can be found in MIIS_2003_GAL_Synchronization.doc.

Only the differences (changes made to the default setup) will be recorded in the procedure below.

The default GALSync configuration allows to provision target objects into one single container/OU.

 

Hub-and-spoke

In lots of cases customers wish to synchronize the existing address books within the different domains, targeting one central "Global Address Book", presenting the different domains as subdivisions.

Customers want to have an overview via Outlook of all existing mail addresses, grouped by domain or entity.

And frequently they need to use a structured target container, provisioning target objects in sub OUs of the main target container.

The functionality to use sub OU's in the target container must be added as customization into the IIFP/ILM server configuration.

Sample domain and OU structure

domain1.local (DOMAIN1)

├ ...

├┬ GAL Contacts (OU)

│├ Domain2 (OU)

│└ Domain3 (OU)

├ ...

 

domain2.local (DOMAIN2)

├ ...

├┬ GAL Contacts (OU)

│├ Domain1 (OU)

│└ Domain3 (OU)

├ ...

domain3.local (DOMAIN3)

├ ...

├┬ GAL Contacts (OU)

│├ Domain1 (OU)

│└ Domain2 (OU)

├ ...

 

GALSync Attributes

In the first stage of setup, the list of attributes that are configured by default (by default GALSync setup/wizard), will be maintained.

This will allow for a better review of the initial setup.

It's much easier to remove the unwanted data flow configuration instead of rebuilding (default) data flows from scratch.

 

Security

Reference: MIIS/ILM Management Agent Communication Ports, Rights, and Permissions

Keep in mind you need a management agent connection account with the proper rights and permissions to read and write data in the targets.

(import, update, provisioning, ...)

To allow the AD MA connection account to create, delete and update objects in the GAL contacts OU, the necessary permissions must be added to the GAL Contacts OU and its subfolders (using heritance).

By preference the administrator must create the container structure before you start provisioning.

You could allow MIIS/ILM/FIMSync to create the subOUs during provisioning, but that is not part of the scope of this document.

 

Attribute flows

To detect the source of an object (linked to the target subcontainer) an attribute is added to the MV object definition (all objects): targetSubOU.

Details will be documented further in this document.

 

Metaverse configuration

Automated object creation by GALSync

When using the GALSync MA's, MIIS automatically adds the necessary attribute flows to the new and to the existing management agents.

Also the MV is extended with new object types (like contact_XXX, where XXX is the name of the management agent, spaces replaces by underscore).

 

Add the targetSubOU attribute to the MV Objects

If you add another GALSync MA, you need to check that all active objects in the MV (MV objects in use by the GALSync) have the targetSubOU string attribute added.

This attribute is used to define the original source of an object, which also defines in which OU the related contact object must be created.

Check these MV object definitions:

  • person
  • group
  • contact_gal_*
    • contact_gal_domain
    •  contact_gal_domain2
    • contact_gal_domain3
    • .

Attribute flow precedence

Attribute flow precedence is handled automatically by the MIIS configuration wizard.

 

Management Agent Configuration

Auto generation of attribute flows

When using the GALSync MA's, MIIS automatically adds the necessary attribute flows to the new and to the existing management agents.

Also the MV is extended with new object types (like contact_XXX, where XXX is the name of the management agent, spaces replaces by underscore).

 

Add the targetSubOU attribute to the new GAL object

When you add a new management agent, the wizard automatically creates a new object type in the MV.

This object must include the new targetSubOU attribute. This attribute already exists in the attribute list but the attribute must be linked to the freshly created object.

 

Add targetSubOU attribute in attribute IMPORT flows

 When implementing GAL Sync, the MA wizard automatically creates the needed attribute flows for the objects in the GAL Sync solution.

To determine the target in which a contact must be created, you need to add an additional attribute flow in the GAL Sync MA configuration.

Only for the (auto-created) attribute flows that mainly exist of import flows, you must add the "targetSubOU".

The attribute flows that exist of export attribute flows must not contain the targetSubOU attribute.

Attribute flows that mainly exist of export attribute flows must not have this import flow added.

Below you'll find some examples of flows that must be added:   

Data Source Attribute Metaverse Attribute Type Flow Nulls
Object Type: Contact Object Type:contact_gal_<own MA>*
<dn> -> targetSubOU Rules Extension - targetSubOU
Object Type: user Object Type:person
<dn> -> targetSubOU Rules Extension - targetSubOU
Object Type: group Object Type:group
<dn> -> targetSubOU Rules Extension - targetSubOU

Add EXPORT attribute flow to adres list filter attribute

To allow Exchange admins creating an address list in AD, a certain attribute must be filled with the msExchOriginatingForest attribute.

In this procedure I chose "extensionAttribute15" for ease of use.

Export Attribute Flow
Data Source Attribute To Metaverse Attribute Mapping Type Allow Nulls
contact - contact_gal_domain1 - -
extensionAttribute15 <-- msExchOriginatingForest Direct Allow
contact - person - -
extensionAttribute15 <-- msExchOriginatingForest Direct Allow
contact - group - -
extensionAttribute15 <-- msExchOriginatingForest Direct Allow

targetSubOU attribute flow definition

GALMA.vb must be extended with an additional flowrule in MapAttributesForImport.

 

Source code - enable provisioning in sub containers

As mentioned before ((Ref. MIIS_2003_GAL_Synchronization.doc)

"When synchronizing with a connected data source that uses a hierarchical structure such as Active Directory, Microsoft Identity Integration Server 2003 does not export container operations. That is, when provisioning a child object, Microsoft Identity Integration Server 2003 does not create the parent automatically. The management of containers with hierarchies must be done completely in the connected data source."

The functionality to use sub OU's in the target container will be added as customization into the MIIS server configuration.

The GALSync code extensions are gathered into 1 project solution.The source code of the GALSync setup is installed by default in the MIIS program files directory (%program files%\Microsoft Identity Integration Server\SourceCode\GalSync).

The solution exists of 3 base code files:

  • GALMA.vb : the GAL management agent extensions
  • GALMV.vb : the GAL metaverse extensions
  • GALUtil.vb: code library for functions used in GALMA.vb and GALMV.vb

In addition, the solution uses a XML file (GALSync.XML) to read MA l configuration options.

 

Galsync.xml

IMPORTANT:

The galsync.xml file in the Extensions folder is automatically updated/managed by the system, when the MA's in MIIS are added, updated or changed.

GALSync.xml is very volatile. It's not really suitable for containing custom information (like the sub OU configuration.)

For that reason, another similar xml file is created to contain custom information: GALSync_subOUs.xml. 

 

GALSync_subOUs.xml

For each management agent, a section (<target-subou>) has to be added to the MA configuration, to support the provisioning in subcontainers.

This information is quite stable and is administrator-managed.

At the moment of configuration this information must be updated to the real life configuration data (AD Container info).

<rules-extension-properties>
 
 <galsync-mas>
 
  <galma name="GAL Domain1">
 
   <contact-type>contact_gal_Domain1</contact-type>
 
   <target-ou>OU= GALContacts,DC=domain1,DC=local</target-ou>
 
   <target-subou>OU=Domain1/target-subou>
 
  </galma>
 
  <galma name="GAL Domain2">
 
   <contact-type>contact_gal_Domain2</contact-type>
 
   <target-ou>OU=Contacts,DC=domain2,DC=local</target-ou>
 
   <target-subou>OU=Domain2</target-subou>
 
  </galma>
 
  <galma name="GAL Domain3">
 
   <contact-type>contact_gal_Domain3</contact-type>
 
   <target-ou>OU=Contacts,DC=domain3,DC=local</target-ou>
 
   <target-subou>OU=Domain3</target-subou>
 
  </galma>
 
 </galsync-mas>
 
</rules-extension-properties> 

Attribute flows

Per management agent, per managed object, all object flows that use (almost) only import attribute flows must be extended, to support the target-subou attribute import flow.

Object attribute flows that are (mainly) export must not be extended for the moment.

Management agent extension (GALMA.vb)

Advanced Import flow for targetSubOU

To support the advanced import attribute flow, the GALMA code must be extended.

The following code (between the '#Customized Code markers) has been added in the "Public Sub MapAttributesForImport" section:

Select Case  FlowRuleName
 
'# Customized Code to add
 
Case "targetSubOU"
 
Dim tempMAConfig As new GALMA
 
tempMAConfig = FindMA(csentry)
 
mventry(FlowRuleName).Value = tempMAConfig.targetSubOU
 
'# Customized Code to add
 
Case "TargetAddressMapping"

Metaverse extension (GALMV.vb)

To support subcontainers , change the provisioning code:

'# Customized Code to add
 
Dim strTargetDN As String  = _
 
mventry("targetSubOU").StringValue & "," & MAConfig.SynchronizationOU
 
'# Customized Code to add
 
'# Customized Code to change
 
Dim dn As ReferenceValue = _
 
'MA.EscapeDNComponent(rdn).Concat(MAConfig.SynchronizationOU)
 
MA.EscapeDNComponent(rdn).Concat(strTargetDN)
 
'# Customized Code to change

Note

The GALSync solution does not create the parent automatically.

The hierarchical structure is not dynamic, each MA has it's fixed position in the target GAL contacts OU.

So the function to create the parent is not added to the procedure. 

 

GAL Utils extension (GALUtil.vb)

GAL MA Class

In the GALUtil.vb code, the following sections must be updated:

Public Class  GALMA
 
'# Customized Code to add - begin 1
 
Public targetSubOU As String
 
'# Customized Code to add - end 1
 
End Class
XML Configuration tags

Add the customized code like:

Const GAL_SYNC_MA_XF_DELEGATION As String  = _
 
"cross-forest-delegation"
 
'# Customized Code to add - begin 2
 
Const GAL_SYNC_MA_TARGET_SUBOU As String  = _
 
"target-subOU"
 
'# Customized Code to add - end 2

FindMA Function

To call the FindMA function outside the code section, "private" cannot be used.

'# Customized Code to change - begin 3
 
'Private Function FindMA( _
 
Protected Function  FindMA( _
 
ByVal csentry As CSEntry) _
 
As GALMA
 
'# Customized Code to change - end 3

GetSubOUNames (Custom function, added to out-of-the box code)

'# Customized code to add - begin 4
 
Public Sub  GetSubOUNames(ByRef  refHT As  Hashtable)
 
Dim xMLDoc As XmlDocument = New XmlDocument
 
xMLDoc.Load(Utils.ExtensionsDirectory ├ "\GALSync_subOUs.xml")
 
Dim xmlnodeMA As XmlNode
 
Dim iCount As Integer
 
Dim xMLMaAttribute As XmlAttribute
 
Dim strMAName As String
 
Dim xMLnode As XmlNode
 
Dim xMLNodeMAs As XmlNode =xMLDoc.SelectSingleNode( "/" & MMS_RULES_EXTENSION & "/" ├ GAL_SYNC_MAS)
 
Dim xMLnodeMAList As XmlNodeList = xMLNodeMAs.SelectNodes(GAL_SYNC_MA)
 
 
For iCount = 0 To xMLnodeMAList.Count - 1
 
 xmlnodeMA = xMLnodeMAList.Item(iCount)
 
 ' Find MA Name
 
 For Each  xMLMaAttribute In  xmlnodeMA.Attributes
 
  If "name" = xMLMaAttribute.Name() Then
 
   strMAName = xMLMaAttribute.InnerText().Trim()
 
   Exit For
 
  End If
 
 Next
 
 If IsNothing(strMAName) Then
 
  Throw New  UnexpectedDataException( _
 
  "No MA name Attribute in subOU configuration XML")
 
 End If
 
 ' Read target Sub OU info
 
 XmlNode = xmlnodeMA.SelectSingleNode(GAL_SYNC_MA_TARGET_SUBOU)
 
 If Not  IsNothing(XmlNode) Then
 
  'add MA Name and MA subOU name to hashtable
 
  'refHT.add(MAName, SubOUName)
 
  refHT.Add(strMAName, xMLnode.InnerText().Trim())
 
 End If
 
Next iCount
 
End Sub
 
'# Customized code to add - end 4
GetConFigurationData

/../
 
doc.Load(Utils.ExtensionsDirectory ├ "\GALSync.xml")
 
'# Customized code to add - begin 5
 
'' GALSync.xml is updated/modified by ILM/MIIS when saving a GAL MA configuration
 
'' thus GALSync.XML is not usable to store custom data, like subOU info
 
'' the subOU info is stored in a separate XML file "GALSync_subous.xml", similar to GALSync.XML
 
'' GALSync_subous.xml info is loaded in to hash table
 
Dim hTsubOU As New  Hashtable
 
GetSubOUNames(hTsubOU)
 
'# Customized code to add ) end 5
 
nodeMAs = doc.SelectSingleNode("/" & MMS_RULES_EXTENSION & "/" ├ GAL_SYNC_MAS)
 
/../
 
/../
 
MAConfig.MailRouting = False
 
'# Customized code to add - begin 6
 
MAConfig.targetSubOU = Nothing
 
'# Customized code to add - end 6
 
' Find MA Name
 
For Each  maAttribute In  nodeMA.Attributes
 
 If "name" = maAttribute.Name() Then
 
  MAConfig.MAName = maAttribute.InnerText().Trim()
 
  Exit For
 
 End If
 
Next
 
If IsNothing(MAConfig.MAName) Then
 
Throw New  UnexpectedDataException( _
 
"No MA name Attribute in configuration XML")
 
End If
 
'# Customized code to add - begin 7
 
'' Read target Sub OU info from hash table
 
'' that was initialized before
 
''if HT does not contain the MAName, throw error
 
If Not  hTsubOU.Contains(MAConfig.MAName) Then
 
 Throw New  UnexpectedDataException( _
 
 "No MA name Attribute in hash table configuration")
 
End If
 
MAConfig.targetSubOU = hTsubOU.Item(MAConfig.MAName).ToString
 
'# Customized code to add - end 7
 
' Read contact type
 
/../

Exchange Server Configuration

With Exchange 2003/2007, it is not possible to create an global address list based on objects in an OU.

To create a global address list with a custom query, you must use an existing attribute of an user, contact, distribution group.

This procedure uses the extensionAttribute15 to store a value.

The msExchOriginatingForest attribute, which is maintained by the GAL Sync, is propagated to the extensionAttribute15 attribute.

This allows for creating an address list based on a contact attribute.

Every target forest has a corresponding OU container in the GAL contacts structure.

For every existing (or new) target forest, create an address list.

ExtensionAttribute15 contains the FQDN of the source forest.

Example: domain1.local for GAL Domain1, domain2.local for GAL Domain2

 

 

Note

This article is not discussing provisioning to Exchange 2007 / Exchange 2010.

When using GALSync with these systems, make sure you install the proper tooling. (Powershell, Exchange Management Console, ..)

See Also

 

References