[USERENV] LoadUserProfileW: Check the user for Administators and Guests group members...
authorEric Kohl <eric.kohl@reactos.org>
Sun, 17 Mar 2019 11:44:54 +0000 (12:44 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 17 Mar 2019 11:44:54 +0000 (12:44 +0100)
See https://www.pcreview.co.uk/threads/purpose-of-the-state-key-located-in-users-profiles.2939114/post-9722112

dll/win32/userenv/internal.h
dll/win32/userenv/misc.c
dll/win32/userenv/profile.c

index f33725f..2c1cfeb 100644 (file)
@@ -40,6 +40,10 @@ BOOL
 RemoveDirectoryPath(LPCWSTR lpPathName);
 
 /* misc.c */
+
+extern SID_IDENTIFIER_AUTHORITY LocalSystemAuthority;
+extern SID_IDENTIFIER_AUTHORITY WorldAuthority;
+
 typedef struct _DYN_FUNCS
 {
   HMODULE hModule;
index 9014998..214d8f1 100644 (file)
@@ -31,8 +31,8 @@
 #define NDEBUG
 #include <debug.h>
 
-static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
-static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
+SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
 
 /* FUNCTIONS ***************************************************************/
 
index bd859cc..cf54242 100644 (file)
@@ -348,6 +348,106 @@ done:
 }
 
 
+static
+DWORD
+CheckForGuestsAndAdmins(
+    _In_ HANDLE hToken,
+    _Out_ PDWORD pdwState)
+{
+    PTOKEN_GROUPS pGroupInfo = NULL;
+    PSID pAdministratorsSID = NULL;
+    PSID pGuestsSID = NULL;
+    DWORD i, dwSize;
+    DWORD dwError = ERROR_SUCCESS;
+
+    DPRINT("CheckForGuestsAndAdmins(%p %p)\n", hToken, pdwState);
+
+    /* Get the buffer size */
+    if (!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize))
+    {
+        dwError = GetLastError();
+        if (dwError != ERROR_INSUFFICIENT_BUFFER)
+        {
+            DPRINT1("GetTokenInformation() failed (Error %lu)\n", dwError);
+            return dwError;
+        }
+
+        dwError = ERROR_SUCCESS;
+    }
+
+    /* Allocate the buffer */
+    pGroupInfo = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 0, dwSize);
+    if (pGroupInfo == NULL)
+    {
+        dwError = ERROR_OUTOFMEMORY;
+        DPRINT1("HeapAlloc() failed (Error %lu)\n", dwError);
+        goto done;
+    }
+
+    /* Get the token groups */
+    if (!GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize))
+    {
+        dwError = GetLastError();
+        DPRINT1("GetTokenInformation() failed (Error %lu)\n", dwError);
+        goto done;
+    }
+
+    /* Build the Administrators Group SID */
+    if(!AllocateAndInitializeSid(&LocalSystemAuthority,
+                                 2,
+                                 SECURITY_BUILTIN_DOMAIN_RID,
+                                 DOMAIN_ALIAS_RID_ADMINS,
+                                 0, 0, 0, 0, 0, 0,
+                                 &pAdministratorsSID))
+    {
+        dwError = GetLastError();
+        DPRINT1("AllocateAndInitializeSid() failed (Error %lu)\n", dwError);
+        goto done;
+    }
+
+    /* Build the Guests Group SID */
+    if(!AllocateAndInitializeSid(&LocalSystemAuthority,
+                                 2,
+                                 SECURITY_BUILTIN_DOMAIN_RID,
+                                 DOMAIN_ALIAS_RID_GUESTS,
+                                 0, 0, 0, 0, 0, 0,
+                                 &pGuestsSID))
+    {
+        dwError = GetLastError();
+        DPRINT1("AllocateAndInitializeSid() failed (Error %lu)\n", dwError);
+        goto done;
+    }
+
+    /* Check for Administratos or Guests group memberships */
+    for (i = 0; i < pGroupInfo->GroupCount; i++)
+    {
+        if (EqualSid(pAdministratorsSID, pGroupInfo->Groups[i].Sid))
+        {
+            *pdwState |= 0x0100; // PROFILE_ADMIN_USER
+        }
+
+        if (EqualSid(pGuestsSID, pGroupInfo->Groups[i].Sid))
+        {
+            *pdwState |= 0x0080; // PROFILE_GUESTS_USER
+        }
+    }
+
+    dwError = ERROR_SUCCESS;
+
+done:
+    if (pGuestsSID != NULL)
+        FreeSid(pGuestsSID);
+
+    if (pAdministratorsSID != NULL)
+        FreeSid(pAdministratorsSID);
+
+    if (pGroupInfo != NULL)
+        HeapFree(GetProcessHeap(), 0, pGroupInfo);
+
+    return dwError;
+}
+
+
 static
 DWORD
 SetProfileData(
@@ -360,8 +460,7 @@ SetProfileData(
     DWORD dwLength, dwState = 0;
     DWORD dwError;
 
-    DPRINT("SetProfileData(%S %p)\n",
-           pszSidString, hToken);
+    DPRINT("SetProfileData(%S %p)\n", pszSidString, hToken);
 
     dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
                             L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
@@ -427,6 +526,14 @@ SetProfileData(
         goto done;
     }
 
+    dwError = CheckForGuestsAndAdmins(hToken,
+                                      &dwState);
+    if (dwError != ERROR_SUCCESS)
+    {
+        DPRINT1("Error: %lu\n", dwError);
+        goto done;
+    }
+
     dwLength = sizeof(dwState);
     dwError = RegSetValueExW(hProfileKey,
                              L"State",
@@ -1350,7 +1457,7 @@ GetProfilesDirectoryA(
     LPWSTR lpBuffer;
     BOOL bResult;
 
-    if (!lpcchSize)
+    if (!lpcchSize || !lpProfileDir)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
@@ -1474,7 +1581,7 @@ GetUserProfileDirectoryA(
     LPWSTR lpBuffer;
     BOOL bResult;
 
-    if (!lpcchSize)
+    if (!lpcchSize || !lpProfileDir)
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;