[WINLOGON] Allow WinSta0 access only when needed. Also, reset the WinSta0 user as...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Mon, 16 Jul 2018 23:44:00 +0000 (01:44 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 22 Jul 2018 17:03:17 +0000 (19:03 +0200)
base/system/winlogon/sas.c
base/system/winlogon/winlogon.h
base/system/winlogon/wlx.c

index 1a57a4a..0189953 100644 (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:
index 37960e2..f1467c9 100644 (file)
 
 #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);
index 5557e7f..89289c0 100644 (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: