How an Access Control List Is Used

7/28/2010 9:30:21 AM
How an Access Control List Is Used
When a user, or rather, a process acting on behalf of the user, opens an object the OS performs an access check before access is granted. The access check matches up the permissions on the object with the type of access the user requested. If the user has permissions granting the type of access requested, the access is granted. If even one is missing, the access is denied. In other words, say that you have a user foo, who has the following access to an object bar: read, write, execute. The user executes an application that attempts to open the object. The application asks for read, write, and delete access. In this case, the access attempt would be denied because user foo does not have delete access. It makes no difference if the application actually deletes the object or not. The mere fact that the application asked for delete access is enough to deny the entire request. If the application retries and asks for read and write access only, the access attempt is allowed.

At a more detailed level, the access check works following a very specific process. When the user attempts to access an object the OS determines what level of access was requested. Let us say the level of access was Read and

Write. The OS now retrieves the DACL on the object along with the process token for the process performing the access, and proceeds to evaluate whether the DACL grants the user the requisite permissions. The access check proceeds only until all requested permissions have been granted or a deny ACE is encountered that prohibits at least one of the requested access methods. If the user is a member of Administrators and the Administrators group is granted Read and Execute and the user is granted write access, then the access attempt would succeed. However, if the user is also a member of the Users group, and the Users group is denied write permission, then the access would be rejected because the application asked for write permission.

The DACL should follow a specific order. However, the operating system will not verify that the ACL is ordered correctly during an access attempt. That can cause some mildly surprising results. The recommended order specifies that explicit (non-inherited) deny ACEs go first, following by explicit allow ACEs. Then follows inherited deny ACES, in the order they were inherited. Finally, you have the inherited allow ACEs, again in the order they were inherited. The order within the inherited ACEs is based on where they were inherited from. The closer to the object you are trying to access the ACE came from, the higher in the order it goes.

This inheritance order can cause some unexpected results if you do not understand it and pay close attention to it when setting ACLs. Let us say, for example, that you have a directory and a file with the following permissions:

C:\>icacls c:\users\jesper\downloads\test /t
c:\users\jesper\downloads\test TEST\jesper:(OI)(IO)(DENY)(S,GR,GW)
c:\users\jesper\downloads\test\testDoc.txt TEST\jesper:(F)

In this case, you have a folder, called TEST. The SYSTEM user (also called LocalSystem) and all Administrators have full access to the folder. The user jesper has full access to the folder, but there is an inherit-only ACE that is inherited by objects, which denies jesper read (GR or Generic Read) and write (GW or Generic Write) access. Jesper also is denied Synchronize (S) access. Synchronize permits, or in this case, denies, jesper creating a synchronization handle to the object. Synchronization handles can be used, for example, to get notified when an object changes.

The deny ACE for Jesper is also inherited by the testDoc.txt file inside the test directory. You can see it there as the second ACE in the list and can tell that it is inherited (based on the I flag). However, it is not the first ACE in the list. The first ACE is the explicit full control ACE specified directly on the file. Now, what do you suppose happens when jesper tries to open the file? If you guessed "access is granted and the file opens normally" you are correct! This is counter-intuitive to many people who are used to hearing that deny ACEs take precedence over allow ACEs. They do, but explicit ACEs, whether inherited or denied, take precedence over inherited ACEs, whether inherited or denied. Therefore, the access is granted.

This result is very important because it means that putting deny ACEs on parent objects is not particularly meaningful as those ACEs may not be honored by children that have explicit ACEs on them. Ideally, you should grant permission only to those that should have it, and use deny ACEs extremely sparingly.

Another important thing to consider here is that while this ACL was ordered correctly, that may not always happen. Some third-party tools, and even builtin tools used incorrectly, may order the ACL incorrectly. In that case you may get some very strange results. If you use such tools, it is best to verify the ACL with the regular Windows ACL editor, also known as ACL UI. If the ACL is ordered incorrectly you will get an error stating this. You can also verify the ACL using icacls.exe command line tool with the /verify switch.

One very important thing to understand is the difference between an empty DACL and a NULL DACL.

  • An empty DACL is an ACL that has no ACEs in it. Remember that an ACE grants a subject permissions to an object. In other words, if a DACL is empty, nobody has been granted permissions.

  • A NULL DACL, on the other hand, is an object without a DACL. This is a very different thing from an empty DACL. An object that does not have a DACL at all has not been secured! This means the object is accessible to everyone. Many people have been told that the semantics of NULL DACLs were going to change in Windows Vista, and that they were going to be interpreted the same way as an empty DACL. This is not correct. Our testing shows that a NULL DACL is interpreted exactly the same way it always has been-as leaving the object without protection. In normal operations it is very rare to find a NULL DACL, at least on common objects. In order to create one a developer has to deliberately set one, which is usually done by misunderstanding how the APIs work. One of the more notable examples of a NULL DACL in the past several years was set on several data files by Microsoft's Age of Mythology game. In Windows XP, the ACL UI would present a NULL DACL as having Everyone Full Control, which is the effective equivalent. In Windows Vista ACL UI has been updated to actually show what really is going on, as shown in Figure 1.

Image from book
Figure 1: A NULL DACL means that the object has not been secured.

  •  Silverlight Tools: XML Editors
  •  Algorithms for Compiler Design: STACK ALLOCATION
  •  Algorithms for Compiler Design: ERROR RECOVERY IN LR PARSING
  •  Algorithms for Compiler Design: PREDICTIVE PARSING ERROR RECOVERY
  •  Algorithms for Compiler Design: LOOP OPTIMIZATION
  •  Algorithms for Compiler Design: ELIMINATING INDUCTION VARIABLES
  •  Algorithms for Compiler Design:
  •  Algorithms for Compiler Design
  •  Algorithms for Compiler Design: THE MACHINE MODEL
  •  Algorithms for Compiler Design: STRAIGHTFORWARD CODE GENERATION
  •  Algorithms for Compiler Design: USING DAG FOR CODE GENERATION
  •  Algorithms for Compiler Design: PEEPHOLE OPTIMIZATION
  •  Algorithms for Compiler Design: L-ATTRIBUTED DEFINITIONS
  •  Algorithms for Compiler Design: SYNTAX-DIRECTED TRANSLATION SCHEMES
    Top 10
    Controlling Access to Files and Folders with NTFS Permissions
    Building Android Apps: Web SQL Database (part 3) - Selecting Rows and Handling Result Sets
    Improving Disk Performance in Vista
    Exchange Server 2010 : Backup and Disaster Recovery Planning
    Preparing to Install Windows 7 (part 2) - New Install or Upgrade
    SharePoint 2010 : Cataloging the Best Scripts to Automate SharePoint Administration
    The 10 most interesting facts about the telephone
    Windows 7 : Recovering After a Crash or Other Problem (part 1) - Recovering Using Restore Points
    Algorithms for Compiler Design:
    Windows 7 : Using Compression and Encryption (part 3) - Encrypting Files and Folders
    Most View
    Building Android Apps : Controlling the Phone with JavaScript (part 3) - Accelerometer
    Using Windows Phone 7 Technologies : Understanding Orientation and Movement
    Users Complaining Of "Overheating" In New Ipad
    SharePoint 2010 : Implementing Authentication Scenarios
    Getting the Most Out of the Microsoft Outlook Client : Deploying Outlook 2007
    Deploying the Client for Microsoft Exchange Server 2010 : Installing the Outlook Client for Exchange Server
    Windows Server 2008 : Transport-Level Security - Using IPSec Encryption with Windows Server 2008 R2
    BizTalk 2006 : Implementing Dynamic Parallel Orchestrations
    App attack: TV Remotes - Panasonic Viera, LG TV Remote, Media Remote (Sony) & Samsung Remote
    Programming with DirectX : View Transformations
    The Path to Shellcode
    SharePoint 2010 : Performing an In-Place Upgrade of a SharePoint Environment
    Windows System Programming : File Locking
    Parallel Programming with Microsoft .Net : Futures - The Basics
    Windows Azure and ASP.NET : Creating a Windows Azure Project
    IIS 7.0 : Managing Configuration - Delegating Configuration (part 1)
    Windows Server : Designing a Software Update Infrastructure (part 2)
    Working with Computer and User Script Policies in Vista
    Expert computing advice (Part 3) - Using heritage format files & Free Screen Capture Software
    Windows Server 2008 : Configuring and Monitoring Terminal Service Resources