https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0f21a8a6e699d83168dbc…
commit 0f21a8a6e699d83168dbcbe8438a53423773247f
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Mar 17 12:44:54 2019 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
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-user…
---
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;