The Win32 Application Programming Interface (API) provides two sets of APIs for working with security descriptors and access control lists (ACLs): low-level and high-level. This series of articles provide a complete set of Microsoft Visual Basic code samples that use low-level access control APIs to create, as well as modify, an existing discretionary ACL (DACL) on a kernel object, user object, shared resource (such as a shared folder or shared printer), registry key, or printer.

In this article we will learn how to use Visual Basic to handle user object (Desktop,Windows...) security using APIs

The UpdatePermissionsOfUserObject function in the sample code uses the GetUserObjectSecurity() and SetUserObjectSecurity() functions to modify an existing DACL of any user object. UpdatePermissionsOfDesktop is used to call this helper function to modify permissions of the "Default" desktop in the current window station.

This example uses the following generic structure to represent the permissions for a user or group account

where AccountName is any user or group account name, and AccessMask is any of the generic or object-specific access masks. All the access mask constants for any securable object are defined in the sample code. AceFlags and AceType structure members have the same values as documented in the ACE_HEADER data structure in the Microsoft Platform SDK.

As demonstrated in some of the code samples available through the preceding link, the caller can specify an array of AccountPerm structures to either construct a new security descriptor or add to an existing security descriptor of any securable object. If the caller wants to pass a well known SID, the caller can allocate the SID by using the AllocateAndInitializeSid() function and then specify it in the pSid structure member, with SidPassedByCaller set to True.

Step-By-Step Example

- First step to test this example is create 3 User accounts (User1, User2 and User3) as shown below

- Create a standard exe project- Add a module to the project- Place one command button on the form1- Place the following code in form1 code window

' Find the SIDs for each userName supplied in Accounts() array' and compute the new ACL size needed.' Call LookupAccountName only for the entries where the' SID is not supplied by the caller. szDomainName = Space(256)For n = 0 To dwNumOfAccountsIf (Accounts(n).pSid = 0) Then nSidSize = 0 cbDomainName = 256

' Copy all non-inherited ACEs from the existing DACLIf (lDaclPresent <> 0 And pAcl <> 0 And sACLInfo.AceCount > 0) Then' Get each ACE from the old DACL and add them into the new DACL.For I = 0 To (sACLInfo.AceCount - 1)' Attempt to get the next ACE. fResult = GetAce(pAcl, I, Ptr)If (fResult = 0) Then Err.Raise 0

'Add the ACE to the new DACL if the SID is not in Accounts()If Not (IsEqual(Accounts(), Ptr + 8)) Then' Now that you have the ACE, add it to the new ACL. fResult = AddAce(pNewACL, ACL_REVISION, _MAXDWORD, Ptr, _ tempAce.Header.AceSize)If fResult = 0 Then Err.Raise 0 AceIndex = AceIndex + 1EndIfNext IEndIf

' Copy now all inherited ACEs from the existing DACL, so that the' new DACL will be in the Windows 2000 preferred orderIf (lDaclPresent <> 0 And pAcl <> 0 And sACLInfo.AceCount > 0) Then' Get each INHERITED_ACE from the old ACL and' add them into the new ACL.For I = I To (sACLInfo.AceCount - 1)' Attempt to get the next ACE. fResult = GetAce(pAcl, I, Ptr)If (fResult = 0) Then Err.Raise 0

'WinSta0 is the name of the window station object that represents the'physical screen, keyboard and mouse. Winlogon creates the following'desktops in the WinSta0 object

'[1]Winlogon desktop'======================='This is the desktop Winlogon and GINA use for interactive identification'and authentication, and other secure dialogs. Winlogon automatically'switches to this desktop when it receives SAS event notification.

'[2]Application desktop'======================='Each time a user successfully logs on, an application desktop is created'for that logon session. The application desktop is also called the default'or user desktop. This desktop is where all user activity takes place.'The application desktop is protected; only the system and the interactive'logon session have access to it. Note that only a particular instance of'the logged-on user has access to the desktop. If the interactive user'activates a process using the service controller, that service application'will not have access to the application desktop.

'[3]Screen-saver desktop'======================='This is the current desktop when a screen saver is running. If a user is'logged on, both the system and the interactive logon session have access'to the desktop. Otherwise, only the system has access to the desktop.

Job Description : He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting.