[SERVICES]

Fix acquiring/releasing driver-loading and unloading privilege (see r57754) by using the RtlAdjustPrivilege API instead of using the standard user-mode Win32 API (thus get rid of calling LSA when calling LookupPrivilegeValueW).

svn path=/trunk/; revision=58233
This commit is contained in:
Hermès Bélusca-Maïto 2013-01-26 23:14:05 +00:00
parent 705173ebd5
commit 4ad0f2245b
2 changed files with 29 additions and 70 deletions

View file

@ -16,57 +16,13 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static DWORD EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
{
DWORD dwRet = ERROR_SUCCESS;
HANDLE hToken = NULL;
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES,
&hToken))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
if (LookupPrivilegeValueW(NULL,
lpszPrivilegeName,
&tp.Privileges[0].Luid))
{
if (AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
{
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
dwRet = ERROR_NOT_ALL_ASSIGNED;
}
else
{
dwRet = GetLastError();
}
}
else
{
dwRet = GetLastError();
}
CloseHandle(hToken);
}
else
{
dwRet = GetLastError();
}
return dwRet;
}
DWORD DWORD
ScmLoadDriver(PSERVICE lpService) ScmLoadDriver(PSERVICE lpService)
{ {
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN WasPrivilegeEnabled = FALSE;
PWSTR pszDriverPath; PWSTR pszDriverPath;
UNICODE_STRING DriverPath; UNICODE_STRING DriverPath;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */ /* Build the driver path */
/* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */ /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
@ -87,38 +43,38 @@ ScmLoadDriver(PSERVICE lpService)
DPRINT(" Path: %wZ\n", &DriverPath); DPRINT(" Path: %wZ\n", &DriverPath);
/* Acquire driver-loading privilege */ /* Acquire driver-loading privilege */
dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
if (dwError != ERROR_SUCCESS) TRUE,
FALSE,
&WasPrivilegeEnabled);
if (!NT_SUCCESS(Status))
{ {
/* We encountered a failure, exit properly */ /* We encountered a failure, exit properly */
DPRINT1("SERVICES: Cannot acquire driver-loading privilege, error = %lu\n", dwError); DPRINT1("SERVICES: Cannot acquire driver-loading privilege, Status = 0x%08lx\n", Status);
goto done; goto done;
} }
Status = NtLoadDriver(&DriverPath); Status = NtLoadDriver(&DriverPath);
/* Release driver-loading privilege */ /* Release driver-loading privilege */
EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
WasPrivilegeEnabled,
if (!NT_SUCCESS(Status)) FALSE,
{ &WasPrivilegeEnabled);
dwError = RtlNtStatusToDosError(Status);
}
done: done:
HeapFree(GetProcessHeap(), 0, pszDriverPath); HeapFree(GetProcessHeap(), 0, pszDriverPath);
return RtlNtStatusToDosError(Status);
return dwError;
} }
DWORD DWORD
ScmUnloadDriver(PSERVICE lpService) ScmUnloadDriver(PSERVICE lpService)
{ {
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN WasPrivilegeEnabled = FALSE;
PWSTR pszDriverPath; PWSTR pszDriverPath;
UNICODE_STRING DriverPath; UNICODE_STRING DriverPath;
NTSTATUS Status;
DWORD dwError = ERROR_SUCCESS;
/* Build the driver path */ /* Build the driver path */
/* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */ /* 52 = wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") */
@ -136,29 +92,31 @@ ScmUnloadDriver(PSERVICE lpService)
RtlInitUnicodeString(&DriverPath, RtlInitUnicodeString(&DriverPath,
pszDriverPath); pszDriverPath);
DPRINT(" Path: %wZ\n", &DriverPath);
/* Acquire driver-unloading privilege */ /* Acquire driver-unloading privilege */
dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE); Status = RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
if (dwError != ERROR_SUCCESS) TRUE,
FALSE,
&WasPrivilegeEnabled);
if (!NT_SUCCESS(Status))
{ {
/* We encountered a failure, exit properly */ /* We encountered a failure, exit properly */
DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, error = %lu\n", dwError); DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, Status = 0x%08lx\n", Status);
goto done; goto done;
} }
Status = NtUnloadDriver(&DriverPath); Status = NtUnloadDriver(&DriverPath);
/* Release driver-unloading privilege */ /* Release driver-unloading privilege */
EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE); RtlAdjustPrivilege(SE_LOAD_DRIVER_PRIVILEGE,
WasPrivilegeEnabled,
if (!NT_SUCCESS(Status)) FALSE,
{ &WasPrivilegeEnabled);
dwError = RtlNtStatusToDosError(Status);
}
done: done:
HeapFree(GetProcessHeap(), 0, pszDriverPath); HeapFree(GetProcessHeap(), 0, pszDriverPath);
return RtlNtStatusToDosError(Status);
return dwError;
} }

View file

@ -14,6 +14,7 @@
#include <ndk/iofuncs.h> #include <ndk/iofuncs.h>
#include <ndk/obfuncs.h> #include <ndk/obfuncs.h>
#include <ndk/rtlfuncs.h> #include <ndk/rtlfuncs.h>
#include <ndk/setypes.h>
#include <services/services.h> #include <services/services.h>
#include <svcctl_s.h> #include <svcctl_s.h>