Under Windows, for the purposes of scripting, the security descriptor structure is abstracted by a collection of COM objects. For instance, the Active Directory Service Interfaces (ADSI) have their own collection of COM objects to represent a security descriptor. In the same way, WMI also has its own way to represent the security descriptor structure. In this particular case, WMI uses three classes to represent the security descriptor:
Win32_SecurityDescriptor
Win32_ACE
Win32_Trustee
Note that security descriptors are not dedicated to Windows. Each operating system has its own way of structuring the content of a security descriptor and its own interfaces for manipulating the security descriptor content.
Before looking at classes exposing security information, we will first take a quick look at the security descriptor logical structure, as seen from WMI (see Figure 4.11). This will help us to understand the class purposes.
Figure 4.11: The security descriptor logical structure as seen from WMI.
The security descriptor is made up of several components, which expose properties, which in turn may contain subcomponents. From a WMI point of view, the security descriptor is an SWBemObject object, which is an instance of the Win32_SecurityDescriptor class. Basically, a security descriptor as represented by WMI is made up of four properties, which contain other objects:
Owner: It identifies the owner of the security descriptor. The owner is represented by an instance of the Win32_Trustee class.
Group: It identifies the primary group of the security descriptor. The group is represented by an instance of the Win32_Trustee class. This property contains the SID for the owner's primary group. This information is only used by the POSIX subsystem of Windows and is ignored by other Windows subsystems (i.e., Win32). Therefore, the Group property is only present for compatibility purposes regarding the POSIX applications.
Control: It is a set of bit flags that describes a security descriptor and/ or its components. It is mainly used to determine the presence of the Discretionary ACL (DACL) and the System ACL (SACL) and the effect of the inherited Access Control Entries (ACE) on the security descriptor. We will see in section 4.11.2 ("Deciphering the security descriptor Control Flags") how to decipher this value.
ACL: The Access Control List (ACL) is an array holding Access Control Entries (ACE). An ACE object is represented by an instance of the Win32_ACE class, which defines, on a per user basis, what the user is authorized to do. This is the smallest data element defining the user privileges and permissions of an object.
There are two kinds of ACLs: the Discretionary ACL (DACL) and the System ACL (SACL). The DACL handles access control on objects. The SACL handles the system auditing on objects. To define each privilege and permission for a given user, an ACE has several properties. An ACE is composed of:
Trustee: A trustee is a user, a group, or a computer with access rights to an object (i.e., DomainName\UserName). As for the owner and the group element of the security descriptor, a trustee is represented by an instance of the Win32_Trustee class.
AccessMask: The access mask is a sequence of bits turned ON or OFF to activate specific rights. Note that the bit values are not the same for all securable objects. For instance, the bit sequence defining rights on a file is different from the bit sequence defining rights on an Active Directory object. In section 4.11.4.5 ("Deciphering the ACE AccessMask property"), we will see which bit sequence to use in regard to the secured object.
AceFlags: This entry contains the inheritance control flags. As for the AccessMask, the bit sequence defining the inheritance may vary from one secured object to another. In section 4.11.4.3 ("Deciphering the ACE Flags property"), we will see which bit sequence to use in regard to the managed object.
AceType: The value assigned to this ACE property determines the type of permissions granted for the corresponding access mask (Allowed, Denied, Audit).
GuidObjectType: This property indicates what object class or Active Directory attribute set an ACE refers to. It takes a GUID as a value. Usually, this property is set when referring to an Active Directory Extended Right or to an Active Directory class.
GuidInheritedObjectType: This property specifies the GUID of an object class whose instances will inherit the ACE.
The structural view of the security descriptor is the same for any object in a Windows system (i.e., share or file system objects such as files and folders). However, not all WMI classes representing manageable entities provide an access method to retrieve the security descriptor. The WMI provider capabilities related to a manageable entity and the classes it supports are determinant. For instance, as we will see further in section 4.7.1.1 ("Retrieving file and folder security descriptors with WMI"), the Win32_LogicalFileSecuritySetting class, supported by the WMI Security provider, exposes the GetSecurityDescriptor method to retrieve the security descriptor set on a file or a folder.
Unfortunately, it is not always easy or possible to retrieve a security descriptor from a secured object with WMI. In some cases, a more suitable COM abstraction layer such as ADSI must be used. When doing so, it is important to consider the secured object type to be managed when choosing an access method. For instance, the technique to access a security descriptor on a file or a folder will not necessarily be the same as the technique used to access the security descriptor on a registry key. Here, we totally rely on the COM abstraction layer capabilities (i.e., WMI versus ADSI).
Actually, we must clearly distinguish two things:
The technique for accessing and updating the security descriptor: This relies on the WMI provider and class capabilities. If there is no WMI class method or properties exposing the desired security descriptor, it is possible that another technique not implemented by WMI must be used. In such a case, if ADSI offers some capabilities, we will use it to retrieve the security descriptor from a secured object.
The format of the security descriptor: Once the security descriptor is read, its representation is not always in the form of a Win32_SecurityDescriptor instance. From a WMI perspective, some methods or properties return the security descriptor as a Win32_SecurityDescriptor instance; others return the security descriptor in a raw form (a binary array). If the security descriptor is accessed with ADSI, then its representation will be available in the ADSI object model, which is totally different from the Win32_SecurityDescriptor class representation supported by WMI.
Because we will require help from ADSI, it is important to have a look at the security descriptor representation made by ADSI (Figure 4.12).
Figure 4.12: The security descriptor logical structure as seen from ADSI.
Although the security descriptor structure remains globally the same as the one shown in Figure 4.11, only the names of the components representing a security descriptor with their properties are slightly different. However, the information they contain is identical. Table 4.3 presents a short comparison of the properties exposed by both object models.
Table 4.3: The WMI and ADSI Security Descriptor Exposed Methods and Properties
WMI | ADSI | ||
---|---|---|---|
Win32_SecurityDescriptor | IADsSecurityDescriptor | ||
Properties | Properties | ||
Owner | object:Win32_Trustee | Owner | string |
Group | object:Win32_Trustee | Group | string |
ControlFlags | unit32 | Control | long |
DACL | array of object:Win32_ACE | DiscretionaryACL | object:IADsAccessControlList |
SACL | array of object:Win32_ACE | SystemACL | object: lADsAccessControlList |
N/A | Revision | long | |
Methods | Methods | ||
N/A | CopySecurityDescriptor() | ||
IADsAccessControlList | |||
Properties | Properties | ||
N/A | AdRevision | long | |
AceCount | long | ||
Methods | Methods | ||
N/A | AddAoe (objACE) | ||
RemoveAce (objACE) | |||
CopyAccessList() | |||
(Enumeration) | collection of object:IADsAccessControlEntry |
Win32_ACE | IADsAccessControlEntry | ||
---|---|---|---|
Properties | Properties | ||
Trustee | object:Win32_Trustee | Trustee | string |
AccessMask | unit32 | AccessMask | long |
AceFlags | unit32 | AceFlags | long |
AceType | unit32 | AceType | long |
N/A | Flags | long | |
GUIDObjectType | string | ObjectType | string |
GUIDInheritedObjectType | string | InheritedObjectType | string |
Methods | Methods | ||
N/A | N/A |
As we can see, WMI uses three classes to represent a security descriptor and its components (Win32_SecurityDescriptor, Win32_ACE, and Win32_Trustee). We clearly see in Figure 4.11 and Table 4.3 that WMI does not represent an ACL as an object. WMI represents an ACL as an array containing a series of ACEs exposed by the DACL or SACL properties. On the other hand, ADSI exposes the same information type, but it is organized differently. First, a SecurityDescriptor object (exposed by the IADsSecurityDescriptor ADSI COM interface) represents a security descriptor. Next, the DiscretionaryACL or the SystemACL properties expose the ACL in an AccessControlList object (exposed by the IADsAccessControlList ADSI COM interface), which, in turn, contains a collection of ACEs represented by AccessControlEntry objects (exposed by the IADsAccessControlEntry ADSI COM interface).
The only extra information we get from ADSI is the revision level of the security descriptor and some flags that are turned ON when values are set in the ACE ObjectType and ACE InheritedObjectType properties. In sections 4.11.4.5.3.1 ("Understanding the ACE ObjectType property") and 4.11.4.5.3.2 ("Understanding the ACE InheritedObjectType property"), we will see how to use these properties when working with Active Directory security descriptors.
As mentioned previously, based on the secured object type we access, it is important to determine the access methods available and the security descriptor format associated with the access method. Table 4.4 helps us understand which access method can be used and which security descriptor representation format is obtained, based on the security descriptor origin.
|
It is interesting to note that sometimes it is possible to use both WMI and ADSI to retrieve a security descriptor. For instance, this is the case for a security descriptor from a file or a folder. In some other cases, only WMI or ADSI can be used. This is the case for a security descriptor from a registry key, which only uses an ADSI access method. It is the same for a security descriptor from a CIM repository namespace, which only uses a WMI access method. There is one particular case concerning the Exchange 2000 mailbox security descriptor. We see that we can get the security descriptor by using ADSI, WMI, or Collaboration Data Objects for Exchange Management (CDOEXM). Of course, each technique has its own peculiarities, which must be considered. We will examine this in section 4.7 ("Accessing the security descriptor set on manageable entities").
However, not all access methods retrieve security descriptors in the same format. It makes sense to think that an ADSI access method will retrieve the security descriptor in the ADSI object model and a WMI access method will retrieve the security descriptor in a Win32_SecurityDescriptor instance. However, there are exceptions. For instance, it is possible to retrieve a security descriptor from an Active Directory object with ADSI or with WMI. The ADSI access method will expose the security descriptor in the ADSI object model, while the WMI access method retrieves the security descriptor in binary form. In the latter case, the security descriptor needs to be converted to a structural representation. The conversion of a binary array representing a security descriptor to a Win32_SecurityDescriptor instance is not simple. This may require some advanced programming techniques on top of the Win32 API to decipher the security descriptor. Obviously, we leave the world of scripting to enter the world of API programming. Hopefully, with ADSI, it is possible to convert the binary array to a SecurityDescriptor object. We will see in section 4.9 ("The security descriptor conversion") how to proceed. This means that in some cases, we can access the security descriptor with WMI and manipulate its content with the ADSI object model. Although slightly more complex, this method works well and keeps programming in the space of the scripting world.
Last but not least, not all access methods retrieve all security descriptor properties. As seen before, ADSI shows the revision level of the security descriptor, while WMI does not. Most importantly, the System ACL is also subject to some exceptions. As we can see in Table 4.4, based on the security descriptor origin (file, share, Active Directory, etc.) and the access method used to read the security descriptor, the System ACL is not always available. For instance, this is the case for an Active Directory object retrieved with WMI, where the SystemACL is missing its ADSI representation. The Operating System platform also influences this, since the File System share security descriptor ADSI access method is not available under Windows 2000 or any earlier platforms.