Author: hbelusca
Date: Sat Nov 24 00:53:01 2012
New Revision: 57754
URL:
http://svn.reactos.org/svn/reactos?rev=57754&view=rev
Log:
[SERVICES]
- (Re-)implement acquiring/releasing driver-loading and unloading privilege (Note: the two
privileges have the same name SE_LOAD_DRIVER_NAME).
- Rework the SCM initialization code. In particular, acquiring the starting lock MUST BE
done BEFORE starting the RPC server, otherwise, a program can try to start a service (and
during this operation, the global start lock is acquired by the SCM) DURING the
initialization of SCM, and in particular between the call to ScmStartRpcServer and
ScmAcquireServiceStartLock. The SCM would then see an already-acquired start lock at this
point and would fail to initialize. ==> This commit corrects this behaviour.
Modified:
trunk/reactos/base/system/services/driver.c
trunk/reactos/base/system/services/services.c
Modified: trunk/reactos/base/system/services/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/drive…
==============================================================================
--- trunk/reactos/base/system/services/driver.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/driver.c [iso-8859-1] Sat Nov 24 00:53:01 2012
@@ -16,6 +16,50 @@
/* 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
ScmLoadDriver(PSERVICE lpService)
{
@@ -40,18 +84,28 @@
RtlInitUnicodeString(&DriverPath,
pszDriverPath);
- /* FIXME: Acquire privilege */
-
DPRINT(" Path: %wZ\n", &DriverPath);
+
+ /* Acquire driver-loading privilege */
+ dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE);
+ if (dwError != ERROR_SUCCESS)
+ {
+ /* We encountered a failure, exit properly */
+ DPRINT1("SERVICES: Cannot acquire driver-loading privilege, error =
%lu\n", dwError);
+ goto done;
+ }
+
Status = NtLoadDriver(&DriverPath);
- /* FIXME: Release privilege */
+ /* Release driver-loading privilege */
+ EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
}
+done:
HeapFree(GetProcessHeap(), 0, pszDriverPath);
return dwError;
@@ -82,17 +136,26 @@
RtlInitUnicodeString(&DriverPath,
pszDriverPath);
- /* FIXME: Acquire privilege */
+ /* Acquire driver-unloading privilege */
+ dwError = EnablePrivilege(SE_LOAD_DRIVER_NAME, TRUE);
+ if (dwError != ERROR_SUCCESS)
+ {
+ /* We encountered a failure, exit properly */
+ DPRINT1("SERVICES: Cannot acquire driver-unloading privilege, error =
%lu\n", dwError);
+ goto done;
+ }
Status = NtUnloadDriver(&DriverPath);
- /* FIXME: Release privilege */
+ /* Release driver-unloading privilege */
+ EnablePrivilege(SE_LOAD_DRIVER_NAME, FALSE);
if (!NT_SUCCESS(Status))
{
dwError = RtlNtStatusToDosError(Status);
}
+done:
HeapFree(GetProcessHeap(), 0, pszDriverPath);
return dwError;
Modified: trunk/reactos/base/system/services/services.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/servi…
==============================================================================
--- trunk/reactos/base/system/services/services.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/services.c [iso-8859-1] Sat Nov 24 00:53:01 2012
@@ -327,28 +327,6 @@
}
-VOID FASTCALL
-AcquireLoadDriverPrivilege(VOID)
-{
- HANDLE hToken;
- TOKEN_PRIVILEGES tkp;
-
- /* Get a token for this process */
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken))
- {
- /* Get the LUID for the debug privilege */
- LookupPrivilegeValue(NULL, SE_LOAD_DRIVER_NAME, &tkp.Privileges[0].Luid);
-
- /* One privilege to set */
- tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-
- /* Get the debug privilege for this process */
- AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
- }
-}
-
-
BOOL WINAPI
ShutdownHandlerRoutine(DWORD dwCtrlType)
{
@@ -378,7 +356,7 @@
{
HANDLE hScmStartEvent = NULL;
SC_RPC_LOCK Lock = NULL;
- BOOL bDeleteCriticalSection = FALSE;
+ BOOL bCanDeleteNamedPipeCriticalSection = FALSE;
DWORD dwError;
DPRINT("SERVICES: Service Control Manager\n");
@@ -400,6 +378,10 @@
goto done;
}
+ /* Initialize our communication named pipe's critical section */
+ ScmInitNamedPipeCriticalSection();
+ bCanDeleteNamedPipeCriticalSection = TRUE;
+
// ScmInitThreadManager();
/* FIXME: more initialization */
@@ -422,28 +404,8 @@
/* Update service database */
ScmGetBootAndSystemDriverState();
- /* Start the RPC server */
- ScmStartRpcServer();
-
/* Register service process with CSRSS */
RegisterServicesProcess(GetCurrentProcessId());
-
- DPRINT("SERVICES: Initialized.\n");
-
- /* Signal start event */
- SetEvent(hScmStartEvent);
-
- /* Register event handler (used for system shutdown) */
- SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
-
- /* Wait for the LSA server */
- ScmWaitForLsa();
-
- /* Acquire privileges to load drivers */
- AcquireLoadDriverPrivilege();
-
- ScmInitNamedPipeCriticalSection();
- bDeleteCriticalSection = TRUE;
/* Acquire the service start lock until autostart services have been started */
dwError = ScmAcquireServiceStartLock(TRUE, &Lock);
@@ -453,6 +415,20 @@
goto done;
}
+ /* Start the RPC server */
+ ScmStartRpcServer();
+
+ DPRINT("SERVICES: Initialized.\n");
+
+ /* Signal start event */
+ SetEvent(hScmStartEvent);
+
+ /* Register event handler (used for system shutdown) */
+ SetConsoleCtrlHandler(ShutdownHandlerRoutine, TRUE);
+
+ /* Wait for the LSA server */
+ ScmWaitForLsa();
+
/* Start auto-start services */
ScmAutoStartServices();
@@ -467,7 +443,8 @@
WaitForSingleObject(hScmShutdownEvent, INFINITE);
done:
- if (bDeleteCriticalSection == TRUE)
+ /* Delete our communication named pipe's critical section */
+ if (bCanDeleteNamedPipeCriticalSection == TRUE)
ScmDeleteNamedPipeCriticalSection();
/* Close the shutdown event */