https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c6a53810a4b76317370b6f...
commit c6a53810a4b76317370b6f30d143361a7b6d26ab Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Mon Aug 5 20:18:17 2019 +0200 Commit: Eric Kohl eric.kohl@reactos.org CommitDate: Mon Aug 5 20:20:48 2019 +0200
[SERVICES] Enable the backup and restore privileges before loading or unloading a user profile and then disable them again. --- base/system/services/database.c | 63 +++++++++++++++++++++++++++++++++++++++-- base/system/services/services.h | 1 + 2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/base/system/services/database.c b/base/system/services/database.c index 7c41c54eb9f..622bdf0c847 100644 --- a/base/system/services/database.c +++ b/base/system/services/database.c @@ -279,18 +279,65 @@ ScmIsLocalSystemAccount( }
+static +BOOL +ScmEnableBackupRestorePrivileges( + _In_ HANDLE hToken, + _In_ BOOL bEnable) +{ + PTOKEN_PRIVILEGES pTokenPrivileges = NULL; + DWORD dwSize; + BOOL bRet = FALSE; + + DPRINT("ScmEnableBackupRestorePrivileges(%p %d)\n", hToken, bEnable); + + dwSize = sizeof(TOKEN_PRIVILEGES) + 2 * sizeof(LUID_AND_ATTRIBUTES); + pTokenPrivileges = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); + if (pTokenPrivileges == NULL) + { + DPRINT1("Failed to allocate the privilege buffer!\n"); + goto done; + } + + pTokenPrivileges->PrivilegeCount = 2; + pTokenPrivileges->Privileges[0].Luid.LowPart = SE_BACKUP_PRIVILEGE; + pTokenPrivileges->Privileges[0].Luid.HighPart = 0; + pTokenPrivileges->Privileges[0].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0); + pTokenPrivileges->Privileges[1].Luid.LowPart = SE_RESTORE_PRIVILEGE; + pTokenPrivileges->Privileges[1].Luid.HighPart = 0; + pTokenPrivileges->Privileges[1].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0); + + bRet = AdjustTokenPrivileges(hToken, FALSE, pTokenPrivileges, 0, NULL, NULL); + if (!bRet) + { + DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError()); + } + else if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) + { + DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n"); + bRet = FALSE; + } + +done: + if (pTokenPrivileges != NULL) + HeapFree(GetProcessHeap(), 0, pTokenPrivileges); + + return bRet; +} + + static DWORD ScmLogonService( IN PSERVICE pService, IN PSERVICE_IMAGE pImage) { - DWORD dwError = ERROR_SUCCESS; PROFILEINFOW ProfileInfo; PWSTR pszUserName = NULL; PWSTR pszDomainName = NULL; PWSTR pszPassword = NULL; PWSTR ptr; + DWORD dwError = ERROR_SUCCESS;
DPRINT("ScmLogonService(%p %p)\n", pService, pImage); DPRINT("Service %S\n", pService->lpServiceName); @@ -355,9 +402,13 @@ ScmLogonService( // ProfileInfo.lpPolicyPath = NULL; // ProfileInfo.hProfile = NULL;
+ ScmEnableBackupRestorePrivileges(pImage->hToken, TRUE); if (!LoadUserProfileW(pImage->hToken, &ProfileInfo)) - { dwError = GetLastError(); + ScmEnableBackupRestorePrivileges(pImage->hToken, FALSE); + + if (dwError != ERROR_SUCCESS) + { DPRINT1("LoadUserProfileW() failed (Error %lu)\n", dwError); goto done; } @@ -475,7 +526,11 @@ ScmCreateOrReferenceServiceImage(PSERVICE pService)
/* Unload the user profile */ if (pServiceImage->hProfile != NULL) + { + ScmEnableBackupRestorePrivileges(pServiceImage->hToken, TRUE); UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile); + ScmEnableBackupRestorePrivileges(pServiceImage->hToken, FALSE); + }
/* Close the logon token */ if (pServiceImage->hToken != NULL) @@ -546,7 +601,11 @@ ScmRemoveServiceImage(PSERVICE_IMAGE pServiceImage)
/* Unload the user profile */ if (pServiceImage->hProfile != NULL) + { + ScmEnableBackupRestorePrivileges(pServiceImage->hToken, TRUE); UnloadUserProfile(pServiceImage->hToken, pServiceImage->hProfile); + ScmEnableBackupRestorePrivileges(pServiceImage->hToken, FALSE); + }
/* Close the logon token */ if (pServiceImage->hToken != NULL) diff --git a/base/system/services/services.h b/base/system/services/services.h index 4a1a0c0827c..647df6a0da0 100644 --- a/base/system/services/services.h +++ b/base/system/services/services.h @@ -19,6 +19,7 @@ #include <winuser.h> #include <netevent.h> #define NTOS_MODE_USER +#include <ndk/setypes.h> #include <ndk/obfuncs.h> #include <ndk/rtlfuncs.h> #include <services/services.h>