From 02eee253b2674f1a88d0dc1fd68e3deae8abbb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 17 Jul 2018 01:44:00 +0200 Subject: [PATCH] [WINLOGON] Allow WinSta0 access only when needed. Also, reset the WinSta0 user as soon as we have logged-off. --- base/system/winlogon/sas.c | 182 ++++++++++++++++---------------- base/system/winlogon/winlogon.h | 22 +++- base/system/winlogon/wlx.c | 5 +- 3 files changed, 115 insertions(+), 94 deletions(-) diff --git a/base/system/winlogon/sas.c b/base/system/winlogon/sas.c index 1a57a4ad6e1..0189953cff0 100644 --- a/base/system/winlogon/sas.c +++ b/base/system/winlogon/sas.c @@ -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: diff --git a/base/system/winlogon/winlogon.h b/base/system/winlogon/winlogon.h index 37960e23678..f1467c9c5c0 100644 --- a/base/system/winlogon/winlogon.h +++ b/base/system/winlogon/winlogon.h @@ -43,6 +43,14 @@ #include +BOOL +WINAPI +SetWindowStationUser( + IN HWINSTA hWindowStation, + IN PLUID pluid, + IN PSID psid OPTIONAL, + IN DWORD size); + #include 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); diff --git a/base/system/winlogon/wlx.c b/base/system/winlogon/wlx.c index 5557e7fbf5d..89289c08a99 100644 --- a/base/system/winlogon/wlx.c +++ b/base/system/winlogon/wlx.c @@ -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: