From 0f21a8a6e699d83168dbcbe8438a53423773247f Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 17 Mar 2019 12:44:54 +0100 Subject: [PATCH] [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 f33725ffd7e..2c1cfeb79b4 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 9014998e405..214d8f1f448 100644 --- a/dll/win32/userenv/misc.c +++ b/dll/win32/userenv/misc.c @@ -31,8 +31,8 @@ #define NDEBUG #include -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 bd859cc21c0..cf5424288a3 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;