Family Inheritance

Knowing how NTFS passes down file access attributes would have helped one systems administrator avoid exile to the basement. It could do the same for you.

I try to avoid taking long looks at myself in the mirror, but when I do, I see features that have branded members of both sides of my family for generations. Big ears, bad eyes, thin hair. Inheritance is a blessing or a curse, depending on what characteristics you get and from whom you get them.

I started thinking about inheritance the other day after overhearing someone moan about a calamity on a big Windows NT 4.0 file server. It seems that a recently trained administrator had gotten a work request from an irate manager who wanted contractors blocked from accessing server-based files. “They can store their stuff on their own hard drives,” the manager wrote in her work request. “Just keep them away from everyone else’s files, especially mine.”

This junior administrator, eager to exercise his newly acquired system privileges, promptly set to work. Using Windows Explorer, he opened the Properties window for the root of the data drive on the server. He selected the Security tab and clicked Add. He found a group named Contractors and added it to the access list along with the Administrators group, the only other entry. He then selected No Access from the permissions drop-down list, checked the box labeled “Replace Permissions on Subdirectories” and clicked OK.

It wasn’t long before the phones started ringing at the help desk as users from all over the company—contractors and regular employees alike—called to complain that they’d lost access to their files. The administrator who made the change was thoroughly perplexed. “Why would non-contractors lose access?” he asked in bewilderment as the CIO had him hauled down to the basement to do maintenance inventories for the next six months.

To give this administrator a complete answer to his question requires a close look at the operation of the NTFS file system, especially the role of an innocent-looking data structure called the security descriptor. While we’re at it, we’ll see how the outcome would have been different on Windows 2000, where permission inheritance can help avoid these kinds of problems.

NTFS and Access Permissions
I’m sure you know the NTFS file system is a database contained in a file called the Master File Table (MFT). This database consists of a series of one-kilobyte records, each of which contains a brief header followed by a set of attributes that describes the contents of a file or folder.

When the junior administrator opened the Properties window at the root of the volume and selected the Security tab, he saw the contents of an attribute called $Security_Descriptor. This attribute defines who owns the associated MFT record, who can access the contents of the record, what they’re permitted to do, and who can audit their actions.

Users, groups and computers with access permissions to a file or folder are listed within the security descriptor in a table called the Discretionary Access Control List (DACL). The term “discretionary” differentiates the ACL from the “security” ACL, which controls auditing permissions.

The DACL is the business end of the stick used to control access permissions. It contains a set of Access Control Entries, or ACEs, each of which consists of a Security ID (SID) and a 32-bit number called an access mask. Bits in the access mask define specific permissions. For example, bit No. 1 sets Read permission, bit 10 sets Write permission, and bit 100 sets Append permission.

When a user touches a file or folder, the file system extracts the DACL from the security descriptor and hands it over to the Security Reference Monitor (SRM) in the Windows Executive. The SRM compares the contents of the security descriptor with the user’s access token. This token contains the user’s SID along with the SIDs of any groups to which the user belongs and other assorted security information.

The SRM does its evaluation by plucking the first ACE from the DACL then scanning the access token looking for a match to the SID in the ACE. If it finds one, it compares the permissions requested by the user process to the permissions listed in the access mask. For example, if the process opened a file for Read/Write access, the SRM looks for the Read and Write bits set in the access mask.

The SRM has its eye on the clock and doesn’t want to do any extra work. It goes through the ACEs and, once it finds a match for a particular permission, it stops looking for other ACEs lower down that might have access masks that control the same permission. This is called canonical evaluation, based on the root word canon, which means a body of information arranged in the order it’s encountered. A canon of music, for instance, might start with Mesopotamian lute strumming and continue through Mozart cantatas to end up with Eminem rap music.

The SRM takes no responsibility for sorting the ACEs. It’s solely up to the application, such as Explorer, that modified the contents of the security descriptor to arrange the ACEs in the DACL in a way that makes sense during canonical evaluation. Generally, this means that Deny entries come before Allow entries, although some applications such as Exchange 2000 play games with this sorting.

If the SRM doesn’t find a match between the SIDs in the access token and the ACE entries in the DACL, including a match for every permission requested by the user process, it denies access completely. “If you aren’t on the A list, buddy,” says the SRM, “you don’t get in.”

Which brings us to the event that occurred to our hapless junior administrator. When he added the Contractors group to the access list at the root folder of the volume, he modified the contents of the DACL in the $Security_Descriptor attribute of the “\” (root) record. His decision to apply this change to subfolders and files was what ruined his afternoon, because the file system obligingly went on to overwrite the $Security_Descriptor attribute in every file and folder record in the MFT database. This wiped out any existing permissions lower in the tree, which is why users other than members of the Contractors group lost access.

Windows 2000 and Permission Inheritance
The root cause of the administrator’s mistake wasn’t so much a lack of training as a flaw in the operating system whereby a single mouse click could wreak that kind of havoc. Fortunately, in the versions of NTFS that ship with Win2K and XP, Microsoft completely re-engineered the mechanism for handling security descriptors. (The internal version number of NTFS in NT 4.0 is version 1.2. NTFS version 3.0 ships with Win2K and version 3.1 ships with XP.)

In NTFS 3.x, files and folders don’t have discrete security descriptors. All security descriptors are stored in a database under a new MFT metadata record called $Secure. The security descriptors in the $Secure database are assigned index numbers that link them to the MFT records of files and folders in the volume.

When a user accesses a file, the file system obtains the security descriptor index number from the $Standard_ Information attribute in the file record, goes to the $Secure database, looks up the security descriptor that corresponds to the index number, and delivers the DACL inside that security descriptor to the Security Reference Monitor for processing. (This happens a lot more quickly than it takes to describe.)

This central repository of security descriptors in the $Secure database makes it possible to implement inheritance for file and folder permissions. The mechanism for this inheritance isn’t quite as intuitive as you might think, though.

When you create the first folder at the root of a new NTFS 3.x volume, the file system creates a new security descriptor entry in the $Secure database. Any new folders and subfolders you create in that volume will reference the index number of that security descriptor in their $Standard_Information attribute, at least as long as you don’t change the default permissions. In this way, folders and subfolders appear to inherit their permissions when—in actuality—they share the same security descriptor.

A slight complication to this mechanism is necessary to conserve the number of security descriptors and speed up processing. From the outside, it looks as if the system should just find the security descriptor index number in the parent folder and give the same index number to the subfolder. In actuality, the system selects a security descriptor in the same way that I locate a pair of socks in the morning, by finding one sock then rummaging around looking for a match.

The file system first calculates the contents of the security descriptor needed by the file or folder. It then scans the $Secure database looking for a security descriptor that has the same contents. To avoid a slow, byte-by-byte comparison of all the security descriptors during the scan, the $Secure database has a lookup table called $SDH that stores the index number of each security descriptor and a 128-bit hash of the security descriptor’s contents. To do the scan, the file system hashes the calculated security descriptor then compares the result with the hashes in the lookup table. If it finds a match, it does a byte-by-byte comparison of the actual security descriptor for verification, then uses its index number as the link to the new MFT record. The database also stores a cross-reference between hashes and index numbers in the $SII index to speed up access to security descriptors.

Permission Inheritance Mechanisms
We’re just about ready to see how Win2K permission inheritance might have kept our junior administrator in the good graces of the CIO, but first we need to wiggle past a complexity in the permission process itself.

To accommodate permission inheritance, each ACE in an NTFS 3.x DACL must be flagged to determine its inheritance setting. By default, when you put a new user or group on the access list for a folder, the new ACE is set to be inherited by all files in that folder and all subfolders and files below the folder. But as we’ve seen, this inheritance isn’t calculated dynamically. The security descriptor in the $Security database is a fixed entity. This means the system needs a way to differentiate between ACEs, depending on their source, so it can create new security descriptors for the subfolders and their files.

If you add a user or group to an access list, the result is a Direct Apply ACE. This contrasts with an Inherited ACE placed there by the system. The ACL Editor in the Security tab of the Property window in Explorer has an Advanced view that lists each ACE in the security descriptor and whether it was inherited or directly applied. The ACL Editor in XP, shown in Figure 1, shows the source folder of each inherited ACE.

ACL Editor
Figure 1. The ACL Editor (viewed from the Windows XP GUI), tells you from where the file got its permission settings. (Click image to view larger version.)

So, let’s say you add a group to the access list of a folder that already has a couple of inherited ACEs. The file system creates a new security descriptor in the $Secure database for that folder and constructs a DACL that lists the new group as a Direct Apply ACE along with the original Inherited ACEs. It then creates still another security descriptor for the subfolders under the folder where you made the change. This security descriptor has the same set of ACEs in the DACL, but the ACE for the new group is flagged as Inherited. The system then proceeds to update the $Standard_Information attributes of the subfolders to point at this new security descriptor.

How Windows 2000 is Different—and Better
Let’s see how this new-fangled NTFS permission machinery would have kept our junior administrator out of trouble. When he placed the Contractors group on the access list for the root of the volume, the file system would have created a new security descriptor containing the old ACE for the Administrators group, plus a new ACE for the Contractors group. Both of these entries would be Direct Apply ACEs because they’re applied to the root of the volume, the highest point in the directory tree.

The system would then construct a security descriptor having a DACL with the same ACE list, but with each ACE flagged as Inherited. It would then visit each MFT record and update the index number in the $Standard_Information attribute to point to the new security descriptor.

If this sounds like what happened in NT, here’s the difference. When the system encounters a folder with a pointer to a different security descriptor, it creates a new security descriptor that retains the original ACEs, plus the new ACE for the Contractors group. As a result, the Deny ACE for the contractors is added to folders and files throughout the volume without disrupting access by any other users. And because only a limited number of security descriptors were involved, the operation occurs much more quickly than with NT.

If you’re rolling out Win2K servers and desktops, or planning on doing so, it would be worth your time to play around with file maneuvers and permission settings in the lab so you can prepare your users for any changes. If you find other interesting or surprising convolutions caused by permission inheritance, let me know.

Featured