Cross Forest Availability: What’s Trust(s) Got To Do With It?

Recently I was dispatched on an engagement to a customer running Exchange Server 2010 where they were having a hard time implementing Cross-Forest Availability (refered to as CFA in this article) between themselves and another organization they had acquired. The customer had already gone through the process of replicating contacts between the orgs using Identity Management software, so we were just left with figuring out the Exchange portion.

Looking back to our “Configure the Availability Service for Cross-Forest Topologies”, the setup of Cross Forest Availability only has a few moving parts.

The first is to make sure that AutoDiscover is working properly as AutoDiscover is used to lookup where to send the availability requests for the user during a free/busy lookup.

Next in the list is to decide how you want to share free busy and whether or not you want to setup a Trust between forests. You can setup Cross Forest Availability in an untrusted environment, but this customer had chosen to set up a Trust between the two forests.

The customer I was visiting had setup two trusts between the Forests. The first was a two-way, Transitive Forest Trust and the other was a two-way External Trust.

The next item would be to add an AD Permission to each CAS to setup token serialization that will be used so that the CAS can pass credentials back and forth during lookups – that’s done with this command:

Get-ClientAccessServer | Add-ADPermission -Accessrights Extendedright -Extendedrights "ms-Exch-EPI-Token-Serialization" -User "<Remote Forest Domain>\Client Access servers" A note here is that there is not a “Client Access Servers” group by default. You can either create a group and add the Client Access Servers into a new Security Group and use that, or you can use the “Exchange Servers” group as is. You do not need, and should not, remove any of the other servers out of the “Exchange Servers” group to make this functional.

Our final task is to create an availability address space. This is a simple Exchange Management Shell one-liner to tell the client access servers to go get availability for anyone with that specific email address via https at the location specified in the command. To create the Availability Address Space, use the command below.

Add-AvailabilityAddressSpace -Forestname <Target_Forest> -AccessMethod PerUserFB -UseServiceAccount:$true

The customer I was at had already had all of this in place. They had created their Trusts, they had granted the AD Permission, and they had created the Availability Address Space as well as creating contact entries in their forest for the users in the target forest. No dice on the availability.

Troubleshooting steps included verifying all of the items in place, and we found there were several trusts in place. As mentioned earlier, there was a 2-way Forest Trust and an External Trust. During this engagement, I came to find out that an external trust will not work with Cross Forest Availability. Based on how other AD related features work, my explanation is that the External Trust will be used first since it’s technically a lower level, or more restrictive. When Exchange goes to communicate via the trust and pass credentials, it will pass those credentials via the Trust and if an External Trust is in place, it will try to use the External Trust, and will then fail miserably. This was validated via turning up diagnostic logging on MSExchange Availability to Expert level. During the availability request when the External Trust was in place, below is the error that was recorded.

Log Name:      Application Source:        MSExchange Availability Date:          7/24/2013 10:51:31 AM Event ID:      4002 Task Category: Availability Service Level:         Error Keywords:      Classic User:          N/A Computer:      SERVER01.domain.company.org

Description:

Process 7608[w3wp.exe:/LM/W3SVC/1/ROOT/owa-1-130181594999947019]: Proxy request CrossForest from Requester:S-1-5-21-3283536547-2396439389-1474086371-392179 to https://owa.company-2.org/ews/exchange.asmx failed. Caller SIDs: S-1-5-21-3283536547-2396439389-1474086371-392179. The exception returned is Microsoft.Exchange.InfoWorker.Common.Availability.ProxyWebRequestProcessingException: System.Web.Services.Protocols.SoapException: The authenticated user doesn't have sufficient privileges to issue this request.    at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)    at System.Web.Services.Protocols.SoapHttpClientProtocol.EndInvoke(IAsyncResult asyncResult)    at Microsoft.Exchange.InfoWorker.Common.Availability.Proxy.Service.EndGetUserAvailability(IAsyncResult asyncResult)    at Microsoft.Exchange.InfoWorker.Common.Availability.ProxyWebRequest.CompleteRequest(). The request information is ProxyWebRequest type = CrossForest, url = https://owa.company-2.org/ews/exchange.asmx

Mailbox list = <Test User>SMTP:testuser@company-2.org, Parameters: windowStart = 6/30/2013 12:00:00 AM, windowEnd = 8/11/2013 12:00:00 AM, MergedFBInterval = 30, RequestedView = MergedOnly

.. Make sure that Active Directory site/forest containing the user mailbox has at least one local Exchange 2007 server running Exchange Availability service. Turn up logging for MSExchange Availability service and test basic network connectivity.

Once we removed the external trust that was in place, the availability service started working as expected and the customer was receiving availability information from the remote forest just fine at that point.

So, the moral of the story here is to never, ever, ever (like, ever!) use External Trusts while working with Cross Forest Availability.

Special thanks to the following folks to assistance in understanding various pieces of information to write this:
Rob McGinnis, Jeff Dykstra, Bill Ziemer, Chad Solarz, and Dan Smith