mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[SERVICES]: Add a *temporary* hack, as part of CORE-12541 and CORE-12279, that manually creates and loads the "LocalService" and "NetworkService" accounts and user profiles (and their registry hives), inspired from code from userenv.dll . This is done here until services can be correctly logged into the "LocalService" or "NetworkService" accounts (Eric is working on that), and their user profiles automatically properly created. When this is OK the hack will be removed and a proper call to "LoadUserProfile" in the code will be done where needed.
svn path=/trunk/; revision=73486
This commit is contained in:
parent
1de5731e1e
commit
a35a785b11
1 changed files with 178 additions and 0 deletions
|
@ -123,6 +123,178 @@ 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,
|
||||
|
@ -235,6 +407,9 @@ wWinMain(HINSTANCE hInstance,
|
|||
*/
|
||||
SetProcessShutdownParameters(480, SHUTDOWN_NORETRY);
|
||||
|
||||
/*** HACK CORE-12541: Apply service accounts HACK ***/
|
||||
ScmApplyServiceAccountsHack();
|
||||
|
||||
/* Start auto-start services */
|
||||
ScmAutoStartServices();
|
||||
|
||||
|
@ -254,6 +429,9 @@ wWinMain(HINSTANCE hInstance,
|
|||
/* Wait until the shutdown event gets signaled */
|
||||
WaitForSingleObject(hScmShutdownEvent, INFINITE);
|
||||
|
||||
/*** HACK CORE-12541: Cleanup service accounts HACK ***/
|
||||
ScmCleanupServiceAccountsHack();
|
||||
|
||||
done:
|
||||
ScmShutdownSecurity();
|
||||
|
||||
|
|
Loading…
Reference in a new issue