MORE INFORMATION
Background (for UNIX Users)
UNIX UIDs and GUIDs (this article treats these two IDs as equal items) have always been integers. Historically, these integers have been 16-bit integers, but recently, they have become larger. These IDs are unique in a single computer or with certain tools, such as NIS, and they are unique across a limited group of computers.
The SID is the Windows NT-equivalent of these IDs. A SID is a string-like object that contains multiple components, which is typically represented as "S-1-
n-
n-
x-
x-
x-
y" (an example of a SID is S-1-5-21-790525478-57989841-1606980848-1003). A SID contains more than an integer's worth of bits, and it is universally unique for each real security principal, which may be a user, group, computer, or a number of other object types. The
x values and the
y values are each 32-bit numbers. SIDs have a type associated with them, such as "user" or "group." In some situations, a file's user owner can have a SID that is a group type. It may be helpful if you think that the user and group databases are constrained to contain the same entries.
UNIX programs that run on Interix require a single integer to represent a SID, and the Interix subsystem must provide a mapping between the two. If you map the SIDs to an integer, consider the following issues:
- SIDs contain two parts, the domain (which is further subdivided. This subdivision is not addressed in this article) and the relative ID (RID). The RID value is unique in any domain, but the same value may assigned in another domain. RID values are assigned at the time a user (or other security principal) is created; the computer selects the value. You cannot control the value (this behavior was designed for Windows NT 4.0).
- The domain part of the ID provides the universal uniqueness. There are several types of domains. Each computer forms its own domain by using the computer's unique identifier. Users who are authenticated on that computer have their SIDs formed from the computer's domain SID and the RID. Similarly, for users who have domain accounts, their SID is derived from the (unique) domain SID and the unique-within-the-domain RID.
- Typically, RIDs are assigned from small to large values in each domain; therefore, RIDs are frequently relatively small numbers.
- Additionally, certain SIDs are "well known" values that have been preassigned by Windows NT. These SIDs occur in a number of different domains, such as the Built-in domain and the NT Authority domain. These domains have SIDs that look a little different from computer and domain SIDs, and also must be able to be represented as UIDs.
UID Packing
You can convert an SID to a UID (and vice versa), as long as the number of domains that are involved is small enough and as long as the number of RIDs that is used in each domain is small enough. Both these limits are large; the maximum number of domains is 4094, and at least a million RIDs can be represented in each. With careful management, you can trade off these limits to allow for very large domains.
Windows NT includes the POSIX OFFSET value. This value is a 12-bit value (that is represented as the high 12 bits of a 32-bit word), which is maintained by each domain controller and accessible to all the computers in the domain. Each value represents the domain SID of another trusted domain.
The following table describes how to convert a packed UID to an SID:
If the high 12 bits (the POSIX OFFSET value) of the UID is:
0: The UID is a special case. If the next 4 bits (which correspond to the mask 0x000f0000) are:
0-1: The RID is preassigned by Windows NT in a built-in domain. (The mapping is arbitrary and mostly fixed.)
2: This value is not used (no meaning is assigned to this value).
3: The low-order 16 bits represent an RID in the computer's domain. (Local accounts, such as <computer> and guest.)
(Values 4 and higher are currently not used.)
1: The low-order portion of the word represents an RID in the domain in which the computer is registered.
2 to 4095: The low-order portion of the word represents an RID in the domain that corresponds to the POSIX OFFSET value found in these 12 bits.
The reverse is obvious (given the appropriate tables of SIDs).
Initially, it seems that POSIX OFFSET values are 12 bits, which limits the range of RIDs supportable to 20 bits (about a million). However, this is not quite the case. When a trust relationship is added to a domain, the domain controllers (that are running Windows 2000 or later) try to assign POSIX OFFSET values from high-order to low-order bits. (The first trust created has a POSIX OFFSET value of 0x80000000.) If several possible POSIX OFFSET values are reserved by the Interix implementation for a single trust, an increased range of RIDs can be supported.
For example, if only one trust exists, values for POSIX OFFSET values between 0x00100000 and 0x7ff000000 can be used by the local domain, and values between 0x80000000 and 0xfff00000 can be used by this single trust. In this situation, there can be nearly 2 billion RIDs in each domain.
Typically, more than one trust relationship exists, and some of the trusted domains are larger than others. If you select the POSIX OFFSET values for each trust to allow for a range of RIDs large enough for that domain, most configurations can be supported with 32-bit UNIX UIDs.
Controlling the Offset
You can use the
PsxOffset command to distribute the POSIX OFFSET values to perform either of the following tasks:
- To distribute the required space between POSIX OFFSET values.
- To make sure that POSIX OFFSET values are the same in several of the trusted domains. This task is valuable if you want to transfer numeric UIDs (for example, by using the pax command). However, the value of 0x00100000 always represents the current domain.
In many situations, there is little benefit in changing the computer's default settings, because domains that have more than a million RIDs are rare and numeric UIDs between domains are rarely transferred. Additionally, the computer has already tried to allocate values that have a lot of space between them, and that space may be enough. You may not be able to move a UID's numeric values between classical UNIX systems either.
However, if you must perform either of the preceding tasks, follow these steps:
- Use the PsxOffset -list command to get a list of the POSIX OFFSET values for all the trusted domains that are known to the current domain.
- Based on the number of RIDs that you expect to use over time in each domain, allocate ranges of POSIX OFFSET values large enough for each domain.
If you expect to add additional trusts, leave room for them. If you do not expect to add additional trusts, leave room for growth of the RID space in each domain. Remember that offsets 0 and 1 are reserved, and that 1 is for the current domain; therefore, leave room for the largest domain after slot 1 in all domains. - Use the following command to write a script to set the offset of each domain to the value you want to use:
PsxOffset -set domain_nameoffset
You may have to work around value collisions. If you have a script, you can modify the offset later.
- Restart every computer in the domain that is running Interix.
The computers receive the POSIX OFFSET value from the domain controller; however, the computers in the domain may not accept these values until you restart them.