When migrating from one domain to another (usually new) domain, the users and groups are migrated so as to retain their historical SID. This is so that the migrated account in the new domain can still access resources in the old domain that were secured against that users unique SID or groups to which that user was once a member. When a user account is migrated, a new account is effectively created with a new, unique SID, but the old SID is also retained.
This is convenient so that everything continues to “hang together” in terms of newly migrated users being able to access new data and old data pending its inevitable migration to file servers or NAS in the new domain.
Once the data is migrated to the new domain, then the ACL’s will still likely contain ACE’s of user and group SIDs from the legacy domain. The migrated users will still be able to access this data provided the old domain continues to exist for the purposes of authenticating old SIDs but at some point, the old domain will likely be scheduled for decomissioning to free up money and space associated with cooling, electricity and ongoing support overheads. Another option would be to virtualize an old DC and have done with it.
The legacy user and group SID’s contained in the ACE’s will need to be translated to the primary SIDs of the new migrated users and groups to remove the need for legacy DC’s to remain in the new environment. This can be done using SetACL – the freely available tool mentioned in other posts such as Removing Orphaned SIDs.
The following prose is a combination of my own notes and those found on the Helge Klein website where SetACL can be downloaded.
Migration – the Flexible Way
SetACL 3 comes with a more flexible way of handling permissions migrations. Its enhanced migration engine can be used to migrate intra-domain, inter-domain or any mix of the two. To start a migration using the flexible model use a command line similar to the following:
SetACL -on D:\Data -ot file -actn trustee -trst csv:C:\temp\mappings.csv;ta:repltrst -rec cont
This instructs SetACL to copy permissions between individual users or groups for the D:\Data directory tree. Which accounts the migration is performed for is read from a simple CSV file, mappings.csv in the example, whose contents might look like this:
MyOldDomain\Joe,MyNewDomain\Peter
MyOldDomain\Mary,MyNewDomain\Mary
MyOldDomain\DG-OldDom-HelpDesk,MyNewDomain\DG-NewDom-HelpDesk
MyOtherDom\Fred,MyNewDomain\Fred
or like this… (both formats are supported, I prefer this one i.e. sddl format)
S-1-5-21-1552345877-4092344333-3107638942-187127,S-1-5-21-3615417180-1828292988-6264
S-1-5-21-1552345877-4092344333-3107638942-187157,S-1-5-21-3615417180-1828292988-6294
S-1-5-21-1552345877-4092344333-3107638942-187177,S-1-5-21-3615417180-1828292988-6394
As you can see, the system is flexible, powerful and easy to use. All you have to do is create a mapping table pairing old account with new account. If you do not want to do that or if you think it is just too much bother: the simpler method presented above still works and is still considered useful in many scenarios.
Command reference
https://helgeklein.com/setacl/documentation/command-line-version-setacl-exe
Working example
Back up directory security first. Always use a starting folder, not the root of the drive. The restores do not work to the root of a drive as the export file has an empty first line that upsets the restore process. This means you may need to back up each top level folder individually so that your restores would work or you can just delete the first empty line (but be aware you’ll not recover its permissions and applying them manually will cause them to subsequently ripple down through the tree (no)thanks to Windows’ behaviour.)
icacls D:\sourcedata /save ACL_Dep.txt /T /C (Traverse and continue on errors )
backups of acl’s can be restored as follows:
icacls D:\ /restore ACL_Dep.txt /c (continue on errors such as missing files)
Map files can be created as follows.
Dump SID + SID history to a file for Migrated Groups: (change the OU path with the correct one for your AD)
dsquery * “OU=Groups,OU=MigratedGroups,OU=Cromford,OU=UK,OU=DEV,OU=VMFARM,DC=cyberfella,DC=co,DC=uk” -filter “(&(objectClass=Group)(sidHistory=*))” -attr sidHistory ObjectSID -limit 20000 > Sidmapping.txt
Check if –limit option is set large enough given the number of groups in your domain. Perform necessary edits to the sidmapping.txt file until it’s format looks like this (below).
S-1-5-21-2121000310-530922351-1601650009-38709,S-1-5-21-1477100029-3748294062-1861910009-37469
S-1-5-21-2121000310-530922351-1601650009-171643,S-1-5-21-1477100029-3748294062-1861910009-37983
S-1-5-21-2121000310-530922351-1601650009-67673,S-1-5-21-1477100029-3748294062-1861910009-38089
S-1-5-21-2121000310-530922351-1601650009-67965,S-1-5-21-1477100029-3748294062-1861910009-38585
S-1-5-21-2121000310-530922351-1601650009-68256,S-1-5-21-1477100029-3748294062-1861910009-38867
S-1-5-21-2121000310-530922351-1601650009-54379,S-1-5-21-1477100029-3748294062-1861910009-39244
S-1-5-21-2121000310-530922351-1601650009-127676,S-1-5-21-1477100029-3748294062-1861910009-39397
Re-ACL Migrated Group ACE’s from the historical SIDs currently securing the data to the primary object SIDs in the new domain using the freely available SetACL tool.
setacl -on D:\destinationdata -ot file -actn trustee -trst csv:sidmapping.txt;ta:repltrst -rec cont_obj –log reacl_log.txt
The following command will delete any orphaned SIDs (ACE’s that to don’t resolve to any group in AD and thus serve no purpose)
setacl -on D:\destinationdata -ot file -actn delorphanedsids -rec cont_obj
EXAMPLE TIMINGS
(Obviously your results may vary depending on many variables such as number of folder, files, rows in sid map csv, disk speed, cpu speed, etc)
Exporting ACLs for 128GB filesystem consisting of 30,000 files in 2,750 folders on an HP ProBook CORE i5 laptop took 15 seconds.and processed every file successfully although problems are generally encountered if files have been created using file explorer run as administrator (the ownership changes from the logged on user to admnistrators).
5 new groups were added to the acl’s at the top of the tree and re-exporting the security took 17 seconds (a further 3 seconds)
Re-ACLing the filesystem using a SID Map containing 5 rows to translate ALL ACE’s referencing the newly added groups to a single new group, took 5 minutes, 45 seconds.
Copying the folder structure only but leaving all files behind (create duplicate empty folder structure with security using emcopy), took 14 seconds.
Re-ACLing the empty folder structure (2,750 folders), avoiding the overhead of scanning and re-acling 30,000 files took 25 seconds.
It is therefore recommended that re-acling take place on a duplicate empty folder structure and data (files) are subsequently copied into it using emcopy with the /nosec switch.
For large filesystems, say over 1TB, you may want to process each top level folder as its own individual job, looping through all top level folders sequentially. It’s definitely my preferred approach with pretty much everything, not just setacl. You can use a for loop to do this, e.g.
for /f %%f in (‘dir s:\ /ad /b’) DO setacl.exe -on “d:\root\%%f” -ot file -actn trustee -trst csv:sidmap.txt;ta:repltrst -rec cont_obj
INHERITANCE PROTECTION ISSUE
As is often the case, the real-world (the source of all my blog posts) presents some unforseen issues around the use of these complex tools, and setacl appears to have an issue whereby re-acling using the trustee action above (the same method as documented on Helge Klein’s website) also performs a reset on the inheritance attribute, potentially opening up hardened subfolders where the original inherited ace’s have been partially retained and inheritance turned off.
The following sequence of commands appear to correct the issue by re-breaking inheritance, removing inherited ace’s, applying specific permissions to the subfolder before turning inheritance back on on the parent.
Consider the following structure. T:\level 1\level 2\level 3 where level 2 inherits from level 1 but level 3 stops inheriting and has its own permissions set. If these permissions were originally ace’s that were inherited, then re-permissioning can reset inheritance. The following sequence of commands seems to correct it. Your mileage may vary.
setacl -on “t:\level 1\level 2” -ot file -actn setprot -op “dacl:p_nc;sacl:p_nc” (Protection, No Copy Inherited ACEs)
setacl -on “t:\level 1\level 2\level 3” -ot file -actn ace -ace “n:S-1-5-21-12345-12345-12345-1234;p:full” -ace “n:S-1-5-21…. and so on.
setacl -on “t:\level 1\level 2\level 3” -ot file -actn setprot -op “dacl:p_nc;sacl:p_nc” (Protection, Remove Inherited ACEs)
setacl -on “t:\level 1\level 2” -ot file -actn setprot -op “dacl:np;sacl:np” (No Protection)
Thanks for the post, useful info in addition to the original tool. When running on a 2016 server I didn’t have the issue where inheritance was broken.