|  
  |  
Working with security descriptors of Active Directory objects is an advanced programming topic that requires a solid understanding of the Active Directory accesscontrol model. However, administrators can easily use some operations that deal with reading and/or settings permissions on Active Directory and other objects. ADSI 2.5 contains three interfaces that help to perform these tasks:
IADsSecurityDescriptor provides access to the common properties of a directory object's security descriptor, such as the owner of the object, the meaning of the descriptor, etc.
IADsAccessControlList allows you to manage the object's Discretionary Access Control List (DACL) that contains the Access Control Entries (ACEs). System ACL (SACL), which controls audit settings, is also supported.
IADsAccessControlEntry manages individual ACEs.
When programmatically setting permissions, you should reference the enumerations shown in the table below. These enumerations contain all necessary constants that must be set in the new Access Control Element (ACE).
|   Property  |   Enumeration  |  
|---|---|
|   AccesMask  |   ADS_RIGHTS_ENUM  |  
|   AceFlags  |   ADS_ACEFLAG_ENUM  |  
|   AceType  |   ADS_ACETYPE_ENUM  |  
The following program adds a new ACE that allows the user NET\Jessica to read properties (permissions List Contents, Read All Properties, and Read Permissions) of the Staff OU directory object. The program also displays all permissions set on this object.
Listing 17.22. addSecDescr.bas — Viewing and Modifying the Security Descriptor of an Object
    Option Explicit    Sub Main ()    Dim objObject As IADs    Dim objSD As IADsSecurityDescriptor    Dim objPropEntry As IADsAccessControlEntry    Dim objDACL As IADsAccessControlList    'Dim objSACL As IADsAccessControlList    'System ACL    Dim i As Integer    '***** Bind to an Active Directory object:    Set objObject = GetObject ("LDAP://OU=Staff,DC=net, DC=dom")    objObject.GetInfo    '***** Retrieve the security descriptor and some its properties:    Set objSD = objObject.Get ("ntSecurityDescriptor")    Debug.Print "========================================================"    Debug.Print "Control", objSD.Control, Hex (objSD.Control) + "(Hex)"    Debug.Print "Group", objSD.Group    Debug.Print "Owner", objSD.Owner    Set objDACL = objSD.DiscretionaryAcl    ' Set objSACL = objSD.SystemAcl    '***** Create a new ACE:    Set objPropEntry = CreateObject("AccessControlEntry")    '***** Define properties of the ACE *****    ' The permissions are granted to the user...    objPropEntry.Trustee = "NET\ Jessica"    ' Which permissions are granted (OxFO1FF = Full control):    objPropEntry.AccessMask = ADS_RIGHT_GENERIC_READ 'ADS_RIGHTS_ENUM    ' Define objects the permissions are applied to:    '  ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = This object only (Default)    '  ADS_ACEFLAG_INHERIT_ACE = This object and all child objects    objPropEntry.AceFlags = ADS_ACEFLAG_INHERIT_ACE 'ADS_ACEFLAG_ENUM    ' Grant or deny (ADS_ACETYPE_ACCESS_DENIED) access rights:    objPropEntry.AceType = ADS_ACETYPE_ACCESS_ALLOWED 'ADS_ACETYPE_ENUM    '***** Modify the ACL and assign it to the security descriptor:    objDACL.AddAce objPropEntry    objSD.DiscretionaryAcl = objDACL    On Error Resume Next    objObject.Put "ntSecurityDescriptor", Array (objSD)    objObject.SetInfo    If Err.Number = 0 Then    MsgBox "ACE has been successfully added!", , "Permissions"    Else    MsgBox "Error (Hex) : " + Hex (Err.Number) , , "Permissions"    Exit Sub    End If    '***** Read current ACL:    objObject.GetInfo    Debug.Print objDACL.AceCount 'Total number of the ACEs    i=1    For Each objPropEntry In objDACL 'Display some ACE'S properties       Debug.Print CStr (i) + ") "; objPropEntry.Trustee       Debug.Print " Mask (Hex) " + Hex (objPropEntry.AccessMask)       Debug.Print " Flags (Hex) " + Hex (objPropEntry.AceFlags)       Debug.Print " Type", objPropEntry.AceType       i = i + 1    Next    Set objObject = Nothing    Set objPropEntry = Nothing    Set objSD = Nothing    Set objDACL = Nothing    End Sub  The program presented will display the permissions on the directory object in the following form:
1) NT AUTHORITY\SYSTEM Mask (Hex) FOlFF Flags (Hex) 0 Type 0 2) NET\Domain Admins Mask (Hex) FOlFF Flags (Hex) 0 Type 0 3) NT AUTHORITY\Authenticated Users Mask (Hex) 20094 Flags (Hex) 0 Type 0 ... 33) NET\Jessica Mask (Hex) 80000000 Flags (Hex) 2 Type 0
With minimal changes, you can use this program with the NTFS File, Registry, Exchange Directory, or Active Directory objects, if you install the ADsSecurity DLL from the ADSI SDK Resource Kit. (You may also want to go over the examples located in the \ResourceKit\ADsSecurity\File folder.) The following listing illustrates how the same code can be used with both AD objects and files. Notice the statements marked in bold.
Listing 17.23. addSecDescr.bas — Using ADsSecurity for Viewing and Modifying Security Descriptors
    Option Explicit    Sub Main ()    Dim objObject As New ADsSecurity    Dim objSD As IADsSecurityDescriptor    Dim objPropEntry As IADsAccessControlEntry    Dim objDACL As IADsAccessControlList    'Dim objSACL As IADsAccessControlList    ' System ACL    Dim i As Integer    ' In VBScript you must also add the following statement:    '    objObject = Createobject ("ADsSecurity")    ' Read the object's security descriptor directly:    ' - from an Active Directory object    Set objSD = _    objObject. GetSecurityDescriptor ("LDAP: //OU=Staff,DC=net, DC=dom")    ' - from a file (BE SURE THAT THE FILE EXISTS!)    ' Set objSD = _    '            objObject. GetSecurityDescriptor("FILE://D:\text.txt")    ' Retrieve some properties of the security descriptor:    Debug.Print "========================================================="    Debug.Print "Control", objSD.Control, Hex (objSD.Control) + " (Hex)"    Debug.Print "Group", objSD. Group    Debug.Print "Owner", objSD. Owner    Set objDACL = objSD.DiscretionaryAcl    'Set objSACL = objSD.SystemAcl    '***** Create a new ACE *****    Set objPropEntry = CreateObject("AccessControlEntry")    '***** Define properties of the ACE *****    ' The permissions are granted to the user:    objPropEntry. Trustee = "NET\Jessica"    ' Which permissions are granted (0xF0lFF = Full control):    objPropEntry.AccessMask = ADS_RIGHT_GENERIC_READ 'ADS_RIGHTS_ENUM    ' Define objects the permissions are applied to:    ' ADS_ACEFLAG_NO_PROPAGATE_INHERIT_ACE = This object only (Default)    ' ADS_ACEFLAG_INHERIT_ACE = This object and all child objects    objPropEntry.AceFlags = ADS_ACEFLAG_INHERIT_ACE 'ADS_ACEFLAG_ENUM    ' Grant or deny (ADS_ACETYPE_ACCESS_DENIED) access rights:    objPropEntry.AceType = ADS_ACETYPE_ACCESS_ALLOWED 'ADS_ACETYPE_ENUM    '***** Modify the ACL and assign it to the security descriptor **    objDACL.AddAce obj PropEntry    objSD.DiscretionaryAcl = objDACL    On Error Resume Next    objObject.SetSecurityDescriptor objSD    If Err.Number = 0 Then      MsgBox "ACE has been successfully added!", ,"Permissions"    Else      MsgBox "Error (Hex): " + Hex (Err.Number), , "Permissions"      Exit Sub    End If    '***** Read the current ACL *****    objObject.GetInfo    Debug.Print objDACL.AceCount 'Total number of the ACESs    i = l    For Each objPropEntry In objDACL 'Displaying some ACE's properties       Debug.Print CStr (i) + ") "; objPropEntry.Trustee       Debug.Print " Mask (Hex) " + Hex (objPropEntry. AccessMask)       Debug.Print " Flags (Hex) " + Hex (objPropEntry.AceFlags)       Debug.Print " Type", objPropEntry.AceType       i = i + l    Next    Set objObject = Nothing    Set objPropEntry = Nothing    Set objSD = Nothing    Set objDACL = Nothing    End Sub  | Caution |   If you are going to use ADsSecurity.dll from a Visual Basic application, do not forget to register the DLL and add a reference to the ADsSecurinty 2.5 Type Library to the project.  |  
| Important |   By using ADsSecurity.dll, you can manipulate permissions on the file system as well as other objects. However, in the current version of ADSI, it is not possible to control access to file or print shares.  |  
  |  
  |