新进化论

道生一,一生二,二生三,三生万物。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Access Control Lists (ACL; rhymes with "cackle") are used in two ways in Windows security. One type of ACL is designed to gate access, and the other is designed to audit access. The structure is the same in both cases, but the semantics of how the ACL is used differs. I'll focus first on ACLs that gate access, and then discuss how ACLs used for auditing differ. If you've read my discussion of security descriptors in WhatIsASecurityDescriptor, you'll recognize where these two types of ACLs are found. The DACL in a security descriptor is used to gate access whereas the SACL is used for auditing.

Figure 43.1 Logical structure of an Access Control List

The basic structure of an ACL is shown in Figure 43.1. Each record in it is called an Access Control Entry, or ACE, and includes the SID (WhatIsASID) of a single user or group along with a 32-bit access mask that specifies the permissions being granted, denied, or audited. Each entry also includes a set of flags used to determine how it participates in ACL inheritance, if at all. Inheritance applies to hierarchical systems such as the file system, registry, and directory service, and I'll talk more about it in WhatIsACLInheritance. Before you read about inheritance, however, make sure you understand the basics in this item first.

Imagine a DACL on a file. Let's give it an ACE that grants access to a group, say Engineers. This is a "positive" ACE—it grants permissions. Let's also add an ACE that denies access to some users, say Contractors. This is a "negative" ACE—it denies permissions. Assuming the Engineers group might include some contractors, this is an easy way to say, "All engineers except contractors are granted access." Figure 43.2 shows how this is represented in an ACL (I'm going to be omitting ACL headers in these diagrams for clarity).

Figure 43.2 All engineers except contractors are granted permissions 0x1FF

Note the order of the ACL in Figure 43.2. Order is important because, when performing an access check, the kernel evaluates the ACL from top to bottom and stops as soon as access is either fully granted or even partially denied. Not all ACEs are necessarily evaluated. For example, if a user who is both an engineer and a contractor attempts to open this file for permissions 1 and 3, only the first ACE needs to be evaluated to discover that the user should be denied access. In this case the kernel stops evaluating the ACL and denies access access immediately after evaluating the first ACE. If the ACL is ordered the other way, with the positive ACE first, the kernel evaluates the first ACE, sees that all permissions requested have been granted by that ACE, and stops evaluation, granting access immediately. So let me state the rule the kernel follows. When performing access checks, ACEs are evaluated in order, from top to bottom, until either all requested permissions are granted or one or more requested permissions are denied.

As long as you use the built-in ACL editor in the Windows user interface, you’re assured that deny ACEs will take precedence over grants because the editor puts them first in the ACL. This means that you should use negative ACEs to surgically remove a subset of users from a grant, not the other way around. For example, it's easy to construct an ACL that says, "All authenticated users except Bob should be granted Read permission." Imagine what that ACL would look like: The first ACE would deny Read permission to Bob, and the second would grant read permission to Authenticated Users. Very natural. But just for kicks, consider the opposite policy: "All authenticated users except Bob should be denied read permission." In this case, we want to deny a large set of users and grant permissions to a small subset (well, Bob).

Let me say right up front that this scenario isn't supported by the built-in ACL editor. Technically the kernel supports this scenario if you’re willing to manually construct an ACL in reverse order, so that the positive ACE comes before the negative one. Think about it for a minute and you'll see that this will work. If Bob requests Read permission, the kernel evaluates the first ACE, sees that he's been granted all the permissions he requested, and stops evaluating the ACL. For any authenticated user other than Bob, the kernel continues to the second ACE and denies access at that point. Once again, while the kernel supports this ordering, the user interface doesn’t (the built-in ACL editor always puts negative entries at the top), so unless you're going to write your own ACL editor, I advise you to keep things simple by using negative entries to exclude smaller subsets from larger permission grants. In other words, use deny entries carefully, like you use salt when cooking.

An ACL with negative ACEs can be tricky to get right. Throw ACL inheritance (discussed in WhatIsACLInheritance) into the mix and things can get confusing really fast. You should test these tricky scenarios to make sure you've actually achieved the semantics you want!

Figure 43.3 The "summary" view of a DACL

One last note on ACL order. Don't let the ACL editor's main page fool you—it’s just a condensed summary of permissions in the DACL for an object (see Figure 43.3). First of all, it doesn't attempt to show the detailed permissions being granted. Rather, it condenses permissions into generic categories like "Read", "Modify", "Full Control". Sometimes permissions don't fit nicely into these categories. I've even seen cases on older systems where an entry on the summary page didn't have any permissions checked at all! But what's often even more confusing is that the condensed entries are shown in alphabetical order. If you really want to see what the DACL looks like, you should press the Advanced button to get a more detailed dialog.

Figure 43.4 The "advanced" view of the same DACL

Figure 43.4 shows the "Advanced…" dialog from Windows Server 2003 (it looks a little different on Windows XP). This dialog provides access to the other properties of the security descriptor (WhatIsASecurityDescriptor) besides the DACL, and it provides a much more precise view of the DACL itself. Note that each entry is shown, and you can see how the entries are actually ordered in the ACL (of course, if you press any of the sort buttons at the top of the list to sort by type, name, and so on, you'll have to close the window and reopen it to see the real, physical order again). Compare this with the summary page in Figure 43.3. When I really care about an ACL, I come to this page to look at it.

Each ACE contains a set of permissions. Permissions are represented as bits in a 32-bit binary mask, sometimes referred to as an "access mask." So, if an ACE contains a mask of 0x00000003, it’s talking about permissions 1 and 2. Depending on the type of ACE, this may be a permission grant, deny, or audit. The layout of the permission mask is interesting enough to warrant its own separate topic, and you can read more about it in WhatIsAPermission.

Note that the ACL editor does its best to provide a human-readable description of the access mask. For example, in Figure 43.4 the first positive entry grants Bob a single permission, "Read Attributes." This is easy to name. Similarly the next entry grants all permissions, or "Full Control." The last entry grants special permissions that are commonly granted as a set, "Read & Execute". These permissions are all you’ll see on the summary page (Figure 43.3), which is another reason I recommend drilling into the "Advanced…" dialog when you want more than just a trivial view of a DACL. Sometimes you'll see the editor refer to "Special Permissions." There's really nothing special going on here; it's just that the editor doesn't have a stock way of representing a particular combination of permissions. This often happens in the summary page, which has very few named permission sets—typically "Full Control," "Read," "Write," and the like.

There are three different types of ACEs: permission grants, denials, and audits. DACLs contain only grants and denials, whereas SACLs contain only audits . Because the most commonly used part of a security descriptor (WhatIsASecurityDescriptor) is the DACL, that's what is summarized on the main page of the built-in ACL editor. To see the owner and SACL, you'll need to head back to the "Advanced…" view, shown in Figure 43.4. Note the tabs for Owner and Auditing. In case you were wondering about the last tab, Effective Permissions, that's just a worksheet that lets you enter an account name. It then calculates the permissions someone with that SID would be granted.

Figure 43.5 Peering into a SACL

Let's take a look at the SACL now, which specifies the audit policy for an object. Each ACE in the SACL indicates a condition under which an audit should be generated. We’ll use Figure 43.5 as an example. The first ACE says that if the kernel receives a request to open this object for one or more of the permissions included in the mask 0x1FF, the token used for the request has the Everyone SID, and the request is denied, then an audit should be generated in the security event log. Note that if the request is granted, this ACE is effectively ignored because it only audits failures. However, the second ACE audits both successes and failures. So if someone who is a member of Contractors tries to open the object for either of permissions 1 and 2, regardless of whether the request is granted or denied, an audit is generated. (If you're wondering what I mean by "permissions 1 and 2", check out WhatIsAPermission.)

The SACL can be ordered however you like, because there are no "negative" ACEs in a SACL that can prevent an audit from being generated. ACEs may be inherited, just as in the DACL, which eases the management of large hierarchical systems (WhatIsACLInheritance). Also note that there's a switch you need to flip in security policy before the system even bothers looking at SACLs and generating audits. You must enable auditing of "object access" (HowToEnableAuditing). With this switch you must choose whether you want to generate success or failure audits, or both.

There's one other important thing you should know about the SACL. Only specially privileged users are allowed to even see it. Look at the difference between the acronyms DACL and SACL. The first is the "discretionary" access control list. The second is the "system" access control list. You see, the SACL is nondiscretionary (WhatIsDiscretionaryAccessControl). Even the owner of an object (WhatIsOwnership) has no special rights to it! The only principals allowed to read and write the SACL of any object are those who have been granted SeSecurityPrivilege, the idea being that security officers should be the only ones who control (or even know) what's being audited in a system. This privilege is granted to the Administrators local group by default, so in practice, unless you're running with admin privileges, you won't be allowed to modify or even look at the auditing settings for any objects in the system. Thus, if you bring up the “Advanced…” dialog and don't see the Auditing tab, don't worry that something is broken; you're probably just not running as an administrator. Good for you!

posted on 2009-10-26 14:17  岌岌可危  阅读(497)  评论(0编辑  收藏  举报