[WINLOGON]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 18 Sep 2016 23:32:02 +0000 (23:32 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 18 Sep 2016 23:32:02 +0000 (23:32 +0000)
- CreateUserEnvironment: if user impersonation fails, just fail the call.
- SetDefaultLanguage: Use the *correct* HKEY_CURRENT_USER key to retrieve the lang., that is, first impersonate the user, then, call RegOpenCurrentUser. We do that because otherwise calling RegOpenKey(Ex) for HKEY_CURRENT_USER just uses the process cached value of HKEY_CURRENT_USER, which does not change *even if* one impersonates an user.

[MSGINA]
- Correctly impersonate the user when opening & initializing the shutdown dialog (in the same way as winlogon does), i.e. call ImpersonateLoggedOnUser and use RegOpenCurrentUser.
- Fill few (but not all) code holes in WlxScreenSaverNotify.

svn path=/trunk/; revision=72737

reactos/base/system/winlogon/environment.c
reactos/base/system/winlogon/sas.c
reactos/base/system/winlogon/screensaver.c
reactos/base/system/winlogon/winlogon.c
reactos/base/system/winlogon/winlogon.h
reactos/dll/win32/msgina/gui.c
reactos/dll/win32/msgina/msgina.c
reactos/dll/win32/msgina/shutdown.c

index 1fb30af..4bb3633 100644 (file)
@@ -134,9 +134,13 @@ CreateUserEnvironment(
     TRACE("WL: CreateUserEnvironment called\n");
 
     /* Impersonate the new user */
-    ImpersonateLoggedOnUser(Session->UserToken);
+    if (!ImpersonateLoggedOnUser(Session->UserToken))
+    {
+        ERR("ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
+        return FALSE;
+    }
 
-    /* Open the new users HKCU key */
+    /* Open the new user HKCU key */
     lError = RegOpenCurrentUser(KEY_CREATE_SUB_KEY,
                                 &hKeyCurrentUser);
     if (lError == ERROR_SUCCESS)
index e9945e9..97f3761 100644 (file)
@@ -106,51 +106,69 @@ StartUserShell(
 
 BOOL
 SetDefaultLanguage(
-    IN BOOL UserProfile)
+    IN PWLSESSION Session)
 {
-    HKEY BaseKey;
-    LPCWSTR SubKey;
-    LPCWSTR ValueName;
+    BOOL ret = FALSE;
+    BOOL UserProfile;
     LONG rc;
-    HKEY hKey = NULL;
+    HKEY UserKey, hKey = NULL;
+    LPCWSTR SubKey, ValueName;
     DWORD dwType, dwSize;
     LPWSTR Value = NULL;
     UNICODE_STRING ValueString;
     NTSTATUS Status;
     LCID Lcid;
-    BOOL ret = FALSE;
+
+    UserProfile = (Session && Session->UserToken);
+
+    if (UserProfile && !ImpersonateLoggedOnUser(Session->UserToken))
+    {
+        ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
+        return FALSE;
+        // FIXME: ... or use the default language of the system??
+        // UserProfile = FALSE;
+    }
 
     if (UserProfile)
     {
-        BaseKey = HKEY_CURRENT_USER;
+        rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &UserKey);
+        if (rc != ERROR_SUCCESS)
+        {
+            TRACE("RegOpenCurrentUser() failed with error %lu\n", rc);
+            goto cleanup;
+        }
+
         SubKey = L"Control Panel\\International";
         ValueName = L"Locale";
     }
     else
     {
-        BaseKey = HKEY_LOCAL_MACHINE;
+        UserKey = NULL;
         SubKey = L"System\\CurrentControlSet\\Control\\Nls\\Language";
         ValueName = L"Default";
     }
 
-    rc = RegOpenKeyExW(
-        BaseKey,
-        SubKey,
-        0,
-        KEY_READ,
-        &hKey);
+    rc = RegOpenKeyExW(UserKey ? UserKey : HKEY_LOCAL_MACHINE,
+                       SubKey,
+                       0,
+                       KEY_READ,
+                       &hKey);
+
+    if (UserKey)
+        RegCloseKey(UserKey);
+
     if (rc != ERROR_SUCCESS)
     {
         TRACE("RegOpenKeyEx() failed with error %lu\n", rc);
         goto cleanup;
     }
-    rc = RegQueryValueExW(
-        hKey,
-        ValueName,
-        NULL,
-        &dwType,
-        NULL,
-        &dwSize);
+
+    rc = RegQueryValueExW(hKey,
+                          ValueName,
+                          NULL,
+                          &dwType,
+                          NULL,
+                          &dwSize);
     if (rc != ERROR_SUCCESS)
     {
         TRACE("RegQueryValueEx() failed with error %lu\n", rc);
@@ -169,13 +187,12 @@ SetDefaultLanguage(
         TRACE("HeapAlloc() failed\n");
         goto cleanup;
     }
-    rc = RegQueryValueExW(
-        hKey,
-        ValueName,
-        NULL,
-        NULL,
-        (LPBYTE)Value,
-        &dwSize);
+    rc = RegQueryValueExW(hKey,
+                          ValueName,
+                          NULL,
+                          NULL,
+                          (LPBYTE)Value,
+                          &dwSize);
     if (rc != ERROR_SUCCESS)
     {
         TRACE("RegQueryValueEx() failed with error %lu\n", rc);
@@ -204,10 +221,15 @@ SetDefaultLanguage(
     ret = TRUE;
 
 cleanup:
-    if (hKey)
-        RegCloseKey(hKey);
     if (Value)
         HeapFree(GetProcessHeap(), 0, Value);
+
+    if (hKey)
+        RegCloseKey(hKey);
+
+    if (UserProfile)
+        RevertToSelf();
+
     return ret;
 }
 
@@ -272,6 +294,11 @@ PlayLogonSoundThread(
     ULONG Index = 0;
     SC_HANDLE hSCManager, hService;
 
+    //
+    // FIXME: Isn't it possible to *JUST* impersonate the current user
+    // *AND* open its HKCU??
+    //
+
     /* Get SID of current user */
     Status = NtQueryInformationToken((HANDLE)lpParameter,
                                      TokenUser,
@@ -336,7 +363,7 @@ PlayLogonSoundThread(
         return 0;
     }
 
-    /* Open service manager */
+    /* Open the service manager */
     hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
     if (!hSCManager)
     {
@@ -344,17 +371,17 @@ PlayLogonSoundThread(
         return 0;
     }
 
-    /* Open wdmaud service */
+    /* Open the wdmaud service */
     hService = OpenServiceW(hSCManager, L"wdmaud", GENERIC_READ);
     if (!hService)
     {
-        /* Sound is not installed */
+        /* The service is not installed */
         TRACE("Failed to open wdmaud service (%x)\n", GetLastError());
         CloseServiceHandle(hSCManager);
         return 0;
     }
 
-    /* Wait for wdmaud start */
+    /* Wait for wdmaud to start */
     do
     {
         if (!QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&Info, sizeof(SERVICE_STATUS_PROCESS), &dwSize))
@@ -451,8 +478,8 @@ HandleLogon(
     DisplayStatusMessage(Session, Session->WinlogonDesktop, IDS_APPLYINGYOURPERSONALSETTINGS);
     UpdatePerUserSystemParameters(0, TRUE);
 
-    /* Set default language */
-    if (!SetDefaultLanguage(TRUE))
+    /* Set default user language */
+    if (!SetDefaultLanguage(Session))
     {
         WARN("WL: SetDefaultLanguage() failed\n");
         goto cleanup;
@@ -1530,7 +1557,7 @@ InitializeSAS(
         goto cleanup;
     }
 
-    if (!SetDefaultLanguage(FALSE))
+    if (!SetDefaultLanguage(NULL))
         return FALSE;
 
     ret = TRUE;
index 402d840..a613928 100644 (file)
@@ -177,13 +177,14 @@ ScreenSaverThreadMain(
     }
 
 cleanup:
-    RevertToSelf();
     if (Session->hUserActivity)
         CloseHandle(Session->hUserActivity);
 
     if (Session->hEndOfScreenSaver)
         CloseHandle(Session->hEndOfScreenSaver);
 
+    RevertToSelf();
+
 #ifndef USE_GETLASTINPUTINFO
     if (Session->KeyboardHook)
         UnhookWindowsHookEx(Session->KeyboardHook);
@@ -194,6 +195,7 @@ cleanup:
 
     CloseHandle(Session->hEndOfScreenSaverThread);
     CloseHandle(Session->hScreenSaverParametersChanged);
+
     return 0;
 }
 
@@ -368,13 +370,14 @@ StartScreenSaver(
     CallNotificationDlls(Session, StopScreenSaverHandler);
 
 cleanup:
-    RevertToSelf();
     if (hKey)
         RegCloseKey(hKey);
 
     if (hCurrentUser)
         RegCloseKey(hCurrentUser);
 
+    RevertToSelf();
+
     if (!ret)
     {
         PostMessageW(Session->SASWindow, WLX_WM_SAS, WLX_SAS_TYPE_SCRNSVR_ACTIVITY, 0);
index c43b16f..2621934 100644 (file)
@@ -160,7 +160,7 @@ InitKeyboardLayouts(VOID)
     /* Open registry key with preloaded layouts */
     if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Preload", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
     {
-        while(TRUE)
+        while (TRUE)
         {
             /* Read values with integer names only */
             swprintf(wszKeyName, L"%d", i++);
index 640f80f..9c5819d 100644 (file)
@@ -293,7 +293,7 @@ StartRpcServer(VOID);
 
 /* sas.c */
 BOOL
-SetDefaultLanguage(IN BOOL UserProfile);
+SetDefaultLanguage(IN PWLSESSION Session);
 
 BOOL
 InitializeSAS(IN OUT PWLSESSION Session);
index ca46bac..6d0840c 100644 (file)
@@ -624,15 +624,33 @@ OnShutDown(
     INT ret;
     DWORD ShutdownOptions;
 
-    // FIXME: User impersonation!!
-    pgContext->nShutdownAction = LoadShutdownSelState();
-    ShutdownOptions = GetAllowedShutdownOptions();
+    if (ImpersonateLoggedOnUser(pgContext->UserToken))
+    {
+        pgContext->nShutdownAction = LoadShutdownSelState();
+        ShutdownOptions = GetAllowedShutdownOptions();
+        RevertToSelf();
+    }
+    else
+    {
+        ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
+        pgContext->nShutdownAction = 0;
+        ShutdownOptions = 0;
+    }
 
     ret = ShutdownDialog(hwndDlg, ShutdownOptions, pgContext);
 
-    // FIXME: User impersonation!!
     if (ret == IDOK)
-        SaveShutdownSelState(pgContext->nShutdownAction);
+    {
+        if (ImpersonateLoggedOnUser(pgContext->UserToken))
+        {
+            SaveShutdownSelState(pgContext->nShutdownAction);
+            RevertToSelf();
+        }
+        else
+        {
+            ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
+        }
+    }
 
     return ret;
 }
index 7c36f40..4be15dd 100644 (file)
@@ -352,8 +352,9 @@ WlxScreenSaverNotify(
     BOOL  *pSecure)
 {
 #if 0
+    PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext;
     WCHAR szBuffer[2];
-    HKEY hKey;
+    HKEY hKeyCurrentUser, hKey;
     DWORD bufferSize = sizeof(szBuffer);
     DWORD varType = REG_SZ;
     LONG rc;
@@ -369,14 +370,29 @@ WlxScreenSaverNotify(
      *    HKCU\Control Panel\Desktop : ScreenSaverIsSecure
      */
 
-    // FIXME: User impersonation!!
+    if (!ImpersonateLoggedOnUser(pgContext->UserToken))
+    {
+        ERR("WL: ImpersonateLoggedOnUser() failed with error %lu\n", GetLastError());
+        *pSecure = FALSE;
+        return TRUE;
+    }
 
-    rc = RegOpenKeyExW(HKEY_CURRENT_USER,
-                       L"Control Panel\\Desktop",
-                       0,
-                       KEY_QUERY_VALUE,
-                       &hKey);
-    TRACE("RegOpenKeyExW: %ld\n", rc);
+    /* Open the current user HKCU key */
+    rc = RegOpenCurrentUser(MAXIMUM_ALLOWED, &hKeyCurrentUser);
+    TRACE("RegOpenCurrentUser: %ld\n", rc);
+    if (rc == ERROR_SUCCESS)
+    {
+        /* Open the subkey */
+        rc = RegOpenKeyExW(hKeyCurrentUser,
+                           L"Control Panel\\Desktop",
+                           0,
+                           KEY_QUERY_VALUE,
+                           &hKey);
+        TRACE("RegOpenKeyExW: %ld\n", rc);
+        RegCloseKey(hKeyCurrentUser);
+    }
+
+    /* Read the value */
     if (rc == ERROR_SUCCESS)
     {
         rc = RegQueryValueExW(hKey,
@@ -397,6 +413,9 @@ WlxScreenSaverNotify(
         RegCloseKey(hKey);
     }
 
+    /* Revert the impersonation */
+    RevertToSelf();
+
     TRACE("*pSecure: %ld\n", *pSecure);
 #endif
 
@@ -820,10 +839,10 @@ CreateProfile(
     pProfile->pszEnvironment = lpEnvironment;
 
     if (!GetTokenInformation(pgContext->UserToken,
-        TokenStatistics,
-        (PVOID)&Stats,
-        sizeof(TOKEN_STATISTICS),
-        &cbStats))
+                             TokenStatistics,
+                             &Stats,
+                             sizeof(Stats),
+                             &cbStats))
     {
         WARN("Couldn't get Authentication id from user token!\n");
         goto cleanup;
index ea0534f..11390e5 100644 (file)
@@ -32,18 +32,26 @@ DWORD
 LoadShutdownSelState(VOID)
 {
     LONG lRet;
-    HKEY hKey;
+    HKEY hKeyCurrentUser, hKey;
     DWORD dwValue, dwTemp, dwSize;
 
     /* Default to shutdown */
     dwValue = WLX_SAS_ACTION_SHUTDOWN_POWER_OFF;
 
-    lRet = RegOpenKeyExW(HKEY_CURRENT_USER,
-                         L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
-                         0, KEY_QUERY_VALUE, &hKey);
+    /* Open the current user HKCU key */
+    lRet = RegOpenCurrentUser(MAXIMUM_ALLOWED, &hKeyCurrentUser);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Open the subkey */
+        lRet = RegOpenKeyExW(hKeyCurrentUser,
+                             L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
+                             0, KEY_QUERY_VALUE, &hKey);
+        RegCloseKey(hKeyCurrentUser);
+    }
     if (lRet != ERROR_SUCCESS)
         return dwValue;
 
+    /* Read the value */
     dwSize = sizeof(dwTemp);
     lRet = RegQueryValueExW(hKey,
                             L"Shutdown Setting",
@@ -90,18 +98,25 @@ VOID
 SaveShutdownSelState(
     IN DWORD ShutdownCode)
 {
-    HKEY hKey;
+    LONG lRet;
+    HKEY hKeyCurrentUser, hKey;
     DWORD dwValue = 0;
 
-    if (RegCreateKeyExW(HKEY_CURRENT_USER,
-                        L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
-                        0, NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_SET_VALUE,
-                        NULL, &hKey, NULL) != ERROR_SUCCESS)
+    /* Open the current user HKCU key */
+    lRet = RegOpenCurrentUser(MAXIMUM_ALLOWED, &hKeyCurrentUser);
+    if (lRet == ERROR_SUCCESS)
     {
-        return;
+        /* Create the subkey */
+        lRet = RegCreateKeyExW(hKeyCurrentUser,
+                               L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
+                               0, NULL,
+                               REG_OPTION_NON_VOLATILE,
+                               KEY_SET_VALUE,
+                               NULL, &hKey, NULL);
+        RegCloseKey(hKeyCurrentUser);
     }
+    if (lRet != ERROR_SUCCESS)
+        return;
 
     switch (ShutdownCode)
     {