Editor's Note: This article is the 10th part of a 12-part series about Active Directory Service Interfaces (ADSI). The series started in the January 1999 issue. Refer to previous installments for definitions and background information.

Controlling permissions in the Windows 2000 (Win2K) Active Directory (AD) is crucial to your network's security. Although you might not care if everyone can access your users' telephone numbers, you might want to restrict access to more sensitive information. In addition, you might need to create, modify, or delete privileges to prevent malevolent or mischievous employees from, for example, deleting all the users in an organizational unit (OU) in the AD store.

Auditing permission modifications is just as crucial to your network's security. In Win2K, auditing is a process in which the system logs AD events in the Security event log on a particular domain controller. Thus, you can monitor any modification to the AD store, including modifications to permissions.

This month and next, I discuss how to control permissions and audit permission modifications in the AD store. This month, I discuss the basic concepts of how AD implements permissions and how to create an access control entry (ACE). Next month, I'll concentrate on how to write scripts that automate permissions and auditing tasks.

How AD Implements Permissions
Before you can write scripts that control and audit permissions, you need to understand how AD implements permissions. As Figure 1 shows, the process begins with each AD object storing a binary value called a Security Descriptor (SD). The SD holds all the security information for that object, which includes ownership data (i.e., data about the user or group who owns the object) and two ACLs. One ACL is called the System Access Control List (SACL); the other is called the discretionary access control list (DACL). Each ACL consists of a collection of ACEs.

DACL is a collection of ACEs for permissions purposes. DACL ACEs define the users and groups that can access and manipulate an object, its properties, and its children. ACEs can apply to the object as a whole or to the individual properties of the object. For example, you can grant all users read access to the telephone number and email properties for all User objects, but grant users write access to only their individual User object's personal properties (e.g., telephone number, mailing address). Only the objects and their corresponding properties limit the possibilities. Because the AD schema is extensible, you can allow or deny organization-specific permissions for all the objects and properties that your organization creates.

SACL is a collection of ACEs for audit purposes. SACL ACEs define the permission modifications that trigger the system to log an AD event in the Security event log. You can use the SACL ACEs to monitor the creation, modification, or deletion of any object in the AD store and therefore help you track security problems. For example, suppose several new users in a large OU are experiencing problems accessing and modifying their telephone numbers and mailing addresses in the AD store. Because of the unit's size, four administrators have write access to the User objects' SDs. To determine which administrators are incorrectly setting permissions for the new users, you can monitor those administrators' creations, changes, and deletions to the SDs of User objects in that OU.

You can also use SACL ACEs to help you identify unusual system behavior. For example, suppose one morning your users report that the system is slow, but when you check the system, it seems fine. That afternoon, the users report the same problem. Again you check the system and find no problem. The next morning the same situation arises, but this time you experience the slowdown while logging on to AD. Almost as soon as the slowdown starts, the problem goes away. You decide to run the Performance Monitor continuously.

That afternoon, the system again slows down, so you check the Performance Monitor. You find a tremendous amount of creation and deletions occurring. Then, after exactly 5 minutes, the activity stops. Exactly 6 hours later, the same event occurs, which leads you to believe that a process somewhere is operating incorrectly. To find out, you can simply set the appropriate SACL ACEs, switch on Auditing, and record the problems.

How to Create an ACE
Because the ACE is the basic building block in the SD, the most elementary operation in setting permissions and in auditing is creating a new ACE for an object. When you know how to create an ACE, you can perform other tasks, such as changing an existing ACE and adding an ACE to an ACL.

Probably the hardest part of creating an ACE is learning the names of the ACE object's properties. Because Microsoft has the habit of calling a spade a ground insertion earth-management device, the roles of ACE object properties aren't immediately obvious from their names. In addition, although Microsoft uses the same ACE object for both SACL and DACL, several property values aren't interchangeable. Some property values make sense for only SACL, and other property values make sense for only DACL. To complicate matters further, one property (AceFlags) is a catchall area that holds two sets of completely different values.

To set up an ACE, you need to set several properties:

  1. AceType. You use the AceType property to specify whether you're allowing permission, denying permission, or auditing an object or property.
  2. Trustee. You use the Trustee property to specify to whom the permission applies or whom you're auditing.
  3. AccessMask. You use the AccessMask property to specify which permissions you want to set. For example, you can give permission to read or write a property or create or delete an object. You can even give full control. For a DACL ACE, full control means you're granting every permission. For a SACL ACE, full control means you're auditing every action.
  4. AceFlags. You use the AceFlags property to specify the inheritance options you want. You decide whether the ACE applies to the object containing the ACE, child objects, or objects below those child objects. If you're auditing an object or property, you also use the AceFlags property to specify whether you're monitoring successes or failures.
  5. Flags, ObjectType, and InheritedObjectType. You use these three properties to specify what the ACE applies to if it's not the entire object.

Permission schemes can be complex, and the ACEs must be able to handle those complexities. Giving a user full control over an OrganizationalUnit object is quite different from giving that user the ability to set the password for User objects within and below a branch that is beneath an OrganizationalUnit object. The following examples show how ACEs are simple to use yet can store complex permissions.

Let's start with setting up a simple permission. Suppose you want to create an ACE that allows a user every permission for an OrganizationalUnit object. Here are the properties that you set:

  • AceType: Allow permission
  • Trustee: The name of the user you're granting permission to
  • AccessMask: Full control
  • AceFlags: Permission applies to this object; child objects inherit this ACE
  • Flags: ObjectType and InheritedObjectType not set
  • ObjectType: Null
  • InheritedObjectType: Null

With these settings, you're allowing (AceType) the user (Trustee) full control (AccessMask) to the object and all objects down the tree (AceFlags). You don't need to set the last three properties (Flags, ObjectType, and InheritedObjectType) because permission applies to the entire object. AD stores this information as an ACE on the OrganizationalUnit object's SD.

Suppose you also want to audit that user's successful and failed modifications to the OrganizationalUnit object. In this case, the contents of the ACE on the OrganizationalUnit object's SD are

  • AceType: Audit
  • Trustee: The name of the user you're auditing
  • AccessMask: Full control
  • AceFlags: Inherited only (i.e., doesn't apply to this object); child objects inherit; audits successes and failures
  • Flags: ObjectType and InheritedObjectType not set
  • ObjectType: Null
  • InheritedObjectType: Null

With these settings, you're auditing (AceType) the user's (Trustee) successful and failed (AceFlags) modifications of all types (AccessMask) to this object and all children (AceFlags). Comparing this auditing example with the previous permission example calls attention to an important difference between creating DACL ACEs and SACL ACEs. For DACL ACEs, you use AceType to specify whether you're granting or denying permissions. For SACL ACEs, you use AceFlags to specify whether you're auditing successes or failures.

Now let's create more complex DACL and SACL ACEs. Suppose you want to give a user the ability to set the password for User objects within and below a branch that is beneath an OrganizationalUnit object. Although the permission doesn't apply to the OrganizationalUnit object, you still set up this ACE on the OrganizationalUnit object's SD because the OrganizationalUnit object acts as a carrier for this ACE. In other words, all containers below the OrganizationalUnit object inherit the ACE. When you create a user in one of these containers, AD automatically adds the ACE to the User object's SD via inheritance rules.

Here are the ACE properties that you set:

  • AceType: Allow permission
  • Trustee: The name of the user you're granting permission to
  • AccessMask: Write access to a specific property
  • AceFlags: Inherited only (i.e., doesn't apply to this object); child objects inherit
  • Flags: ObjectType and InheritedObjectType set
  • ObjectType: Globally unique ID (GUID) of the User Password attribute
  • InheritedObjectType: GUID of the User class

With these settings, you're allowing (AceType) the user (Trustee) write access (AccessMask) to a specific attribute of a specific object class (Access Mask and Flags), namely the password (ObjectType) of User objects (InheritedObjectType). The ACE doesn't apply to the object (AceFlags), so that object is acting as only a propagator of the ACE down the tree (AceFlags).

Suppose you want to audit that user's successful and failed modifications to the passwords of User objects within and below the branch beneath the OrganizationalUnit object. Once again, you set up this ACE on the OrganizationalUnit object's SD, even though the permission doesn't apply to that object. The contents of this more complex SACL ACE are

  • AceType: Audit
  • Trustee: The name of the user you're auditing
  • AccessMask: Write access to a specific property
  • AceFlags: Inherited only (i.e., doesn't apply to this object); child objects inherit; audits successes and failures
  • Flags: ObjectType and InheritedObjectType set
  • ObjectType: GUID of the User Password attribute
  • InheritedObjectType: GUID of the User class

With these settings, you're auditing (AceType) a user's (Trustee) successful and failed (AceFlags) write access modifications (AccessMask) to a specific attribute of a specific object class (Access Mask and Flags), namely the password (ObjectType) of User objects (InheritedObjectType). The ACE doesn't apply to the object it's on (AceFlags), so that object is acting as only a propagator of the ACE down the tree (AceFlags).

Using ADSI to Manipulate ACEs
As you can see, creating an ACE is simple. And although most of the permissions and auditing tasks are simple, they can become cumbersome if you must perform them many times. Fortunately, you can easily manipulate SDs, ACLs, and ACEs with ADSI, so you can perform these repetitive tasks with scripts.

ADSI provides three main security interfaces to manipulate SDs, ACLs, and ACEs:

  • IADsAccessControlEntry—interface for manipulating individual ACEs
  • IADsAccessControlList—interface for managing collections of ACEs for an object
  • IADsSecurityDescriptor—interface for managing the different sets of ACLs to an object

Next month, I'll discuss how to use these interfaces to set permissions and perform auditing. If you want a sneak preview of what these interfaces can do, check out the Microsoft Developer Network's (MSDN's) Web site at http://msdn.microsoft.com/isapi/ msdnlib.idc?theurl=/library/sdkdoc/adsi/if_sec_5g6r.htm.

This article is adapted from Alistair G. Lowe-Norris' forthcoming book Windows 2000 Active Directory (O'Reilly and Associates).