Author: NetworkAdminKB.com
Created: 2009-04-20
Modified: 2009-05-13
Information:
In How to read a SDDL string we broke apart the complete Security Descriptor Definition Language (SDDL) string into its various parts and showed you how to interpret the various settings within the SDDL string.
In this article we will break down the ACE_String portion of the SDDL format and show how permissions are configured to secure a variety of objects. As you will see later, one of the key components of the SDDL format is that it can be used to apply security to any object in Windows Operating System that implements a standard 32 bit access mask (bits number 0 – 31).
SDDL Format Overview
To review the four basic parts of the SDDL format are:
O:owner_sid
G:group_sid
D:dacl_flags(ace_string1)( ace_string1)... (ace_stringN)
S:sacl_flags(ace_string1)( ace_string1)... (ace_stringN)
In general unneeded components can be omitted from the security descriptor string. However, it is possible that some objects require specific parts of the SDDL be included. If this is the case the designer should implement the SECURITY_INFORMATION bit flags to indicate the components to include in a security descriptor string.
Therefore, a complete SDDL string may look like this (one line, formatted for appearance)
D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)
(A;;KA;;;S-1-5-21-1234565538-1234563583-123456993-1234)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)
In the above example only the D: and S: parts are implemented. Another example may look like this.
O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0005;;;SY)(A;;0x5;;;BA)
In this example the O:, G: and D: parts are implemented.
ACE_String Format
As defined above the ACE_String format can be used in the SDDL string in both the D: (DACL) and the S: (SACL) sections. A separate ACE_String is needed for each user or group object that you are applying permissions for and each individual ACE_String is place inside a set of parentheses.
The parts of an ACE_String are shown below
(ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid)
The part of the ACE_String that we will be discussing more in-depth is the rights section. However, the following two parts will need to be understood as well.
ace_type
A string that corresponds to the AceType Value that is required in the ACE_HEADER (winnt.h) programming structure. The ace_type string can be one of the following strings defined in Sddl.h.
|
ace_type string |
Constant in Sddl.h |
AceType Value |
|
"A" |
SDDL_ACCESS_ALLOWED |
ACCESS_ALLOWED_ACE_TYPE |
|
"D" |
SDDL_ACCESS_DENIED |
ACCESS_DENIED_ACE_TYPE |
|
"OA" |
SDDL_OBJECT_ACCESS_ALLOWED |
ACCESS_ALLOWED_OBJECT_ACE_TYPE |
|
"OD" |
SDDL_OBJECT_ACCESS_DENIED |
ACCESS_DENIED_OBJECT_ACE_TYPE |
|
"AU" |
SDDL_AUDIT |
SYSTEM_AUDIT_ACE_TYPE |
|
"AL" |
SDDL_ALARM |
SYSTEM_ALARM_ACE_TYPE |
|
"OU" |
SDDL_OBJECT_AUDIT |
SYSTEM_AUDIT_OBJECT_ACE_TYPE |
|
"OL" |
SDDL_OBJECT_ALARM |
SYSTEM_ALARM_OBJECT_ACE_TYPE |
|
"ML" |
SDDL_MANDATORY_LABEL |
SYSTEM_MANDATORY_LABEL_ACE |
The rights section of the ACE_String requires the “A” (Allow) or “D” (Deny) ace_type string.
ace_flags
A string that corresponds to the AceFlag Value that is required in the ACE_HEADER (winnt.h) programming structure. The ace_flags string can be a concatenation of the following strings defined in Sddl.h.
|
ace_flags string |
Constant in Sddl.h |
AceFlag Value |
|
"CI" |
SDDL_CONTAINER_INHERIT |
CONTAINER_INHERIT_ACE |
|
"OI" |
SDDL_OBJECT_INHERIT |
OBJECT_INHERIT_ACE |
|
"NP" |
SDDL_NO_PROPAGATE |
NO_PROPAGATE_INHERIT_ACE |
|
"IO" |
SDDL_INHERIT_ONLY |
INHERIT_ONLY_ACE |
|
"ID" |
SDDL_INHERITED |
INHERITED_ACE |
|
"SA" |
SDDL_AUDIT_SUCCESS |
SUCCESSFUL_ACCESS_ACE_FLAG |
|
"FA" |
SDDL_AUDIT_FAILURE |
FAILED_ACCESS_ACE_FLAG |
rights
A string that corresponds to the Access Right this is required by the ACE (winnt.h) programming structure. This string can be a hexadecimal string representation of the access rights, such as 0xF003F, or it can be a concatenation of the following SDDL abbreviated (SDDL Abbr) strings located in the tables found later in the document.
The complete rights string (e.g. CCLCRPRC) corresponds to an access mask that is then used by the ACE programming structure to implement the security. The access mask is a 32-bit value whose individual bits correspond to the specific access rights supported by an object. All Windows securable objects use the access mask format that is shown in the following illustration.

In this format, the low-order 16 bits are for object-specific access rights, the next 8 bits are for standard access rights, which apply to most types of objects, and the 4 high-order bits are used to specify generic access rights that each object type can map to a set of standard and object-specific rights. The ACCESS_SYSTEM_SECURITY (AS) bit corresponds to the right to access the object's SACL.
What all the above technical explanation really means is that SDDL has mapped specific Strings (CC, DC, LC, etc) to the same Hexadecimal values (bits) used by all objects. Thus, rights string values like CC, DC, LC, etc. are used on different objects to represent different access, but always represent the same Hex value (or bit) in the access mask.
To help administrators the designers of the access mask included Standard and Generic combinations (see Common Combinations table below) for Read, Write, Execute, and All. This allows administrators to easily assign these basic “administrative concepts” to diverse objects without needing to worry about the individual rights that make up those combinations. For example, to apply Read access to any object simply enter “GR” in the rights section of the ACE string, or to grant All access (Full Control) simply enter “GA” in the rights section of the ACE string.
Thus, the following are all equivalent values for the rights string to grant GENERIC_ALL access to the SC Manager object.
|
Equivalent rights string
or Hex Value |
Description |
|
GA |
GENERIC_ALL rights string |
|
0x10000000 |
The HEX equivalent of GENERIC_ALL |
|
CCDCLCSWRPWPSDRCWDWO |
The individual rights strings that GENERIC_ALL represent |
|
0xF003F |
The HEX equivalent of the individual rights strings |
In the following tables I have taken four of the object types that SDDL is commonly applied too and shown how their rights correspond to the ACE_String rights string and their corresponding Hex and Bit values. From these tables you should be able to gain a better understanding of the rights string format and how to apply this knowledge to other object types.
Note: The File object (not in tables) and Registry objects appear to have object specific rights strings. For example the Registry object has KA, KX, KR and KW defined. These are really just another name for the same Generic Rights strings GA, GX, GR and GW respectively. You can use either rights string to apply these permissions. Review the Access Rights for the Registry in the table below for more information.
|
Rights Scope |
Bits |
Hex Value |
SDDL Abbr |
Common Rights Name |
Access Rights for the
SC Manager |
Access Rights for
Services |
|
Object Specific |
0 |
0x00000001 |
CC |
|
SC_MANAGER_CONNECT Connect to service controller |
SERVICE_QUERY_CONFIG Query service configuration information |
|
Object Specific |
1 |
0x00000002 |
DC |
|
SC_MANAGER_CREATE_SERVICE Create a new service |
SERVICE_CHANGE_CONFIG Set service configuration information |
|
Object Specific |
2 |
0x00000004 |
LC |
|
SC_MANAGER_ENUMERATE_SERVICE Enumerate services |
SERVICE_QUERY_STATUS Query status of service |
|
Object Specific |
3 |
0x00000008 |
SW |
|
SC_MANAGER_LOCK Lock service database for exclusive access |
SERVICE_ENUMERATE_DEPENDENTS Enumerate dependencies of service |
|
Object Specific |
4 |
0x00000010 |
RP |
|
SC_MANAGER_QUERY_LOCK_STATUS Query service database lock state (RP) |
SERVICE_START Start the service |
|
Object Specific |
5 |
0x00000020 |
WP |
|
SC_MANAGER_MODIFY_BOOT_CONFIG Set last-known-good state of service database |
SERVICE_STOP Stop the service |
|
Object Specific |
6 |
0x00000040 |
DT |
|
|
SERVICE_PAUSE_CONTINUE Pause or continue the service |
|
Object Specific |
7 |
0x00000080 |
LO |
|
|
SERVICE_INTERROGATE Query information from service |
|
Object Specific |
8 |
0x00000100 |
CR |
|
|
SERVICE_USER_DEFINED_CONTROL Issue service-specific control commands |
|
Object Specific |
9 |
0x00000200 |
|
|
|
|
|
Object Specific |
10 |
0x00000400 |
|
|
|
|
|
Object Specific |
11 |
0x00000800 |
|
|
|
|
|
Object Specific |
12 |
0x00001000 |
|
|
|
|
|
Object Specific |
13 |
0x00002000 |
|
|
|
|
|
Object Specific |
14 |
0x00004000 |
|
|
|
|
|
Object Specific |
15 |
0x00008000 |
|
|
|
|
|
Standard |
16 |
0x00010000 |
SD |
DELETE |
|
|
|
Standard |
17 |
0x00020000 |
RC |
READ_CONTROL |
|
|
|
Standard |
18 |
0x00040000 |
WD |
WRITE_DAC |
|
|
|
Standard |
19 |
0x00080000 |
WO |
WRITE_OWNER |
|
|
|
Standard |
20 |
0x00100000 |
|
SYNCHRONIZE |
|
|
|
Standard |
21 |
0x00200000 |
|
|
|
|
|
Standard |
22 |
0x00400000 |
|
|
|
|
|
Standard |
23 |
0x00800000 |
|
|
|
|
|
Access SACL |
24 |
0x01000000 |
AS |
ACCESS_SYSTEM
_SECURITY |
|
|
|
Reserved |
25 |
0x02000000 |
|
|
|
|
|
Reserved |
26 |
0x04000000 |
|
|
|
|
|
Reserved |
27 |
0x08000000 |
|
|
|
|
|
Generic |
28 |
0x10000000 |
GA |
GENERIC_ALL |
SC_MANAGER_ALL_ACCESS (0xF003F): STANDARD_RIGHTS_REQUIRED plus all other SC_MANAGER rights. |
SERVICE_ALL_ACCESS (0xF01FF): STANDARD_RIGHTS_REQUIRED plus all other SERVICE rights |
|
Generic |
29 |
0x20000000 |
GX |
GENERIC_EXECUTE |
(0x20009): STANDARD_RIGHTS_EXECUTE SC_MANAGER_CONNECT SC_MANAGER_LOCK |
(0x20170): STANDARD_RIGHTS_EXECUTE SERVICE_START SERVICE_STOP SERVICE_PAUSE_CONTINUE SERVICE_USER_DEFINED_CONTROL |
|
Generic |
30 |
0x40000000 |
GW |
GENERIC_WRITE |
(0x20022): STANDARD_RIGHTS_WRITE SC_MANAGER_CREATE_SERVICE SC_MANAGER_MODIFY_BOOT_CONFIG |
(0x20002): STANDARD_RIGHTS_WRITE SERVICE_CHANGE_CONFIG |
|
Generic |
31 |
0x80000000 |
GR |
GENERIC_READ |
(0x20014): STANDARD_RIGHTS_READ SC_MANAGER_ENUMERATE_SERVICE SC_MANAGER_QUERY_LOCK_STATUS |
(0x2008D): STANDARD_RIGHTS_READ SERVICE_QUERY_CONFIG SERVICE_QUERY_STATUS SERVICE_INTERROGATE SERVICE_ENUMERATE_DEPENDENTS |
|
Access Rights and Masks |
|
Generic Access Rights |
Service Access Rights |
Service Access Rights |
|
Rights Scope |
Bits |
Hex Value |
SDDL Abbr |
Common Rights Name |
Access Rights for the
Directory Service |
Access Rights for the
Registry |
|
Object Specific |
0 |
0x00000001 |
CC |
|
ADS_RIGHT_DS_CREATE_CHILD |
KEY_QUERY_VALUE |
|
Object Specific |
1 |
0x00000002 |
DC |
|
ADS_RIGHT_DS_DELETE_CHILD |
KEY_SET_VALUE |
|
Object Specific |
2 |
0x00000004 |
LC |
|
ADS_RIGHT_ACTRL_DS_LIST |
KEY_CREATE_SUB_KEY |
|
Object Specific |
3 |
0x00000008 |
SW |
|
ADS_RIGHT_DS_SELF |
KEY_ENUMERATE_SUB_KEYS |
|
Object Specific |
4 |
0x00000010 |
RP |
|
ADS_RIGHT_DS_READ_PROP |
KEY_NOTIFY |
|
Object Specific |
5 |
0x00000020 |
WP |
|
ADS_RIGHT_DS_WRITE_PROP |
KEY_CREATE_LINK |
|
Object Specific |
6 |
0x00000040 |
DT |
|
ADS_RIGHT_DS_DELETE_TREE |
|
|
Object Specific |
7 |
0x00000080 |
LO |
|
ADS_RIGHT_DS_LIST_OBJECT |
|
|
Object Specific |
8 |
0x00000100 |
CR |
|
ADS_RIGHT_DS_CONTROL_ACCESS |
KEY_WOW64_64KEY |
|
Object Specific |
9 |
0x00000200 |
|
|
|
KEY_WOW64_32KEY |
|
Table Truncated To Remove Unneeded Rows |
|
Generic |
28 |
0x10000000 |
GA |
GENERIC_ALL |
DS_GENERIC_ALL (0xF003F): STANDARD_RIGHTS_REQUIRED plus all other ADS_RIGHT rights |
KEY_ALL_ACCESS [KA] (0xF003F): STANDARD_RIGHTS_REQUIRED KEY_QUERY_VALUE KEY_SET_VALUE KEY_CREATE_SUB_KEY KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY KEY_CREATE_LINK |
|
Generic |
29 |
0x20000000 |
GX |
GENERIC_EXECUTE |
DS_GENERIC_EXECUTE (0x20004): STANDARD_RIGHTS_EXECUTE ADS_RIGHT_ACTRL_DS_LIST |
KEY_EXECUTE [KX] (0x20019): STANDARD_RIGHTS_READ KEY_QUERY_VALUE KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY |
|
Generic |
30 |
0x40000000 |
GW |
GENERIC_WRITE |
DS_GENERIC_WRITE (0x20028): STANDARD_RIGHTS_WRITE ADS_RIGHT_DS_SELF ADS_RIGHT_DS_WRITE_PROP |
KEY_WRITE [KW] (0x20006): STANDARD_RIGHTS_WRITE KEY_SET_VALUE KEY_CREATE_SUB_KEY |
|
Generic |
31 |
0x80000000 |
GR |
GENERIC_READ |
DS_GENERIC_READ (0x20094): STANDARD_RIGHTS_READ ADS_RIGHT_ACTRL_DS_LIST ADS_RIGHT_DS_READ_PROP ADS_RIGHT_DS_LIST_OBJECT |
KEY_READ [KR] (0x20019): STANDARD_RIGHTS_READ KEY_QUERY_VALUE KEY_ENUMERATE_SUB_KEYS KEY_NOTIFY |
|
Access Rights and Masks |
|
Generic Access Rights |
ADS Rights Enumeration |
Registry Access Rights |
|
Common Combinations |
Combined Rights |
|
STANDARD_RIGHTS_ALL (0x1F0000): |
Combines DELETE, READ_CONTROL, WRITE_DAC, WRITE_OWNER, and SYNCHRONIZE access. |
|
STANDARD_RIGHTS_EXECUTE (0x20000): |
Currently defined to equal READ_CONTROL. |
|
STANDARD_RIGHTS_READ (0x20000): |
Currently defined to equal READ_CONTROL. |
|
STANDARD_RIGHTS_REQUIRED (0xF0000): |
Combines DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER access. |
|
STANDARD_RIGHTS_WRITE (0x20000): |
Currently defined to equal READ_CONTROL. |
|
GENERIC_READ: |
Object specific combination |
|
GENERIC_WRITE: |
Object specific combination |
|
GENERIC_EXECUTE: |
Object specific combination |
|
GENERIC_ALL: |
Object specific combination |
You may notice that not every bit has a corresponding rights string or a Common Rights Name and it appears that some bits are not used at all. This is by design. While the justification for this may vary the general premise is that the original design was done to allow growth and Microsoft has not fully utilized this access mask yet.
Some of the objects implement specific names (constants) for one or more of the Generic access types. For example the SC Manager implements SC_MANAGER_ALL_ACCESS as a constant that represents the 0xF003F value. In other cases names (constants) are not implemented for the Generic access types. The Generic access type constant name is provided if known just prior to the Hex value it would represent. Actually all the names in the Access Rights for and Common Rights Name columns and are constants used in programming.
At the bottom of each column is a link for access to more information on the MSDN web site.
While there are other parts to the ACE_String to discuss I will leave that for your own research on the MSDN web site. The focus of this article was to demonstrate how the rights string used in the SDDL string can be used and understood by the Network Administrators that may need to deal with them in their daily job.
More Information:
MSDN - ACE String Format
Definitions:
A bit is a binary digit, taking a logical value of either "1" or "0" (also referred to as "true" or "false" respectively).
An Access Mask (bit mask) is a collection of bits that are usually represented by binary number (ie: 100100). The individual bits (true, false) settings are then logically assigned meanings, in this case a type of access. Taken as a whole the bits can then easily be represented by actual numbers after you convert them from Binary to Decimal or Hexadecimal. This whole number is then used to represent a collection of permissions. When reading access masks remember they are ordered right to left with the first bit considered the far right, and the last bit being the far left.