[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
This commit is contained in:
Eric Kohl 2019-03-17 12:44:54 +01:00
parent 646ab9286c
commit 0f21a8a6e6
3 changed files with 117 additions and 6 deletions

View 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;

View 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 ***************************************************************/

View 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;