reactos/base/system/winlogon/security.c

1481 lines
50 KiB
C

/*
* 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;
PSID WinlogonSid = NULL, AdminsSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment below for information */
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;
}
/* 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;
}
/*
* 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.
*
* ===================== !!!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!!! ================================
*/
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(NetworkServiceSid) +
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid);
/* 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;
}
/* 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;
}
/* 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);
}
/* HACK */
if (NetworkServiceSid != NULL)
{
FreeSid(NetworkServiceSid);
}
/* END HACK */
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;
PSID WinlogonSid = NULL, AdminsSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
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;
}
/* 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;
}
/*
* 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) +
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid); /* HACK */
/* 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;
}
/* 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;
}
/* 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);
}
/* HACK */
if (NetworkServiceSid != NULL)
{
FreeSid(NetworkServiceSid);
}
/* END HACK */
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;
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
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;
}
/* 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;
}
/*
* 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) +
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);
/* 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;
}
/* 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;
}
/* 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);
}
/* HACK */
if (NetworkServiceSid != NULL)
{
FreeSid(NetworkServiceSid);
}
/* END HACK */
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;
PSID WinlogonSid = NULL, AdminsSid = NULL, InteractiveSid = NULL, NetworkServiceSid = NULL; /* NetworkServiceSid is a HACK, see the comment in CreateWinstaSecurity for information */
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;
}
/* 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;
}
/*
* 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) +
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(LogonSid) +
sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(NetworkServiceSid); /* HACK */
/* 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;
}
/* 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;
}
/* 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);
}
/* HACK */
if (NetworkServiceSid != NULL)
{
FreeSid(NetworkServiceSid);
}
/* END HACK */
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 */