https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0f21a8a6e699d83168dbcbe8438a53423773247f

commit 0f21a8a6e699d83168dbcbe8438a53423773247f
Author:     Eric Kohl <[email protected]>
AuthorDate: Sun Mar 17 12:44:54 2019 +0100
Commit:     Eric Kohl <[email protected]>
CommitDate: Sun Mar 17 12:44:54 2019 +0100

    [USERENV] LoadUserProfileW: Check the user for Administators and Guests 
group membership and set the State value accordingly.
    
    See 
https://www.pcreview.co.uk/threads/purpose-of-the-state-key-located-in-users-profiles.2939114/post-9722112
---
 dll/win32/userenv/internal.h |   4 ++
 dll/win32/userenv/misc.c     |   4 +-
 dll/win32/userenv/profile.c  | 115 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 117 insertions(+), 6 deletions(-)

diff --git a/dll/win32/userenv/internal.h b/dll/win32/userenv/internal.h
index f33725ffd7..2c1cfeb79b 100644
--- a/dll/win32/userenv/internal.h
+++ b/dll/win32/userenv/internal.h
@@ -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;
diff --git a/dll/win32/userenv/misc.c b/dll/win32/userenv/misc.c
index 9014998e40..214d8f1f44 100644
--- a/dll/win32/userenv/misc.c
+++ b/dll/win32/userenv/misc.c
@@ -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 ***************************************************************/
 
diff --git a/dll/win32/userenv/profile.c b/dll/win32/userenv/profile.c
index bd859cc21c..cf5424288a 100644
--- a/dll/win32/userenv/profile.c
+++ b/dll/win32/userenv/profile.c
@@ -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;

Reply via email to