[0.4.9][SERVICES] Remove the "Special service accounts initialization" hack

This is a *partial* back-port of 0.4.10-dev-279-g 75dc031080
And a plain revert of the guilty SVN r73486 == git a35a785b11

It will fix the following regression symptoms:
- CORE-12614 empty "documents and settings" folder created when using non-english localization
- CORE-12613 we will save 1012KB of memory (commit charge in taskmgr), by shrinking the registry a bit
- CORE-18416 RaceCondition, sometimes the network icon in systray does not appear in late 0.4.9-dev and releases/0.4.9

For the record: I decided to pick only part of the fix from master and not all, because the proper fix
would rely on a lot of things to pick additionally from 0.4.10-dev' and even 0.4.11-dev'.
The consequences of only partially picking is that we cannot complete the setup of Office 2010 with its
copyprotection-driver anymore, which relies on being able to load its service with the proper account and user profile,
and not with the fallback we used in older reactos releases. If you need that feature, please use releases/0.4.11 or higher,
because even 0.4.10 is not handling this properly yet.
The conservative approach of 'not having the hack, and sticking to just one profile' is better for the older releases overall.
This commit is contained in:
Joachim Henze 2022-09-28 00:33:01 +02:00
parent 275c4442bb
commit cd1ab7ea73

View file

@ -123,178 +123,6 @@ ShutdownHandlerRoutine(DWORD dwCtrlType)
}
/*** HACK CORE-12541: Special service accounts initialization HACK ************/
#include <ndk/setypes.h>
#include <sddl.h>
#include <userenv.h>
#include <strsafe.h>
/* Inspired from userenv.dll's CreateUserProfileExW and LoadUserProfileW APIs */
static
BOOL
ScmLogAccountHack(IN LPCWSTR pszAccountName,
IN LPCWSTR pszSid,
OUT PHKEY phProfile)
{
BOOL Success = FALSE;
LONG Error;
NTSTATUS Status;
BOOLEAN WasPriv1Set = FALSE, WasPriv2Set = FALSE;
PSID pSid;
DWORD dwLength;
WCHAR szUserHivePath[MAX_PATH];
DPRINT1("ScmLogAccountsHack(%S, %S)\n", pszAccountName, pszSid);
if (!pszAccountName || !pszSid || !phProfile)
return ERROR_INVALID_PARAMETER;
/* Convert the SID string into a SID. NOTE: No RTL equivalent. */
if (!ConvertStringSidToSidW(pszSid, &pSid))
{
DPRINT1("ConvertStringSidToSidW() failed (error %lu)\n", GetLastError());
return FALSE;
}
/* Determine a suitable profile path */
dwLength = ARRAYSIZE(szUserHivePath);
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
{
DPRINT1("GetProfilesDirectoryW() failed (error %lu)\n", GetLastError());
goto Quit;
}
/* Create user hive name */
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), pszAccountName);
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
DPRINT("szUserHivePath: %S\n", szUserHivePath);
/* Magic #1: Create the special user profile if needed */
if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
{
if (!CreateUserProfileW(pSid, pszAccountName))
{
DPRINT1("CreateUserProfileW() failed (error %lu)\n", GetLastError());
goto Quit;
}
}
/*
* Now Da Magiks #2: Manually mount the user profile registry hive
* aka. manually do what LoadUserProfile does!! But we don't require
* a security token!
*/
/* Acquire restore privilege */
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, TRUE, FALSE, &WasPriv1Set);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Error 0x%08lx)\n", Status);
goto Quit;
}
/* Acquire backup privilege */
Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &WasPriv2Set);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Error 0x%08lx)\n", Status);
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasPriv1Set, FALSE, &WasPriv1Set);
goto Quit;
}
/* Load user registry hive */
Error = RegLoadKeyW(HKEY_USERS, pszSid, szUserHivePath);
/* Remove restore and backup privileges */
RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, WasPriv2Set, FALSE, &WasPriv2Set);
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, WasPriv1Set, FALSE, &WasPriv1Set);
/* HACK: Do not fail if the profile has already been loaded! */
if (Error == ERROR_SHARING_VIOLATION)
Error = ERROR_SUCCESS;
if (Error != ERROR_SUCCESS)
{
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
goto Quit;
}
/* Open future HKEY_CURRENT_USER */
Error = RegOpenKeyExW(HKEY_USERS,
pszSid,
0,
MAXIMUM_ALLOWED,
phProfile);
if (Error != ERROR_SUCCESS)
{
DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
goto Quit;
}
Success = TRUE;
Quit:
LocalFree(pSid);
DPRINT1("ScmLogAccountsHack(%S) returned %s\n",
pszAccountName, Success ? "success" : "failure");
return Success;
}
static struct
{
LPCWSTR pszAccountName;
LPCWSTR pszSid;
HKEY hProfile;
} AccountHandles[] = {
// {L"LocalSystem" , L"S-1-5-18", NULL},
{L"LocalService" , L"S-1-5-19", NULL}, // L"NT AUTHORITY\\LocalService"
{L"NetworkService", L"S-1-5-20", NULL}, // L"NT AUTHORITY\\NetworkService"
};
static VOID
ScmCleanupServiceAccountsHack(VOID)
{
UINT i;
DPRINT1("ScmCleanupServiceAccountsHack()\n");
for (i = 0; i < ARRAYSIZE(AccountHandles); ++i)
{
if (AccountHandles[i].hProfile)
{
RegCloseKey(AccountHandles[i].hProfile);
AccountHandles[i].hProfile = NULL;
}
}
}
static BOOL
ScmApplyServiceAccountsHack(VOID)
{
UINT i;
DPRINT1("ScmApplyServiceAccountsHack()\n");
for (i = 0; i < ARRAYSIZE(AccountHandles); ++i)
{
if (!ScmLogAccountHack( AccountHandles[i].pszAccountName,
AccountHandles[i].pszSid,
&AccountHandles[i].hProfile))
{
ScmCleanupServiceAccountsHack();
return FALSE;
}
}
return TRUE;
}
/*************************** END OF HACK CORE-12541 ***************************/
int WINAPI
wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
@ -407,9 +235,6 @@ wWinMain(HINSTANCE hInstance,
*/
SetProcessShutdownParameters(480, SHUTDOWN_NORETRY);
/*** HACK CORE-12541: Apply service accounts HACK ***/
ScmApplyServiceAccountsHack();
/* Start auto-start services */
ScmAutoStartServices();
@ -429,9 +254,6 @@ wWinMain(HINSTANCE hInstance,
/* Wait until the shutdown event gets signaled */
WaitForSingleObject(hScmShutdownEvent, INFINITE);
/*** HACK CORE-12541: Cleanup service accounts HACK ***/
ScmCleanupServiceAccountsHack();
done:
ScmShutdownSecurity();