Requesting Access Rights to an Object
When you open a handle to an object, the returned handle has some combination of access rights to the object. Some functions, such as CreateSemaphore(), do not require a specific set of requested access rights. These functions always try to open the handle for full access. Other functions, such as CreateFile() and OpenProcess(), allow you to specify the set of access rights that you want. You should request only the access rights that you need, rather than opening a handle for full access. This prevents using the handle in an unintended way, and increases the chances that the access request will succeed if the object's DACL only allows limited access. You should use generic access rights to specify the type of access needed when opening a handle to an object. This is typically simpler than specifying all the corresponding standard and specific rights. Alternatively, use the MAXIMUM_ALLOWED constant to request that the object be opened with all the access rights that are valid for the caller. Take note that the MAXIMUM_ALLOWED constant cannot be used in an ACE. To get or set the SACL in an object's security descriptor, request the ACCESS_SYSTEM_SECURITY access right when opening a handle to the object.
Null DACLs and Empty DACLs
If the DACL belonging to an object's security descriptor is set to NULL, a null DACL is created. A null DACL grants full access to any user that requests it that is full access for Everyone and normal security checking is not performed with respect to the object (newer Win32 API has fixed this issue). A null DACL should not be confused with an empty DACL. An empty DACL is a properly allocated and initialized DACL containing no ACEs. An empty DACL grants no access to the object it is assigned to.
Allowing Anonymous Access
The default security policy restricts anonymous local access to having no rights. Administrators can then add or subtract rights as they see fit. On Windows NT4 the Anonymous access allows access equal to the access granted to the Everyone group. A local access group exists for applications with the same access rights as Everyone (equivalent to Windows NT anonymous access). Administrators can then appropriately increase or decrease the number of users in that group, named the Pre-Windows 2000-Compatible Access Group.
Security Descriptor Definition Language (SDDL)
The security descriptor definition language (sddl) defines the string format that the ConvertSecurityDescriptorToStringSecurityDescriptor() and ConvertStringSecurityDescriptorToSecurityDescriptor() functions use to describe a security descriptor as a text string. The language also defines string elements for describing information in the components of a security descriptor.
Security Descriptor String Format
The Security Descriptor String Format is a text format for storing or transporting information in a security descriptor as shown in the following example.
O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0) S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)
The ConvertSecurityDescriptorToStringSecurityDescriptor() and ConvertStringSecurityDescriptorToSecurityDescriptor() functions use this format. The format is a null-terminated string with tokens to indicate each of the four main components of a security descriptor:
The format:
The SID description:
Control |
Constant in sddl.h |
Meaning |
P |
SDDL_PROTECTED |
The SE_DACL_PROTECTED flag is set. |
AR |
SDDL_AUTO_INHERIT_REQ |
The SE_DACL_AUTO_INHERIT_REQ flag is set. |
AI |
SDDL_AUTO_INHERITED |
The SE_DACL_AUTO_INHERITED flag is set. |
Table 18 |
Unneeded components can be omitted from the security descriptor string. For example, if the SE_DACL_PRESENT flag is not set in the input security descriptor, ConvertSecurityDescriptorToStringSecurityDescriptor() does not include a D: component in the output string. You can also use the SECURITY_INFORMATION bit flags to indicate the components to include in a security descriptor string. The security descriptor string format does not support NULL ACLs. To denote an empty ACL, the security descriptor string includes the D: or S: token with no additional string information. The security descriptor string stores the SECURITY DESCRIPTOR CONTROL bits in different ways. The SE_DACL_PRESENT or SE_SACL_PRESENT bits are indicated by the presence of the D: or S: token in the string. Other bits that apply to the DACL or SACL are stored in dacl_flags and sacl_flags. The SE_OWNER_DEFAULTED, SE_GROUP_DEFAULTED, SE_DACL_DEFAULTED, and SE_SACL_DEFAULTED bits are not stored in a security descriptor string. The SE_SELF_RELATIVE bit is not stored in the string, but ConvertStringSecurityDescriptorToSecurityDescriptor() always sets this bit in the output security descriptor.
Security Descriptor String Examples
The following examples show security descriptor strings and the information in the associated security descriptors.
String 1 example:
O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)
Security Descriptor 1:
Revision: 0x00000001
Control: 0x0004
SE_DACL_PRESENT
Owner: (S-1-5-32-548)
PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512)
DACL
Revision: 0x02
Size: 0x001c
AceCount: 0x0001
Ace[00]
AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE)
AceSize: 0x0014
InheritFlags: 0x00
Access Mask: 0x100e003f
READ_CONTROL
WRITE_DAC
WRITE_OWNER
GENERIC_ALL
Others(0x0000003f)
Ace Sid : (S-1-0-0)
SACL
Not present
String 2 example:
O:DAG:DAD:(A;;RPWPCCDCLCRCWOWDSDSW;;;SY)(A;;RPWPCCDCLCRCWOWDSDSW;;;DA)(OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO)
(OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;6da8a4ff-0e52-11d0-a286-00aa003049e2;;AO)(OA;;CCDC;bf967aa8-0de6-
11d0-a285-00aa003049e2;;PO)(A;;RPLCRC;;;AU)S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)
Security Descriptor 2:
Revision: 0x00000001
Control: 0x0014
SE_DACL_PRESENT
SE_SACL_PRESENT
Owner: (S-1-5-21-397955417-626881126-188441444-512)
PrimaryGroup: (S-1-5-21-397955417-626881126-188441444-512)
DACL
Revision: 0x04
Size: 0x0104
AceCount: 0x0007
Ace[00]
AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE)
AceSize: 0x0014
InheritFlags: 0x00
Access Mask: 0x000f003f
DELETE
READ_CONTROL
WRITE_DAC
WRITE_OWNER
Others(0x0000003f)
Ace Sid: (S-1-5-18)
Ace[01]
AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE)
AceSize: 0x0024
InheritFlags: 0x00
Access Mask: 0x000f003f
DELETE
READ_CONTROL
WRITE_DAC
WRITE_OWNER
Others(0x0000003f)
Ace Sid: (S-1-5-21-397955417-626881126-188441444-512)
Ace[02]
AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
AceSize: 0x002c
InheritFlags: 0x00
Access Mask: 0x00000003
Others(0x00000003)
Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT
ObjectType: GUID_C_USER
InhObjectType: GUID ptr is NULL
Ace Sid: (S-1-5-32-548)
Ace[03]
AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
AceSize: 0x002c
InheritFlags: 0x00
Access Mask: 0x00000003
Others(0x00000003)
Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT
ObjectType: GUID_C_GROUP
InhObjectType: GUID ptr is NULL
Ace Sid: (S-1-5-32-548)
Ace[04]
AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
AceSize: 0x002c
InheritFlags: 0x00
Access Mask: 0x00000003
Others(0x00000003)
Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT
ObjectType: GUID_C_LOCALGROUP
InhObjectType: GUID ptr is NULL
Ace Sid: (S-1-5-32-548)
Ace[05]
AceType: 0x05 (ACCESS_ALLOWED_OBJECT_ACE_TYPE)
AceSize: 0x002c
InheritFlags: 0x00
Access Mask: 0x00000003
Others(0x00000003)
Flags: 0x00000001, ACE_OBJECT_TYPE_PRESENT
ObjectType: GUID_C_PRINT_QUEUE
InhObjectType: GUID ptr is NULL
Ace Sid: (S-1-5-32-550)
Ace[06]
AceType: 0x00 (ACCESS_ALLOWED_ACE_TYPE)
AceSize: 0x0014
InheritFlags: 0x00
Access Mask: 0x00020014
READ_CONTROL
Others(0x00000014)
Ace Sid: (S-1-5-11)
SACL
Revision: 0x02
Size: 0x001c
AceCount: 0x0001
Ace[00]
AceType: 0x02 (SYSTEM_AUDIT_ACE_TYPE)
AceSize: 0x0014
InheritFlags: 0xc0
SUCCESSFUL_ACCESS_ACE_FLAG
FAILED_ACCESS_ACE_FLAG
Access Mask: 0x000d002b
DELETE
WRITE_DAC
WRITE_OWNER
Others(0x0000002b)
Ace Sid: (S-1-1-0)