Working with GALSync and cross-forest Lync
Brief Introduction
=================================
We already have plenty of articles describing how to share Free/Busy across forests and how to enable Lync in a multi-forest scenario. But what about an Exchange-Lync combination in this cross forest scenario? I'm writing this blog trying to provide you some hints on it.
Scenario: Customer got two forests, one for global system and one built & maintained by subsidiary.
Diagram: Lab Topology:
Forest-A: got Exchange 2007 and Lync 2010 deployed. (Contoso.com)
Forest-B: only runs Exchange 2007. No Lync schema extension nor any Lync deployments here. (Fabrikam.com)
Goals:
1. Sync GAL between the two Exchange organizations
2. Share Calendar information with each other
3. Enable Lync for Forest-B users, leveraging the Lync servers deployed in Forest-A
Note: FIM is running on another forest independently, to prove it's not relying on any source/destination forest memberships.
Solution Design
=================================
GAL Sync | To make the two GALs include contact info from remote organization, we have to create corresponding objects in local AD to reflect the remote mail recipients/groups. Microsoft provided solutions on this. IIFP/MIIS/ILM/FIM (they are actually pretty similar products) got builtin component called "GALSync", which pumps objects from source Active Directory into SQL database, and later on we can leverage the metadata to create objects in another Active Directory. Find detailed description here: How to Transition from Cross-Forest to Cross-Forest In this lab, we are going to install FIM 2010 and configure GALSync to do the bi-directional "user <--> contact" sync. |
Calendar Sharing | Assume all clients are based on Outlook 2007 and later, they retrieve Free/Busy information from Exchange 2007 CAS, this is a functionality provided by the Availability Service:- If the requested mailbox is located in local Mailbox server, the local CAS talks to it;- If the requested mailbox is located in remote site, the local CAS proxies the request to remote CAS to retrieve Free/Busy information. The credential being used when CAS in two separate organizations talks to each other: 1. If two-way AD trust exists, we can modify the ACL on CAS to allow access with computer account;2. If no AD trust exists, we can configure CAS to use specified credential to connect to remote CAS. And how can a local CAS locate the remote CAS? It's relying on Autodiscover mechanism. We have two options to achieve this: 1. If AD trust in place, we can export SCP from target AD & import to source AD2. An alternative way is to specify a credential by Get-Credential then leverage it when executing Add-AvailabilityAddressSpace cmdlet. This doesn't requires any trust relationship. When CAS talk to each other, after authentication they also need to validate each other's certificate as the communication is based on HTTPS protocol. We have two options to achieve the mutual certificate validation: 1. If Exchange CAS servers are using the default self-signed certificate, we can modify the registry to make them allow those untrusted certs2. If Exchange CAS servers are using certificate issued by CA, we may install the Root CA certificate into the local "Trusted Certificate Authorities" container, to make those certs issued by the CA trusted Find more details here: How to Configure the Availability Service for Cross-Forest Topologies In this lab, we are going to create AD trust, use autodiscover to locate remote CAS, and allow untrusted certs by modifying registry. |
Cross Forest Lync | There're two scenarios for deploying Lync in multiple forests: 1. Central forest: one large forest hosting users & servers, providing Lync service to spoke forests. We may sync users from spoke forest to contact objects into central forest. Detailed description: Part 1: Deploying Lync Server 2010 in a Central Forest Topology2. Resource forest: a dedicated forest used for deploying servers, we may sync users from user forest to user objects into resource forest. Details: Part 2: Deploying Lync Server 2010 in a Resource Forest Topology In this lab, we are going to use central forest topology, leveraging the contact objects created by GALSync from FIM. This will need some customization on the MA |
Configuration Steps
=================================
The basic idea is:
Source | Metaverse | Destination | Direction |
thumbnailPhoto attribute on user object | photo attribute on person object | thumbnailPhoto attribute on contact object | Domain-A <--> Domain-B |
DN attribute on user object from Domain-B | Ms-DS-Source-Object-DN attribute on person object | msDS-SourceObjectDN on contact object in Domain-A | Domain-B -> Domain-A |
objectSID on user object from Domain-B | objectSid attribute on person object | msRTCSIP-OriginatorSID on contact object in Domain-A | Domain-B -> Domain-A |
1. Prepare FIM 2010
Login to USFIM01, install SQL Server and FIM 2010 Synchronization Service.
Download Lync Server Resource Kit: https://www.microsoft.com/en-us/download/details.aspx?id=21165. Install & copy the entire C:\Program Files\Microsoft Lync Server 2010\ResKit\LcsSync folder to FIM Server (C:\Program Files\Microsoft Forefront Identity Manager\2010\Synchronization Service\Extensions)
Edit the lcsmvschema.xml file. Two incorrect attributes defined (otherHomePhone and otherTelephone), we got to correct them. By default the thumbnailPhoto attribute is not being included in the FIM metaverse for "person" object, if you want to sync photos, add it into the schema as well.
Original | Update to |
In <dsml:directory-schema> section: <dsml:attributeatype id="otherHomePhone"> <dsml:name>otherHomePhone</dsml:name> <dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax> </dsml:attribute-type> |
<dsml:attribute-type id="otherHomePhone" single-value="false" ms-dsml:indexable="true" ms-dsml:indexed="true"> <dsml:name>otherHomePhone</dsml:name> <dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax> </dsml:attribute-type> |
In <dsml:directory-schema> section: <dsml:attribute-type id="otherTelephone"> <dsml:name>otherTelephone</dsml:name> <dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax> </dsml:attribute-type> |
<dsml:attribute-type id="otherTelephone" single-value="false" ms-dsml:indexable="true" ms-dsml:indexed="true"> <dsml:name>otherTelephone</dsml:name> <dsml:syntax>1.3.6.1.4.1.1466.115.121.1.15</dsml:syntax> </dsml:attribute-type> |
In <dsml:directory-schema> section, add | <dsml:attribute-type id="photo" single-value="true"> <dsml:name>photo</dsml:name> <dsml:syntax>1.3.6.1.4.1.1466.115.121.1.5</dsml:syntax> </dsml:attribute-type> |
In <dsml:class id="person" type="structural"> section, add | <dsml:attribute ref="#photo" required="false" /> |
Open Synchronization Service, navigate to Metaverse designer, Action, Import Metaverse Schema, import the updated lcsmvschema.xml.
2. Create MA for Domain-A
Open Synchronization Service, navigate to Management Agents
Properties page: Create, Choose "Active Directory global address list (GAL)", give MA a name, Next
Connect to Active Directory Forest page: Specify forest name, credential, Next
Configure Directory Partitions page: Select the partition, click on "Containers", Next
Configure GAL page: Assign source and destination OU/Container, specify SMTP suffix (must start with @), check the "Support cross-forest delegation (Exchange 2007 or 2010 only)", Next
Configure Provisioning Hierarchy page: Next
Select Object Types page: Next
Select Attributes page: Check "Show All", make sure "msRTCSIP-OriginatorSid", "msDS-SourceObjectDN" and "thumbnailPhoto" checked, Next
Configure Connector Filter page: Next
Configure Join and Projection Rules page: Next
Configure Attributes Flow page: Under "User -> Person" flow, add an import "thumbnailPhoto -> photo", this will read Domain-A user photo into FIM Metaverse. Under "Contact <- Person" flow, add three exports: "thumbnailPhoto <- photo, allow null", "msRTCSIP-OringinatorSid <- objectSid", "msDS-SourceObjectDN <- Ms-DS-Source-Object-DN, allow null", this will read photo, objectSID and DN from Metaverse and write to Domain-A.
Configure Deprovisioning page: Next
Configure Extensions page: Select "Exchange 2007" in the drop-down menu, Finish.
3. Create MA for Domain-B
Open Synchronization Service, navigate to Management Agents
Properties page: Create, Choose "Active Directory global address list (GAL)", give MA a name, Next
Connect to Active Directory Forest page: Specify forest name, credential, Next
Configure Directory Partitions page: Select the partition, click on "Containers", Next
Configure GAL page: Assign source and destination OU/Container, specify SMTP suffix (must start with @), check the "Support cross-forest delegation (Exchange 2007 or 2010 only)", Next
Configure Provisioning Hierarchy page: Next
Select Object Types page: Next
Select Attributes page: Check "Show All", make sure "msRTCSIP-OriginatorSid", "msDS-SourceObjectDN" and "thumbnailPhoto" checked, Next
Configure Connector Filter page: Next
Configure Join and Projection Rules page: Next
Configure Attributes Flow page: Under "User -> Person" flow, add two imports "thumbnailPhoto -> photo" and "<dn> -> Ms-DS-Source-Object-DN", this will read Domain-B user photo and DN into FIM Metaverse for "Person" objects. Under "Contact <- Person" flow, add an export: "thumbnailPhoto <- photo, allow null", this will read photo from Metaverse and write to Domain-B.
Configure Deprovisioning page: Next
Configure Extensions page: Select "Exchange 2007" in the drop-down menu, Finish.
4. Import, Sync and Export
- Import both of the MA, now we have Metaverse in FIM database
- Sync
- Export MA for Domain-A, we should be able to see contact objects being created, with msDS-SourceObjectDN(A) from DN(B), msRTCSIP-OriginatorSID(A) from objectSID(B), thumbnailPhoto(A) from thumbnailPhoto(B)
- Export MA for Domain-B, we should be able to see contact objects being created, with thumbnailPhoto(B) from thumbnailPhoto(A)
5. Enable Lync for syched contacts in Domain-A
Unfortunately, contact object can't be managed by Lync Control Panel. We must use Enale-CsUser cmdlet to enable Lync for Domain-B users.
Example:
Get-CsAdContact '4 li' | Enable-CsUser -SipAddress sip:li4@domainb.com -RegistrarPool cnly01.domaina.com
6. Configure Exchange Calendar Sharing
On CAS server in both domain, modify the registry to allow untrusted certificate:
HKLM\System\CurrentControlSet\Services\MSExchangeOWA\AllowInternalUntrustedCerts = 1
HKLM\System\CurrentControlSet\Services\MSExchangeOWA\AllowExternalUntrustedCerts = 1
On CAS server in Domain-A, add address space for Domain-B:
Add-AvailabilityAddressSpace -ForestName "fabrikam.com" -AccessMethod PerUserFB -UseServiceAccount $true
Get-ClientAccessServer | Add-AdPermission -AccessRights ExtendedRight -ExtendedRights "ms-exch-epi-token-serialization" -User "FABRIKAM\Exchange Servers"
On CAS server in Domain-B, add address space for Domain-A:
Add-AvailabilityAddressSpace -ForestName "contoso.com" -AccessMethod PerUserFB -UseServiceAccount $true
Get-ClientAccessServer | Add-AdPermission -AccessRights ExtendedRight -ExtendedRights "ms-exch-epi-token-serialization" -User "CONTOSO\Exchange Servers"
All done. Hopefully this post helps you to understand and configure multi-forest scenario with Exchange & Lync Servers.