[ Team LiB ] Previous Section Next Section

23.4 Creating Security Descriptors

If you are creating an object from scratch, and you don't want it to get the default DACL and SACL that due to inheritance would normally be applied to objects created at that location in the tree, you can write your own DACL and SACL for an object. As you would expect, there are a number of properties associated with security descriptors and ACLs that you need to set. SDs and ACLs can be manipulated with the IADsAccessControlList (see Table 23-10) and IADsSecurityDescriptor (see Table 23-11) interfaces. We'll go through these briefly now and then move on to some more examples.

Table 23-10. IADsAccessControlList methods and properties

IADsAccessControlList methods and properties

Action

AddAce method

Adds an ACE to an ACL

RemoveAce method

Removes an ACE from an ACL

CopyAccessList method

Copies the current ACL

AclRevision property

Shows the revision of the ACL (always set to 4; see later text)

AceCount property

Indicates the number of ACEs in the ACL

The revision level is a static version number for every ACE, ACL, and SD in Active Directory. It is defined in the ADS_SD_REVISION_ENUM enumerated type, which contains a single constant definition as follows:

Const ADS_SD_REVISION_DS = 4.

Having a revision allows Active Directory to know which elements of an ACE could exist. Later, if new properties and concepts are added to the ACE so that it has a more extended definition, the revision would increment. Active Directory would then know that old revision-4 ACEs could not support the new extensions and could upgrade them or support them with lesser functionality.

Table 23-11. IADsSecurityDescriptor methods and properties

IADsSecurityDescriptor methods and properties

Action

CopySecurityDescriptor method

A copy of an existing SD.

Revision property

The revision of the SD (always set to 4, as noted earlier).

Control property

A set of flags indicating various aspects of the SD (see later text).

Owner property

The SID of the owner. If this field is null, no owner is set.

OwnerDefaulted property

A Boolean value indicating whether the owner is derived by the default mechanism when created (i.e., assembled out of all the inherited ACEs passed down by its parents) rather than explicitly set by the person or application that created the SD in the first place.

Group property

The SID of the object's primary group if appropriate. If this field is null, no primary group exists.

GroupDefaulted property

A Boolean value indicating that the group is derived by the default mechanism rather than explicitly set by the person or application that created the SD in the first place.

DiscretionaryAcl property

The discretionary ACL that holds permissions ACEs. The SE_DACL_PRESENT flag must be set in the Control property if a DACL exists. If the flag is set and yet this field is null, full access is allowed to everyone.

DaclDefaulted property

A Boolean value indicating that the DACL is derived by the default mechanism rather than explicitly set by the person or application that created the SD in the first place. This is ignored unless SE_DACL_PRESENT is set.

SystemAcl property

The system ACL that holds auditing ACEs. The SE_SACL_PRESENT flag must be set in the Control property if a SACL exists.

SaclDefaulted property

A Boolean value indicating that the SACL is derived by the default mechanism rather than explicitly set by the person or application that created the SD in the first place. This is ignored unless SE_SACL_PRESENT is set.

The Control property can take a number of flags that help to define the properties of an SD. See Table 23-12 for a full description.

Table 23-12. Control constants

ADSI name

Decimal value

Hex value

Description

ADS_SD_CONTROL_SE_ OWNER_DEFAULTED

1

&H1

This Boolean flag, when set, indicates that the SID pointed to by the Owner field was provided by the default mechanism rather than set by the person or application that created the SD in the first place. This may affect the treatment of the SID with respect to inheritance of an owner.

ADS_SD_CONTROL_SE_ GROUP_DEFAULTED

2

&H2

This Boolean flag, when set, indicates that the SID in the Group field was provided by the default mechanism rather than explicitly set by the person or application that created the SD in the first place. This may affect the treatment of the SID with respect to inheritance of a primary group.

ADS_SD_CONTROL_SE_ DACL_PRESENT

4

&H4

This Boolean flag, when set, indicates that the security descriptor contains a DACL. If this flag is set and the DiscretionaryAcl field of the SD is null, an empty (but present) ACL is explicitly being specified.

ADS_SD_CONTROL_SE_ DACL_DEFAULTED

8

&H8

This Boolean flag, when set, indicates that the DiscretionaryAcl field was provided by the default mechanism rather than explicitly set by the person or application that created the SD in the first place. This may affect the treatment of the ACL with respect to inheritance of an ACL. This flag is ignored if the SE_DACL_PRESENT flag is not set.

ADS_SD_CONTROL_SE_ SACL_PRESENT

16

&H10

This Boolean flag, when set, indicates that the security descriptor contains a SACL.

ADS_SD_CONTROL_SE_ SACL_DEFAULTED

32

&H20

This Boolean flag, when set, indicates that the ACL pointed to by the SystemAcl field was provided by the default mechanism rather than explicitly set by the person or application that created the SD in the first place. This may affect the treatment of the ACL with respect to inheritance of an ACL. This flag is ignored if the SE_ SACL_PRESENT flag is not set.

ADS_SD_CONTROL_SE_ DACL_AUTO_INHERIT_ REQ

256

&H100

The DACL of the SD must be inherited.

ADS_SD_CONTROL_SE_ SACL_AUTO_INHERIT_ REQ

512

&H200

The SACL of the SD must be inherited.

ADS_SD_CONTROL_SE_ DACL_AUTO_INHERITED

1,024

&H400

The DACL of the SD supports auto-propagation of inheritable ACEs to existing child objects.

ADS_SD_CONTROL_SE_ SACL_AUTO_INHERITED

2,048

&H800

The SACL of the SD supports auto-propagation of inheritable ACEs to existing child objects.

ADS_SD_CONTROL_SE_ DACL_PROTECTED

4,096

&H1000

The DACL of the SD is protected and will not be modified when new rights propagate through the tree.

ADS_SD_CONTROL_SE_ SACL_PROTECTED

8,192

&H2000

The SACL of the SD is protected and will not be modified when new rights propagate through the tree.

ADS_SD_CONTROL_SE_ SELF_RELATIVE

32,768

&H8000

The SD is held in a contiguous block of memory.

These values were taken from the ADSI documentation for the ADS_SD_CONTROL_ENUM enumerated type available from the MSDN Library under the section described at the beginning of the chapter.

In your ADSI code, it is possible to specify that the DACL or SACL is either null or empty. While in both cases each ACL contains no ACEs, there is a big difference between the effects of each setting. Specifically, any ACL that has been set to null (vbNull) grants full permissions to everyone while an ACL that exists but contains no ACEs (i.e., is empty) grants no permissions to anyone at all.

Now we have enough information to be able to create our own SD. Example 23-3 does exactly that. While we have defined all of the SD constants, to save space we have defined only the ACE constants that we are using. Also note that this code is not 100% complete; the object creation code is not included.

Example 23-3. Creating your own security descriptor
'**************************************************************************
'AccessMask constants
'**************************************************************************
Const ADS_RIGHT_DS_LIST_OBJECT = &H80
   
'**************************************************************************
'AceType constants
'**************************************************************************
Const ADS_ACETYPE_ACCESS_DENIED = &H1
   
'**************************************************************************
'AceFlags constants
'**************************************************************************
Const ADS_ACEFLAG_INHERIT_ACE = &H2
   
'**************************************************************************
'Security Descriptor constants
'**************************************************************************
Const ADS_SD_CONTROL_SE_OWNER_DEFAULTED = &H1
Const ADS_SD_CONTROL_SE_GROUP_DEFAULTED = &H2
Const ADS_SD_CONTROL_SE_DACL_PRESENT = &H4
Const ADS_SD_CONTROL_SE_DACL_DEFAULTED = &H8
Const ADS_SD_CONTROL_SE_SACL_PRESENT = &H10
Const ADS_SD_CONTROL_SE_SACL_DEFAULTED = &H20
Const ADS_SD_CONTROL_SE_DACL_AUTO_INHERIT_REQ = &H100
Const ADS_SD_CONTROL_SE_SACL_AUTO_INHERIT_REQ = &H200
Const ADS_SD_CONTROL_SE_DACL_AUTO_INHERITED = &H400
Const ADS_SD_CONTROL_SE_SACL_AUTO_INHERITED = &H800
Const ADS_SD_CONTROL_SE_DACL_PROTECTED = &H1000
Const ADS_SD_CONTROL_SE_SACL_PROTECTED = &H2000
   
'**************************************************************************
'Security Descriptor Revision
'**************************************************************************
Const ADS_SD_REVISION_DS = 4
   
'**************************************************************************
'Declare general variables
'**************************************************************************
Dim objObject                'The object to bind to
Dim objSecDesc               'SecurityDescriptor
Dim objDACL                  'AccessControlList object containing permission ACEs
Dim objSACL                  'AccessControlList object containing audit ACEs
Dim objNewACE                'AccessControlEntry
Dim objAttributeSchemaObject 'An object representing an attribute in the schema
   
'**************************************************************************
'Create the objObject first [this code is not included here]
'**************************************************************************
   
'**************************************************************************
'Set no permission to view the object for members of DenyGroup
'**************************************************************************
Set objNewACE = CreateObject("AccessControlEntry")
AdsACE.Trustee = "cn=VickyLaunders,cn=Users,dc=amer,dc=mycorp,dc=com"
objNewACE.AccessMask = ADS_RIGHT_DS_LIST_OBJECT
objNewACE.AceType = ADS_ACETYPE_ACCESS_DENIED
objNewACE.AceFlags = ADS_ACEFLAG_INHERIT_ACE
 
'**************************************************************************
'Create a new DACL and add the ACE as the sole entry
'**************************************************************************
Set objDACL = CreateObject("AccessControlList")
ObjDACL.AceCount = 1
ObjDACL.AclRevision = ADS_SD_REVISION_DS
ObjDACL.AddAce objNewACE
Set objNewACE = Nothing
   
'**************************************************************************
'Create the SD for the object. Set the SD to use the DACL supplied rather
'than the default one. Set the SD to use the default SACL that will be
'generated from all the inherited ACEs from parents further up the hierarchy.
'**************************************************************************
Set objSecDesc = CreateObject("SecurityDescriptor")
objSecDes.Revision = ADS_SD_REVISION_DS
objSecDes.Control = ADS_SD_CONTROL_SE_SACL_PRESENT _
  + ADS_SD_CONTROL_SE_SACL_PRESENT + ADS_SD_CONTROL_SE_SACL_DEFAULTED _
  + SE_OWNER_DEFAULTED + SE_GROUP_DEFAULTED
objSecDes.OwnerDefaulted = True
objSecDes.GroupDefaulted = True
objSecDes.DiscretionaryAcl = objDACL  
objSecDes.DaclDefaulted = False
objSecDes.SaclDefaulted = True
   
'**************************************************************************
'Assign the SD to the existing object
'**************************************************************************
objObject.Put "ntSecurityDescriptor", objSecDes
obj Object.SetInfo
    [ Team LiB ] Previous Section Next Section