Microsoft KB Archive/295004

{|
 * width="100%"|

HOWTO: Use High-Level Access Control APIs from Visual Basic

 * }

Q295004

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * the operating system: Microsoft Windows 2000

-

SUMMARY
The Win32 API provides two sets of APIs for working with security descriptors (SDs) and access control lists (ACLs). Low-level as well as high-level access control API sets provide an interface for working with SDs and ACLs. For Microsoft Windows 2000, the high-level access control APIs have been enhanced to support object-specific access control entries (ACEs), directory service (DS) objects, and automatic inheritance. This article provides sample code that uses high-level access control APIs to modify an existing discretionary ACL (DACL) on a folder securable object.

MORE INFORMATION
The following Visual Basic sample code uses the GetNamedSecurityInfo API to retrieve the existing DACL of the C:\Test1 folder. Then, it builds the EXPLICIT_ACCESS structure for everyone trustee with GENERIC_READ access by using the BuildExplicitAccessWithName API. In this example, the ACE is constructed with inheritance CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE, which applies as an effective ACE for the C:\Test1 folder and an inheritable ACE for subfolders as well as files.

The SetEntriesInAcl API creates a new access-control list (ACL) by merging new access-control information specified in EXPLICIT_ACCESS structures into an existing ACL and returns a newly updated DACL in memory. This updated DACL is then used to set security on the C:\Test1 folder by using the SetNamedSecurityInfo API.

Option Explicit

' Success status of high level access control APIs Private Const ERROR_SUCCESS = 0&

' Type of Securable Object we are operating in this sample code Private Const SE_FILE_OBJECT = 1&

' The Security Information constants required Private Const DACL_SECURITY_INFORMATION = 4& Private Const SET_ACCESS = 2&

' Standard access rights extracted from WinNT.h Private Const SYNCHRONIZE = &H100000 Private Const READ_CONTROL = &H20000 Private Const WRITE_DAC = &H40000 Private Const WRITE_OWNER = &H80000 Private Const STANDARD_RIGHTS_READ = (READ_CONTROL) Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL) Private Const DELETE = &H10000

' Generic access rights extracted from WinNT.h Private Const GENERIC_ALL = &H10000000 Private Const GENERIC_EXECUTE = &H20000000 Private Const GENERIC_READ = &H80000000 Private Const GENERIC_WRITE = &H40000000

' Inheritance Flags Private Const CONTAINER_INHERIT_ACE = &H2 Private Const OBJECT_INHERIT_ACE = &H1

' The TRUSTEE structure identifies the user account, group account, or logon session ' to which an ACE applies. The structure can use a name or a security identifier (SID) ' to identify the trustee.

' Access control APIs, such as SetEntriesInAcl and GetExplicitEntriesFromAcl, use this ' structure to identify the account associated with the access-control or audit-control ' information in an EXPLICIT_ACCESS structure. Private Type TRUSTEE pMultipleTrustee As Long MultipleTrusteeOperation As Long TrusteeForm As Long TrusteeType As Long ptstrName As String End Type

' EXPLICIT_ACCESS structure that specifies access-control information for a specified ' trustee such as access mask as well as inheritance flags Private Type EXPLICIT_ACCESS grfAccessPermissions As Long grfAccessMode As Long grfInheritance As Long pTRUSTEE As TRUSTEE End Type

' High Level access control API declarations Private Declare Sub BuildExplicitAccessWithName Lib &quot;Advapi32.dll&quot; Alias _ &quot;BuildExplicitAccessWithNameA&quot; _ (ea As Any, _   ByVal TrusteeName As String, _    ByVal AccessPermissions As Long, _    ByVal AccessMode As Integer, _    ByVal Inheritance As Long) Private Declare Function SetEntriesInAcl Lib &quot;Advapi32.dll&quot; Alias _ &quot;SetEntriesInAclA&quot; _ (ByVal CountofExplicitEntries As Long, _   ea As Any, _    ByVal OldAcl As Long, _    NewAcl As Long) As Long

Private Declare Function GetNamedSecurityInfo Lib &quot;Advapi32.dll&quot; Alias _ &quot;GetNamedSecurityInfoA&quot; _ (ByVal ObjName As String, _   ByVal SE_OBJECT_TYPE As Long, _    ByVal SecInfo As Long, _    ByVal pSid As Long, _    ByVal pSidGroup As Long, _    pDacl As Long, _    ByVal pSacl As Long, _    pSecurityDescriptor As Long) As Long Private Declare Function SetNamedSecurityInfo Lib &quot;Advapi32.dll&quot; Alias _ &quot;SetNamedSecurityInfoA&quot; _ (ByVal ObjName As String, _   ByVal SE_OBJECT As Long, _    ByVal SecInfo As Long, _    ByVal pSid As Long, _    ByVal pSidGroup As Long, _    ByVal pDacl As Long, _    ByVal pSacl As Long) As Long

Private Declare Function LocalFree Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long

Private Sub Command1_Click

Dim result As Long Dim pSecDesc As Long Dim ea As EXPLICIT_ACCESS Dim pNewDACL As Long Dim pOldDACL As Long ' Get the DACL information of c:\test1 folder using GetNamedSecurityInfo API. ' SE_FILE_OBJECT constant says that the named securable object is a file or folder result = GetNamedSecurityInfo(&quot;c:\test1&quot;, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0&, 0&, pOldDACL, 0&, pSecDesc) If result = ERROR_SUCCESS Then ' Construct an EXPLICIT_ACCESS structure for Everyone with GENERIC_READ access that will apply for c:\test1 ' as well as subfolder and files using BuildExplicitAccessWithName API BuildExplicitAccessWithName ea, &quot;Users&quot;, GENERIC_READ, SET_ACCESS, CONTAINER_INHERIT_ACE Or OBJECT_INHERIT_ACE ' Merge constructed EXPLICIT_ACCESS structure to the existing DACL and get an updated DACL in memory from ' SetEntriesInAcl API result = SetEntriesInAcl(1, ea, pOldDACL, pNewDACL) If result = ERROR_SUCCESS Then MsgBox &quot;SetEntriesInAcl succeeded&quot; ' Call SetNamedSecurityInfo API with the updated DACL in memory to change the DACL of c:\test1 folder result = SetNamedSecurityInfo(&quot;c:\test1&quot;, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0&, 0&, pNewDACL, 0&) If result = ERROR_SUCCESS Then MsgBox &quot;SetNamedSecurityInfo succeeded&quot; Else MsgBox &quot;SetNamedSecurityInfo failed with error code : &quot; & result End If       ' Free the memory allocated for the new DACL by the SetEntriesInAcl API, using LocalFree API LocalFree pNewDACL Else MsgBox &quot;SetEntriesInAcl failed with error code : &quot; & result End If   ' Free the memory allocated for the security descriptor by the GetNamedSecurityInfo API, using LocalFree API LocalFree pSecDesc Else MsgBox &quot;GetNamedSecurityInfo failed with error code : &quot; & result End If End Sub