2022-04-02 16:16:40 +00:00
/*
* PROJECT : ReactOS Winlogon
* LICENSE : GPL - 2.0 - or - later ( https : //spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE : Security utility infrastructure implementation of Winlogon
* COPYRIGHT : Copyright 2022 George Bișoc < george . bisoc @ reactos . org >
*/
/* INCLUDES *****************************************************************/
# include "winlogon.h"
/* DEFINES ******************************************************************/
# define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | \
DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | \
DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | \
DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED )
# define DESKTOP_ADMINS_LIMITED (DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS | \
DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_ENUMERATE )
# define DESKTOP_INTERACTIVE_LIMITED (STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | \
DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW )
# define DESKTOP_WINLOGON_ADMINS_LIMITED (STANDARD_RIGHTS_REQUIRED | DESKTOP_ENUMERATE)
# define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES | \
WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | \
WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | \
WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | WINSTA_READSCREEN | \
STANDARD_RIGHTS_REQUIRED )
# define WINSTA_ADMINS_LIMITED (WINSTA_READATTRIBUTES | WINSTA_ENUMERATE)
# define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | \
GENERIC_EXECUTE | GENERIC_ALL )
/* GLOBALS ******************************************************************/
static SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY } ;
/* FUNCTIONS ****************************************************************/
/**
* @ brief
* Converts an absolute security descriptor to a self - relative
* format .
*
* @ param [ in ] AbsoluteSd
* A pointer to an absolute security descriptor to be
* converted .
*
* @ return
* Returns a pointer to a converted security descriptor in
* self - relative format . If the function fails , NULL is returned
* otherwise .
*
* @ remarks
* The function allocates the security descriptor buffer in memory
* heap , the caller is entirely responsible for freeing such buffer
* from when it ' s no longer needed .
*/
PSECURITY_DESCRIPTOR
ConvertToSelfRelative (
_In_ PSECURITY_DESCRIPTOR AbsoluteSd )
{
PSECURITY_DESCRIPTOR RelativeSd ;
DWORD DescriptorLength = 0 ;
/* Determine the size for our buffer to allocate */
if ( ! MakeSelfRelativeSD ( AbsoluteSd , NULL , & DescriptorLength ) & & GetLastError ( ) ! = ERROR_INSUFFICIENT_BUFFER )
{
ERR ( " ConvertToSelfRelative(): Unexpected error code (error code %lu -- must be ERROR_INSUFFICIENT_BUFFER) \n " , GetLastError ( ) ) ;
return NULL ;
}
/* Allocate the buffer now */
RelativeSd = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DescriptorLength ) ;
if ( RelativeSd = = NULL )
{
ERR ( " ConvertToSelfRelative(): Failed to allocate buffer for relative SD! \n " ) ;
return NULL ;
}
/* Convert the security descriptor now */
if ( ! MakeSelfRelativeSD ( AbsoluteSd , RelativeSd , & DescriptorLength ) )
{
ERR ( " ConvertToSelfRelative(): Failed to convert the security descriptor to a self relative format (error code %lu) \n " , GetLastError ( ) ) ;
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
return NULL ;
}
return RelativeSd ;
}
/**
* @ brief
* Creates a security descriptor for the default
* window station upon its creation .
*
* @ param [ out ] WinstaSd
* A pointer to a created security descriptor for
* the window station .
*
* @ return
* Returns TRUE if the function has successfully
* created the security descriptor , FALSE otherwise .
*/
BOOL
CreateWinstaSecurity (
_Out_ PSECURITY_DESCRIPTOR * WinstaSd )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
2022-04-09 19:17:58 +00:00
PSID WinlogonSid = NULL , AdminsSid = NULL , NetworkServiceSid = NULL ; /* NetworkServiceSid is a HACK, see the comment below for information */
2022-04-02 16:16:40 +00:00
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Create the network service SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_NETWORK_SERVICE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& NetworkServiceSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to create the network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/*
* Build up the DACL size . This includes a number
* of four ACEs of two different SIDs . The first two
* ACEs give both window station and generic access
* to Winlogon , the last two give limited window station
* and desktop access to admins .
2022-04-09 19:17:58 +00:00
*
* = = = = = = = = = = = = = = = = = = = = = ! ! ! MUST READ ! ! ! = = = = = = = = = = = = = = = = = = = = =
*
* HACK - - Include in the DACL two more ACEs for network
* service SID . Network services will be granted full
* access to the default window station . Whilst technically
* services that are either network or local ones are part
* and act on behalf of the system , what we are doing here
* is a hack because of two reasons :
*
* 1 ) Winlogon does not allow default window station ( Winsta0 )
* access to network services on Windows . As a matter of fact ,
* network services must access their own service window station
* ( aka Service - 0x0 - 3e4 $ ) which never gets created . Why it never
* gets created is explained on the second point .
*
* 2 ) Our LSASS terribly lacks in code that handles special logon
* service types , NetworkService and LocalService . For this reason
* whenever an access token is created for a network service process
* for example , its authentication ID ( aka LogonId represented as a LUID )
* is a uniquely generated ID by LSASS for this process . This is wrong
* on so many levels , partly because a network service is not a regular
* service and network services have their own special authentication logon
* ID ( with its respective LUID as { 0x3e4 , 0x0 } ) . On top of that , a network
* service process must have an impersonation token but for whatever reason
* we are creating a primary access token instead .
*
* FOR ANYONE WHO ' S INTERESTED ON FIXING THIS , DO NOT FORGET TO REMOVE THIS
* HACK ! ! !
*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = ! ! ! END ! ! ! = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
2022-04-02 16:16:40 +00:00
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
2022-04-09 19:17:58 +00:00
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) ;
2022-04-02 16:16:40 +00:00
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " CreateWinstaSecurity(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " CreateWinstaSecurity(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- give full winsta access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
WinlogonSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- give full generic access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
WinlogonSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Third ACE -- give limited winsta access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Fourth ACE -- give limited desktop access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
DESKTOP_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Fifth ACE -- give full access to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
NetworkServiceSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for network service (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* HACK: Sixth ACE -- give full generic access to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
NetworkServiceSid ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set ACE for network service (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " CreateWinstaSecurity(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to the descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " CreateWinstaSecurity(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Convert it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " CreateWinstaSecurity(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Give the descriptor to the caller */
* WinstaSd = RelativeSd ;
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
2022-04-09 19:17:58 +00:00
/* HACK */
if ( NetworkServiceSid ! = NULL )
{
FreeSid ( NetworkServiceSid ) ;
}
/* END HACK */
2022-04-02 16:16:40 +00:00
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( Success = = FALSE )
{
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
}
return Success ;
}
/**
* @ brief
* Creates a security descriptor for the default
* application desktop upon its creation .
*
* @ param [ out ] ApplicationDesktopSd
* A pointer to a created security descriptor for
* the application desktop .
*
* @ return
* Returns TRUE if the function has successfully
* created the security descriptor , FALSE otherwise .
*/
BOOL
CreateApplicationDesktopSecurity (
_Out_ PSECURITY_DESCRIPTOR * ApplicationDesktopSd )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
2022-04-09 19:17:58 +00:00
PSID WinlogonSid = NULL , AdminsSid = NULL , NetworkServiceSid = NULL ; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
2022-04-02 16:16:40 +00:00
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Create the network service SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_NETWORK_SERVICE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& NetworkServiceSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to create the network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/*
* Build up the DACL size . This includes a number
* of two ACEs of two different SIDs . The first ACE
* gives full access to Winlogon , the last one gives
* limited desktop access to admins .
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
2022-04-09 19:17:58 +00:00
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) ; /* HACK */
2022-04-02 16:16:40 +00:00
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- Give full desktop power to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
WinlogonSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- Give limited desktop power to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Third ACE -- Give full desktop power to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
NetworkServiceSid ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to set ACE for network services (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to the descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Conver it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " CreateApplicationDesktopSecurity(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Give the descriptor to the caller */
* ApplicationDesktopSd = RelativeSd ;
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
2022-04-09 19:17:58 +00:00
/* HACK */
if ( NetworkServiceSid ! = NULL )
{
FreeSid ( NetworkServiceSid ) ;
}
/* END HACK */
2022-04-02 16:16:40 +00:00
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( Success = = FALSE )
{
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
}
return Success ;
}
/**
* @ brief
* Creates a security descriptor for the default
* Winlogon desktop . This descriptor serves as a
* security measure for the winlogon desktop so
* that only Winlogon itself ( and admins ) can
* interact with it .
*
* @ param [ out ] WinlogonDesktopSd
* A pointer to a created security descriptor for
* the Winlogon desktop .
*
* @ return
* Returns TRUE if the function has successfully
* created the security descriptor , FALSE otherwise .
*/
BOOL
CreateWinlogonDesktopSecurity (
_Out_ PSECURITY_DESCRIPTOR * WinlogonDesktopSd )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
PSID WinlogonSid = NULL , AdminsSid = NULL ;
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/*
* Build up the DACL size . This includes a number
* of two ACEs of two different SIDs . The first ACE
* gives full access to Winlogon , the last one gives
* limited desktop access to admins .
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) ;
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- Give full desktop access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
WinlogonSid ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- Give limited desktop access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_WINLOGON_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to the descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Conver it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " CreateWinlogonDesktopSecurity(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Give the descriptor to the caller */
* WinlogonDesktopSd = RelativeSd ;
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( Success = = FALSE )
{
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
}
return Success ;
}
/**
* @ brief
* Creates a security descriptor for the screen
* saver desktop .
*
* @ param [ out ] ScreenSaverDesktopSd
* A pointer to a created security descriptor for
* the screen - saver desktop .
*
* @ return
* Returns TRUE if the function has successfully
* created the security descriptor , FALSE otherwise .
*/
BOOL
CreateScreenSaverSecurity (
_Out_ PSECURITY_DESCRIPTOR * ScreenSaverDesktopSd )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
PSID WinlogonSid = NULL , AdminsSid = NULL , InteractiveSid = NULL ;
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Create the interactive logon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_INTERACTIVE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& InteractiveSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to create the interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/*
* Build up the DACL size . This includes a number
* of three ACEs of three different SIDs . The first ACE
* gives full access to Winlogon , the second one gives
* limited desktop access to admins and the last one
* gives full desktop access to users who have logged in
* interactively .
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( InteractiveSid ) ;
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " CreateScreenSaverSecurity(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- Give full desktop access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
WinlogonSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- Give limited desktop access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
DESKTOP_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Third ACE -- Give full desktop access to interactive logon users */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
DESKTOP_INTERACTIVE_LIMITED ,
InteractiveSid ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to set ACE for interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to the descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " CreateScreenSaverSecurity(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Conver it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " CreateScreenSaverSecurity(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Give the descriptor to the caller */
* ScreenSaverDesktopSd = RelativeSd ;
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
if ( InteractiveSid ! = NULL )
{
FreeSid ( InteractiveSid ) ;
}
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( Success = = FALSE )
{
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
}
return Success ;
}
/**
* @ brief
* Assigns access to the specific logon user to
* the default window station . Such access is
* given to the user when it has logged in .
*
* @ param [ in ] WinSta
* A handle to a window station where the
* user is given access to it .
*
* @ param [ in ] LogonSid
* A pointer to a logon SID that represents
* the logged in user in question .
*
* @ return
* Returns TRUE if the function has successfully
* assigned access to the user , FALSE otherwise .
*/
BOOL
AllowWinstaAccessToUser (
_In_ HWINSTA WinSta ,
_In_ PSID LogonSid )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
2022-04-09 19:17:58 +00:00
PSID WinlogonSid = NULL , AdminsSid = NULL , InteractiveSid = NULL , NetworkServiceSid = NULL ; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
2022-04-02 16:16:40 +00:00
SECURITY_INFORMATION SecurityInformation ;
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Create the interactive logon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_INTERACTIVE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& InteractiveSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to create the interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Create the network service SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_NETWORK_SERVICE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& NetworkServiceSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to create the network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/*
* Build up the DACL size . This includes a number
* of eight ACEs of four different SIDs . The first ACE
* gives full winsta access to Winlogon , the second one gives
* generic access to Winlogon . Such approach is the same
* for both interactive logon users and logon user as well .
* Only admins are given limited powers .
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( InteractiveSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( InteractiveSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( LogonSid ) +
2022-04-09 19:17:58 +00:00
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( LogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) + /* HACK */
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) ;
2022-04-02 16:16:40 +00:00
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " AllowWinstaAccessToUser(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- Give full winsta access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
WinlogonSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- Give generic access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
WinlogonSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Third ACE -- Give limited winsta access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Fourth ACE -- Give limited desktop access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
DESKTOP_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Fifth ACE -- Give full winsta access to interactive logon users */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
InteractiveSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Sixth ACE -- Give generic access to interactive logon users */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
InteractiveSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Seventh ACE -- Give full winsta access to logon user */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
LogonSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for logon user SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Eighth ACE -- Give generic access to logon user */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
LogonSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for logon user SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK : Ninenth ACE -- Give full winsta access to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
NO_PROPAGATE_INHERIT_ACE ,
WINSTA_ALL ,
NetworkServiceSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for logon network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* HACK: Tenth ACE -- Give generic access to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE ,
GENERIC_ACCESS ,
NetworkServiceSid ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set ACE for network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Convert it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " AllowWinstaAccessToUser(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Set new winsta security based on this descriptor */
SecurityInformation = DACL_SECURITY_INFORMATION ;
if ( ! SetUserObjectSecurity ( WinSta , & SecurityInformation , RelativeSd ) )
{
ERR ( " AllowWinstaAccessToUser(): Failed to set window station security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
if ( InteractiveSid ! = NULL )
{
FreeSid ( InteractiveSid ) ;
}
2022-04-09 19:17:58 +00:00
/* HACK */
if ( NetworkServiceSid ! = NULL )
{
FreeSid ( NetworkServiceSid ) ;
}
/* END HACK */
2022-04-02 16:16:40 +00:00
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
return Success ;
}
/**
* @ brief
* Assigns access to the specific logon user to
* the default desktop . Such access is given to
* the user when it has logged in .
*
* @ param [ in ] Desktop
* A handle to a desktop where the user
* is given access to it .
*
* @ param [ in ] LogonSid
* A pointer to a logon SID that represents
* the logged in user in question .
*
* @ return
* Returns TRUE if the function has successfully
* assigned access to the user , FALSE otherwise .
*/
BOOL
AllowDesktopAccessToUser (
_In_ HDESK Desktop ,
_In_ PSID LogonSid )
{
BOOL Success = FALSE ;
SECURITY_DESCRIPTOR AbsoluteSd ;
PSECURITY_DESCRIPTOR RelativeSd = NULL ;
2022-04-09 19:17:58 +00:00
PSID WinlogonSid = NULL , AdminsSid = NULL , InteractiveSid = NULL , NetworkServiceSid = NULL ; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
2022-04-02 16:16:40 +00:00
SECURITY_INFORMATION SecurityInformation ;
DWORD DaclSize ;
PACL Dacl ;
/* Create the Winlogon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_LOCAL_SYSTEM_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& WinlogonSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to create the Winlogon SID (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
/* Create the admins SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
2 ,
SECURITY_BUILTIN_DOMAIN_RID ,
DOMAIN_ALIAS_RID_ADMINS ,
0 , 0 , 0 , 0 , 0 , 0 ,
& AdminsSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to create the admins SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Create the interactive logon SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_INTERACTIVE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& InteractiveSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to create the interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Create the network service SID */
if ( ! AllocateAndInitializeSid ( & NtAuthority ,
1 ,
SECURITY_NETWORK_SERVICE_RID ,
0 , 0 , 0 , 0 , 0 , 0 , 0 ,
& NetworkServiceSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to create the network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/*
* Build up the DACL size . This includes a number
* of four ACEs of four different SIDs . The first ACE
* gives full desktop access to Winlogon , the second one gives
* generic limited desktop access to admins . The last two give
* full power to both interactive logon users and logon user as
* well .
*/
DaclSize = sizeof ( ACL ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( WinlogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( AdminsSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( InteractiveSid ) +
2022-04-09 19:17:58 +00:00
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( LogonSid ) +
sizeof ( ACCESS_ALLOWED_ACE ) - sizeof ( DWORD ) + GetLengthSid ( NetworkServiceSid ) ; /* HACK */
2022-04-02 16:16:40 +00:00
/* Allocate the DACL now */
Dacl = RtlAllocateHeap ( RtlGetProcessHeap ( ) ,
HEAP_ZERO_MEMORY ,
DaclSize ) ;
if ( Dacl = = NULL )
{
ERR ( " AllowDesktopAccessToUser(): Failed to allocate memory buffer for DACL! \n " ) ;
goto Quit ;
}
/* Initialize it */
if ( ! InitializeAcl ( Dacl , DaclSize , ACL_REVISION ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to initialize DACL (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* First ACE -- Give full desktop access to Winlogon */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
WinlogonSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set ACE for Winlogon (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Second ACE -- Give limited desktop access to admins */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ADMINS_LIMITED ,
AdminsSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set ACE for admins (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Third ACE -- Give full desktop access to interactive logon users */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
InteractiveSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set ACE for interactive SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Fourth ACE -- Give full desktop access to logon user */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
LogonSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set ACE for logon user SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-09 19:17:58 +00:00
/* HACK: Fifth ACE -- Give full desktop to network services */
if ( ! AddAccessAllowedAceEx ( Dacl ,
ACL_REVISION ,
0 ,
DESKTOP_ALL ,
NetworkServiceSid ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set ACE for network service SID (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
2022-04-02 16:16:40 +00:00
/* Initialize the security descriptor */
if ( ! InitializeSecurityDescriptor ( & AbsoluteSd , SECURITY_DESCRIPTOR_REVISION ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to initialize absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Set the DACL to the descriptor */
if ( ! SetSecurityDescriptorDacl ( & AbsoluteSd , TRUE , Dacl , FALSE ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set up DACL to absolute security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Conver it to self-relative format */
RelativeSd = ConvertToSelfRelative ( & AbsoluteSd ) ;
if ( RelativeSd = = NULL )
{
ERR ( " AllowDesktopAccessToUser(): Failed to convert security descriptor to self relative format! \n " ) ;
goto Quit ;
}
/* Assign new security to desktop based on this descriptor */
SecurityInformation = DACL_SECURITY_INFORMATION ;
if ( ! SetUserObjectSecurity ( Desktop , & SecurityInformation , RelativeSd ) )
{
ERR ( " AllowDesktopAccessToUser(): Failed to set desktop security descriptor (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
Success = TRUE ;
Quit :
if ( WinlogonSid ! = NULL )
{
FreeSid ( WinlogonSid ) ;
}
if ( AdminsSid ! = NULL )
{
FreeSid ( AdminsSid ) ;
}
if ( InteractiveSid ! = NULL )
{
FreeSid ( InteractiveSid ) ;
}
2022-04-09 19:17:58 +00:00
/* HACK */
if ( NetworkServiceSid ! = NULL )
{
FreeSid ( NetworkServiceSid ) ;
}
/* END HACK */
2022-04-02 16:16:40 +00:00
if ( Dacl ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , Dacl ) ;
}
if ( RelativeSd ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , RelativeSd ) ;
}
return Success ;
}
/**
* @ brief
* Assigns both window station and desktop access
* to the specific session currently active on the
* system .
*
* @ param [ in ] Session
* A pointer to an active session .
*
* @ return
* Returns TRUE if the function has successfully
* assigned access to the current session , FALSE otherwise .
*/
BOOL
AllowAccessOnSession (
_In_ PWLSESSION Session )
{
BOOL Success = FALSE ;
DWORD Index , SidLength , GroupsLength = 0 ;
PTOKEN_GROUPS TokenGroup = NULL ;
PSID LogonSid ;
/* Get required buffer size and allocate the TOKEN_GROUPS buffer */
if ( ! GetTokenInformation ( Session - > UserToken ,
TokenGroups ,
TokenGroup ,
0 ,
& GroupsLength ) )
{
if ( GetLastError ( ) ! = ERROR_INSUFFICIENT_BUFFER )
{
ERR ( " AllowAccessOnSession(): Unexpected error code returned, must be ERROR_INSUFFICIENT_BUFFER (error code %lu) \n " , GetLastError ( ) ) ;
return FALSE ;
}
TokenGroup = RtlAllocateHeap ( RtlGetProcessHeap ( ) , HEAP_ZERO_MEMORY , GroupsLength ) ;
if ( TokenGroup = = NULL )
{
ERR ( " AllowAccessOnSession(): Failed to allocate memory buffer for token group! \n " ) ;
return FALSE ;
}
}
/* Get the token group information from the access token */
if ( ! GetTokenInformation ( Session - > UserToken ,
TokenGroups ,
TokenGroup ,
GroupsLength ,
& GroupsLength ) )
{
ERR ( " AllowAccessOnSession(): Failed to retrieve the token group information (error code %lu) \n " , GetLastError ( ) ) ;
goto Quit ;
}
/* Loop through the groups to find the logon SID */
for ( Index = 0 ; Index < TokenGroup - > GroupCount ; Index + + )
{
if ( ( TokenGroup - > Groups [ Index ] . Attributes & SE_GROUP_LOGON_ID )
= = SE_GROUP_LOGON_ID )
{
LogonSid = TokenGroup - > Groups [ Index ] . Sid ;
break ;
}
}
/* Allow window station access to this user within this session */
if ( ! AllowWinstaAccessToUser ( Session - > InteractiveWindowStation , LogonSid ) )
{
ERR ( " AllowAccessOnSession(): Failed to allow winsta access to the logon user! \n " ) ;
goto Quit ;
}
/* Allow application desktop access to this user within this session */
if ( ! AllowDesktopAccessToUser ( Session - > ApplicationDesktop , LogonSid ) )
{
ERR ( " AllowAccessOnSession(): Failed to allow application desktop access to the logon user! \n " ) ;
goto Quit ;
}
/* Get the length of this logon SID */
SidLength = GetLengthSid ( LogonSid ) ;
/* Assign the window station to this logged in user */
if ( ! SetWindowStationUser ( Session - > InteractiveWindowStation ,
& Session - > LogonId ,
LogonSid ,
SidLength ) )
{
ERR ( " AllowAccessOnSession(): Failed to assign the window station to the logon user! \n " ) ;
goto Quit ;
}
Success = TRUE ;
Quit :
if ( TokenGroup ! = NULL )
{
RtlFreeHeap ( RtlGetProcessHeap ( ) , 0 , TokenGroup ) ;
}
return Success ;
}
/* EOF */