Thursday, November 22, 2012

SubInACL in Forest Trust and Child Domain situation

This is a nice find by my colleague Arjen Karten, so all credit goes to him of course!
Imagine a situation:
You have 2 forests:

FABRIKAM = Source - single label forest
CHILD.FABRIKAM = Source Child domain

CONTOSO.COM = Target Forest
You need to re-ACL resources (file shares, application directories, etc…) so you call good old friend "SubInACL". A wonderful tool that allows for scripting and is a sort of "swiss army knife" when it comes to re-ACL jobs. So in our situation we are migrating from CHILD.FABRIKAM to COTOSO.COM. There is a forest trust in place, so the trust relation between FABRIKAN and CHILD is inherited by CONTOSO.COM via the Forest trust, and there is no direct trust relationship between CHILD.FABRIKAM and CONTOSO.COM. When you attempt to run the SubInACL with /changedomain=CHILD=CONTOSO, you will get an error stating that domain name cannot be found. Now we checked everything regarding DNS etc. and all is nice and dandy, and still it does not work. We actually cannot even setup a secure channel connection directly from CONTOSO to CHILD or vice versa.
This problem is also described here: http://www.mombu.com/microsoft/windows-server-migration/t-subinacl-610756.html and there is no answer really.
Well there is: = my colleague Arjen Karten
came up with the idea to solve this… Since Arjen does not have a public blog (yet) I volunteered to publish the solution on mine, but all the Kudos go to Arjen of course. Arjen is a Group Manager with Avanade and we are currently staffed on the same project involving AD migration for a large corporate customer.

So here is what he came up with
"When you try to use subinacl /changedomain in a cross forest migration, with the source or target domain being child domain, you get an error 'Could not find domain name'.
C:\TestFolder>subinacl /subdirectories c:\testfolder\*.* /changedomain=CHILD=CONTOSO
1355 Could not find domain name: child
Error finding domain name: 1355 The specified domain either does not exist or could not be contacted.
Current object c:\testfolder\*.* will not be processed
Elapsed Time: 00 00:00:00
Done:        0, Modified        0, Failed        0, Syntax errors        1
Last Syntax Error:WARNING : /changedomain=child=contoso : Error when checking arguments - c:\testfolder\*.*
From the network trace, you can see that the server that is being migrated (xxx) tries to request the resolve the source domain (CHILD) from its domain controller (yyy).
The domain controller does not have a direct trust connection with the CHILD domain, which is a child domain in the source forest and fails to resolve. (0x54b is 1355 in decimal)
This seems a specific issue with how subinacl tries to resolve the source domain CHILD)

143        1.769676000      192.168.1.xxx     192.168.1.yyy     RPC_NETLOGON              272               NetrGetAnyDCName request
Microsoft Network Logon, NetrGetAnyDCName
    Operation: NetrGetAnyDCName (13)
    Server Handle: \\CONTOSODC01
    Domain: CHILD
144        1.770466000      192.168.1.yyy     192.168.1.xxx     RPC_NETLOGON              202               NetrGetAnyDCName response, Unknown error 0x0000054b
What does work is:
C:\TestFolder>subinacl /subdirectories c:\testfolder\*.* /replace=child\gs-testgroup1=contoso\gs-testgroup1
This means groups and accounts from the source domain can be migrated, but apparently not with the changedomain option.
But it is rather inconvenient to have to add 10.000 groups to the commandline.
After a few hours of troubleshooting and testing with dumpcachedsids and offlinesam we discovered that the issue with a child domain is that a target domain controller cannot resolve the domain name and provide the sid of the source domain.

The solution is to create a domainsid.txt file that contains a single line with the sid of the domain that cannot be resolved:
Use the Sysinternals psgetsid tool to dump the Source domain sid.
C:\INSTALL\PSTools>PsGetsid.exe child
PsGetSid v1.44 - Translates SIDs to names and vice versa
Copyright (C) 1999-2008 Mark Russinovich
Sysinternals - www.sysinternals.com
SID for CHILD\child:S-1-5-21-2349847776-1970708901-3682075933

Create a textfile domainsid.txt and a single line as below:

               child=S-1-5-21-2349847776-1970708901-3682075933
Run the subinacl command again with the offlinesam parameter:
C:\TestFolder>subinacl /offlinesam=domainsid.txt /subdirectories c:\testfolder\*.* /changedomain=child=contoso
And subinacl works again!!!!!!
If you try to use dumpcachedsids to create an offlinesam, you will notice that this does not give you the expected result as it prohibits any use of domain controllers to resolve sids and does not contain any domain sids (source nor target).
C:\TestFolder>\install\subinacl /dumpcachedsids=sids.txt /subdirectories c:\testfolder\*.*  /display  

This result in a sids.txt with the following contents:
__cachefileonly__
contoso\domain users=S-1-5-21-4064155377-322177466-2899229887-513
system=S-1-5-18
builtin\administrators=S-1-5-32-544
builtin\users=S-1-5-32-545
child\gs-testgroup1=S-1-5-21-2349847776-1970708901-3682075933-1114
creator owner=S-1-3-0
 The __cachefileonly__ value makes sure that only the sids.txt is used to resolve sids and no domain controllers are involved. This is the default dump setting from subinacl
 If you try to run the migration with the offlinesam=sids.txt option, it fails.
C:\TestFolder>subinacl /offlinesam=sids.txt /subdirectories c:\testfolder\*.* /changedomain=child=contoso
Could not find domain name in SAM cache file: child
Error finding domain name : 87 The parameter is incorrect.
Current object c:\testfolder\*.* will not be processed
Elapsed Time: 00 00:00:00
Done:        0, Modified        0, Failed        0, Syntax errors        1
Last Syntax Error:WARNING : /changedomain=child=contoso : Error when checking arguments - c:\testfolder\*.*
  If you add the source domain sid to the sids.txt file, you find that the target domain (CONTOSO) now cannot be found. But as the target domain is the local domain, this should be resolvable.
C:\TestFolder>subinacl /offlinesam=sids.txt /subdirectories c:\testfolder\*.* /changedomain=child=contoso
Could not find domain name in SAM cache file: contoso
Error finding domain name : 87 The parameter is incorrect.
Current object c:\testfolder\*.* will not be processed
Elapsed Time: 00 00:00:00
Done:        0, Modified        0, Failed        0, Syntax errors        1
Last Syntax Error:WARNING : /changedomain=child=contoso : Error when checking arguments - c:\testfolder\*.*
In order for subinacl to check with the local domain controller again, you need to remove the __cachefileonly__ line from the sids.txt
As user and group accounts from the source domain can be resolved by subinacl, as proved by the subinacl /replace=child\testgroup=contoso\testgroup command, all other sids, except for the source domain sid are not necessary."

Tuesday, November 13, 2012

Cross-Forest Free/Busy – the Simple Version

I am currently on a project which involves cross-forest mailbox migration (as part of the AD migration/consolidation). In such cases the migration is a process which can take considerable amount of time, so naturally coexistence is important. So mail routing and GALSync need to be in place, and what offers the most value to the business is the Free/Busy lookups cross-forest. Now we all know that starting with Exchange 2007, but truly it is better implemented in Exchange 2010 and higher, there is what we call Exchange Federation. Exchange Federation allows federating two partner companies to share the Calendar and Contact information cross-forest. While this feature allows for sharing more than just Free/Busy, but also the subject of the appointments, the location, etc. (what I call "Rich" Free/Busy), it requires that both organizations have at least one Exchange 2010 CAS server present, and involvement of Microsoft Federation Gateway.

Now on my project the source environment is Exchange 2007 and implementing an Exchange 2010 is not feasible. So my good friend and colleague Arno Zwegers (who is an Exchange Ranger) has pointed out to me that we could offer a "simple" Free/Busy lookups without deploying Exchange 2010 CAS box in the source. This method also does not require access to the Microsoft Federation Gateway (which means you do not need publicly signed certificates per se, as long as the CAs which issued the certificates are mutually trusted).

So…

It is possible to provide free/busy lookups cross forest between two Exchange 2010 or 2007 or a mix of these, without the need of using the Microsoft Federation Gateway. This will offer only basic free/busy information.

Requirements:

  • It only works for Outlook 2007 or more recent clients. Outlook 2003* users will NOT be able to see Free Busy/Availability information from people located in the other side (so between non-migrated and migrated users).
  • It will only work for mail enabled objects that exist in the Global Address List. So it will not work when an object is not listed in the Global Address List. So you need to maintain an up-to-date GAL (GALSync, Script, whatever…)

So…
To be able to access Free/Busy information between Contoso Forest and Fabrikam Forest the following needs to be done:

  1. The host files on ALL CAS servers in both forest need to be adjusted. Entries which will be pointing to respective autodiscover records should be added.
    autodiscover.contoso.com & autodiscover.fabrikam.com
  2. In Contoso Forest create an account "freebusy"(plain user account-CONTOSO\freebusy)
  3. In Fabrikam Forest create an account "freebusy"(plain user account-FABRIKAM\freebusy)
  4. In Contoso Forest: Logon to a CAS server and run the following commands:

Add-AvailabilityAddressSpace –Forestname "fabrikam.com" -AccessMethod OrgWideFB –Credential (get-Credential)
When prompted for the credentials use the "FABRIKAM\freebusy" credentials.

Set-AvailabilityConfig –OrgWideAccount freebusy
freebusy here is the local account we created earlier.

  1. In Fabrikam Forest: Logon to a CAS server and run the following commands:

Add-AvailabilityAddressSpace –Forestname "contoso.com" -AccessMethod OrgWideFB –Credential (get-Credential)
When prompted for the credentials use the "CONTOSO\freebusy" credentials.

Set-AvailabilityConfig –OrgWideAccount freebusy
freebusy here is the local account we created earlier.

Now wait for 15-30 minutes and try scheduling an appointment between 2 users from 2 different forests.

I have successfully tried this in the situation with 2010 and 2007, but I am quite sure it will work for Exchange 2013 as well. (@Arno, Correct me if I am wrong)

* To accommodate Outlook 2003 clients which use Public Folders to retrieve the Availability information exFolders can be used to sync the System and Free/Busy Public Folders between two forests. "exFolders" is the new name for the old IORepl Tool (Inter-Org Replication Tool), which offers the possibility to synchronise Public Folders cross-forest.