This, the second article of our series about security in Windows 2003 Server, continues the discussion of new Active Directory security-related features, particularly SID filtering and software restrictions policies.
To understand the idea behind Security Identifier (SID) Filtering, we must first look at the role of the SID. SID is a unique string of characters assigned to a user, group, computer, or domain. It is used internally by Windows when establishing the identity of an account to determine a level of privileges and access permissions on resources. Its uniqueness is guaranteed within the scope in which SIDs function. For local accounts, the uniqueness might be limited to a single instance of the operating system (and frequently is -- especially in environments where operating system cloning is used).
For Windows 2000 and later domain accounts, on the other hand, SIDs are unique per forest, since SIDs of domain accounts (users, groups, or computers) include a SID assigned to the domain in which they are created. In Windows 200x domains, the task of keeping track of SID uniqueness is handled by RID Operation Masters (one per domain), which hand out ranges of available identifiers to individual domain controllers in each domain. This mechanism was obviously different in Windows NT domains, where the only computer capable of assigning domainwide SIDs was a primary domain controller for each domain.
However, this is not the only difference in how Windows NT and 200x domains handle SIDs. In Windows NT, every security principal could have only a single SID; this has changed in Windows 200x native mode domains. Besides the primary SID (identical in its role to the Windows NT 4.0 SID), a user, group, or computer account can have a number of secondary SIDs stored in a single Active Directory attribute called sIDHistory. sIDHistory's primary purpose is to simplify domain migration processes.
For example, imagine a scenario in which UserA migrates from Windows NT 4.0 domain DomainA to Windows 2000 native or Windows 2003 mode domain DomainB. Since the primary SID of the account DomainB\UserB cannot be the same as DomainA\UserA, after migration is completed, UserB would not be able to access the resources to which UserA has access. To remedy this problem, all resources used by UserA must be found and repermissioned appropriately, granting equivalent privileges to userB. As you can imagine, migrating even a handful of accounts in this fashion requires significant investment in time.
sIDHistory attribute makes such effort unnecessary. The administrator simply includes the SID of DomainA\UserA in the sIDHistory attribute of DomainB\UserB. Once UserB tries to access the resource, the UserA SID stored in sIDHistory attribute ensures that the appropriate level of permissions is granted.
The sIDHistory attribute can be modified manually (using Windows 200x Support Tools -- such as ADSI Edit) or via ADSI scripting. In most Windows 200x migrations, adding SIDs of user accounts in a source domain to the sIDHistory attribute of user accounts in a target domain is performed automatically by migration tools. Practically all commercially available migration packages (as well as freely downloadable Active Directory Migration Tool from Microsoft) offer this functionality.
Unfortunately, the convenience of sIDHistory does have a major drawback -- increased vulnerability. For example, consider a situation where DomainX trusts DomainY, which means that user accounts from DomainY can access resources residing in DomainX (providing, of course, that appropriate permissions on DomainX resources are granted to DomainY users or groups). If an unethical administrator from DomainY manages to obtain a SID of a privileged account from DomainX (SIDs can be easily extracted from, for example, Access Control Lists), he or she can add the SID to the sIDHistory attribute of his or her own account. This effectively grants this administrator the same level of permissions granted directly to the privileged account.
To mitigate this threat, Windows 2003 provides a SID Filtering feature. SID Filtering is enabled by default on Windows 2003 domain controllers (and Windows 2000 domain controllers with Service Pack 4 installed), and it applies to requests coming from domains joined via external trust (external trusts use non-Kerberos authentication between domains and are used to join Windows 200x and legacy domains or domains from two domains in separate forests) and forest trusts. However, SID Filtering cannot be implemented for domains residing in the same forest.
Domain controllers in a domain with SID filtering enabled compare each of the SIDs included in an authentication request (which contains also SIDs in the sIDHistory attribute) with the SID of the domain hosting the account that generated this request. If the domain SID embedded in a SID stored in sIDHistory attribute does not match the SID of the source domain, that SID is not taken into consideration when evaluating permissions to access local domain resources.
As you can imagine, SID Filtering can have also some undesirable side effects. One of them is the impact on permissions granted via universal groups. For example, let's assume a user from one domain is a member of a universal group created in another domain and that universal group is used to grant permissions to resources in yet another domain. If the resource and accounts domains are joined via external trust relationships with SID Filtering enabled, that user will not be able to access these resources.
To circumvent this problem, the administrator must create a universal (or global) group in the user's domain, grant appropriate permissions on the resources to this group, and make the user its member.
Another potential problem results from situations where sIDHistory has been used during the migration to the target domain, but permissions in the resource domain are still based on premigration accounts.
In such cases (or if you want to eliminate SID Filtering for other reasons), you can turn it off using the NETDOM.EXE command line utility. In the case of the earlier example, if DomainX trusts (via external trust) DomainY, you can turn off the filtering in DomainX for authentication requests coming from DomainY by running (using administrative account from DomainX -- in this case AdministratorX with the password $w0rdFi$h) with the following:
NETDOM trust DomainX /domain:DomainY /quarantine:No /usero:DomainX\AdministratorX /passwordo:$w0rdFi$h
Re-enabling SID Filtering would involve running the same command with the /quarantine parameter set to Yes.