[WINLOGON] Allow WinSta0 access only when needed. Also, reset the WinSta0 user as soon as we have logged-off.

This commit is contained in:
Hermès Bélusca-Maïto 2018-07-17 01:44:00 +02:00
parent 9c48edb58c
commit 02eee253b2
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 115 additions and 94 deletions

View file

@ -43,6 +43,8 @@ typedef struct tagLOGOFF_SHUTDOWN_DATA
static BOOL ExitReactOSInProgress = FALSE;
LUID LuidNone = {0, 0};
/* FUNCTIONS ****************************************************************/
static BOOL
@ -425,6 +427,87 @@ PlayLogonSound(
CloseHandle(hThread);
}
static BOOL
AllowWinstaAccess(PWLSESSION Session)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;
PSID psid;
TOKEN_STATISTICS Stats;
DWORD cbStats;
DWORD ret;
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
0,
&dwLength))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
return FALSE;
}
// Get the token group information from the access token.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
dwLength,
&dwLength))
{
goto Cleanup;
}
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
{
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
== SE_GROUP_LOGON_ID)
{
psid = ptg->Groups[dwIndex].Sid;
break;
}
}
dwLength = GetLengthSid(psid);
if (!GetTokenInformation(Session->UserToken,
TokenStatistics,
&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("Couldn't get Authentication id from user token!\n");
goto Cleanup;
}
AddAceToWindowStation(Session->InteractiveWindowStation, psid);
ret = SetWindowStationUser(Session->InteractiveWindowStation,
&Stats.AuthenticationId,
psid,
dwLength);
TRACE("SetWindowStationUser returned 0x%x\n", ret);
bSuccess = TRUE;
Cleanup:
// Free the buffer for the token groups.
if (ptg != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
return bSuccess;
}
static
BOOL
HandleLogon(
@ -485,6 +568,8 @@ HandleLogon(
goto cleanup;
}
AllowWinstaAccess(Session);
if (!StartUserShell(Session))
{
//WCHAR StatusMsg[256];
@ -520,6 +605,8 @@ cleanup:
RemoveStatusMessage(Session);
if (!ret)
{
SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0);
CloseHandle(Session->UserToken);
Session->UserToken = NULL;
}
@ -792,6 +879,11 @@ HandleLogoff(
SwitchDesktop(Session->WinlogonDesktop);
// TODO: Play logoff sound!
SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0);
// DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_LOGGINGOFF);
// FIXME: Closing network connections!
@ -1045,94 +1137,6 @@ DoGenericAction(
}
}
DWORD WINAPI SetWindowStationUser(HWINSTA hWinSta, LUID* pluid, PSID psid, DWORD sidSize);
BOOL
AddAceToWindowStation(
IN HWINSTA WinSta,
IN PSID Sid);
static
BOOL AllowWinstaAccess(PWLSESSION Session)
{
BOOL bSuccess = FALSE;
DWORD dwIndex;
DWORD dwLength = 0;
PTOKEN_GROUPS ptg = NULL;
PSID psid;
TOKEN_STATISTICS Stats;
DWORD cbStats;
DWORD ret;
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
0,
&dwLength))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
if (ptg == NULL)
return FALSE;
}
// Get the token group information from the access token.
if (!GetTokenInformation(Session->UserToken,
TokenGroups,
ptg,
dwLength,
&dwLength))
{
goto Cleanup;
}
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)
{
if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)
== SE_GROUP_LOGON_ID)
{
psid = ptg->Groups[dwIndex].Sid;
break;
}
}
dwLength = GetLengthSid(psid);
if (!GetTokenInformation(Session->UserToken,
TokenStatistics,
&Stats,
sizeof(TOKEN_STATISTICS),
&cbStats))
{
WARN("Couldn't get Authentication id from user token!\n");
goto Cleanup;
}
AddAceToWindowStation(Session->InteractiveWindowStation, psid);
ret = SetWindowStationUser(Session->InteractiveWindowStation,
&Stats.AuthenticationId,
psid,
dwLength);
TRACE("SetWindowStationUser returned 0x%x\n", ret);
bSuccess = TRUE;
Cleanup:
// Free the buffer for the token groups.
if (ptg != NULL)
HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);
return bSuccess;
}
static
VOID
DispatchSAS(
@ -1169,8 +1173,6 @@ DispatchSAS(
&Session->UserToken,
&Session->MprNotifyInfo,
(PVOID*)&Session->Profile);
AllowWinstaAccess(Session);
break;
case STATE_LOGGED_OFF_SAS:

View file

@ -43,6 +43,14 @@
#include <reactos/undocuser.h>
BOOL
WINAPI
SetWindowStationUser(
IN HWINSTA hWindowStation,
IN PLUID pluid,
IN PSID psid OPTIONAL,
IN DWORD size);
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(winlogon);
@ -292,9 +300,15 @@ BOOL
StartRpcServer(VOID);
/* sas.c */
extern LUID LuidNone;
BOOL
SetDefaultLanguage(IN PWLSESSION Session);
NTSTATUS
HandleShutdown(IN OUT PWLSESSION Session,
IN DWORD wlxAction);
BOOL
InitializeSAS(IN OUT PWLSESSION Session);
@ -348,12 +362,14 @@ CloseAllDialogWindows(VOID);
BOOL
GinaInit(IN OUT PWLSESSION Session);
BOOL
AddAceToWindowStation(
IN HWINSTA WinSta,
IN PSID Sid);
BOOL
CreateWindowStationAndDesktops(IN OUT PWLSESSION Session);
NTSTATUS
HandleShutdown(IN OUT PWLSESSION Session,
IN DWORD wlxAction);
VOID WINAPI WlxUseCtrlAltDel(HANDLE hWlx);
VOID WINAPI WlxSetContextPointer(HANDLE hWlx, PVOID pWlxContext);

View file

@ -1271,7 +1271,7 @@ CreateWindowStationAndDesktops(
NULL,
0,
MAXIMUM_ALLOWED,
&DefaultSecurity);
&DefaultSecurity); // FIXME: Must use restricted Winlogon-only security!!
if (!Session->WinlogonDesktop)
{
ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
@ -1304,6 +1304,9 @@ CreateWindowStationAndDesktops(
goto cleanup;
}
SetWindowStationUser(Session->InteractiveWindowStation,
&LuidNone, NULL, 0);
ret = TRUE;
cleanup: