mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
764 lines
21 KiB
764 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
data.c
|
|
|
|
Abstract:
|
|
|
|
This module contains global data for SAC.
|
|
|
|
Author:
|
|
|
|
Sean Selitrennikoff (v-seans) - Jan 11, 1999
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "sac.h"
|
|
|
|
NTSTATUS
|
|
CreateAdminSecurityDescriptor(
|
|
IN PSAC_DEVICE_CONTEXT DeviceContext
|
|
);
|
|
|
|
NTSTATUS
|
|
BuildDeviceAcl(
|
|
OUT PACL *DeviceAcl
|
|
);
|
|
|
|
VOID
|
|
WorkerThreadStartUp(
|
|
IN PVOID StartContext
|
|
);
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( INIT, InitializeGlobalData)
|
|
#pragma alloc_text( INIT, CreateAdminSecurityDescriptor )
|
|
#pragma alloc_text( INIT, BuildDeviceAcl )
|
|
#endif
|
|
|
|
//
|
|
// Globally defined variables are here.
|
|
//
|
|
BOOLEAN GlobalDataInitialized = FALSE;
|
|
UCHAR TmpBuffer[sizeof(PROCESS_PRIORITY_CLASS)];
|
|
BOOLEAN IoctlSubmitted;
|
|
LONG ProcessingType;
|
|
HANDLE SACEventHandle;
|
|
PKEVENT SACEvent=NULL;
|
|
LONG Attempts;
|
|
|
|
#if DBG
|
|
ULONG SACDebug = 0x0;
|
|
#endif
|
|
|
|
|
|
BOOLEAN
|
|
InitializeGlobalData(
|
|
IN PUNICODE_STRING RegistryPath,
|
|
IN PDRIVER_OBJECT DriverObject
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes all the driver components that are shared across devices.
|
|
|
|
Arguments:
|
|
|
|
RegistryPath - A pointer to the location in the registry to read values from.
|
|
DriverObject - pointer to DriverObject
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, else FALSE
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
UNICODE_STRING DosName;
|
|
UNICODE_STRING NtName;
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
UNREFERENCED_PARAMETER(RegistryPath);
|
|
|
|
PAGED_CODE();
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeGlobalData: Entering.\n")));
|
|
|
|
if (!GlobalDataInitialized) {
|
|
|
|
//
|
|
// Create a symbolic link from a DosDevice to this device so that a user-mode app can open us.
|
|
//
|
|
RtlInitUnicodeString(&DosName, SAC_DOSDEVICE_NAME);
|
|
RtlInitUnicodeString(&NtName, SAC_DEVICE_NAME);
|
|
Status = IoCreateSymbolicLink(&DosName, &NtName);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Initialize internal memory system
|
|
//
|
|
if (!InitializeMemoryManagement()) {
|
|
|
|
IoDeleteSymbolicLink(&DosName);
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeGlobalData: Exiting with status FALSE\n")));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
Status = PreloadGlobalMessageTable(DriverObject->DriverStart);
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
IoDeleteSymbolicLink(&DosName);
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(( "SAC DriverEntry: unable to pre-load message table: %X\n", Status )));
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Utf8ConversionBuffer = (PUCHAR)ALLOCATE_POOL(MEMORY_INCREMENT, GENERAL_POOL_TAG);
|
|
if (!Utf8ConversionBuffer) {
|
|
|
|
TearDownGlobalMessageTable();
|
|
|
|
IoDeleteSymbolicLink(&DosName);
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(( "SAC DriverEntry: unable to allocate memory for UTF8 translation." )));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
GlobalDataInitialized = TRUE;
|
|
ProcessingType = SAC_NO_OP;
|
|
IoctlSubmitted = FALSE;
|
|
Attempts = 0;
|
|
|
|
//
|
|
// Setup notification event
|
|
//
|
|
RtlInitUnicodeString(&UnicodeString, L"\\SACEvent");
|
|
SACEvent = IoCreateSynchronizationEvent(&UnicodeString, &SACEventHandle);
|
|
|
|
if (SACEvent == NULL) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeGlobalData: Exiting with Event NULL\n")));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Retrieve all the machine-specific identification information.
|
|
//
|
|
InitializeMachineInformation();
|
|
|
|
}
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeGlobalData: Exiting with status TRUE\n")));
|
|
|
|
return TRUE;
|
|
} // InitializeGlobalData
|
|
|
|
|
|
VOID
|
|
FreeGlobalData(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees all shared components.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
UNICODE_STRING DosName;
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeGlobalData: Entering.\n")));
|
|
|
|
if (GlobalDataInitialized) {
|
|
if(SACEvent != NULL){
|
|
ZwClose(SACEventHandle);
|
|
SACEvent = NULL;
|
|
}
|
|
|
|
TearDownGlobalMessageTable();
|
|
|
|
RtlInitUnicodeString(&DosName, SAC_DOSDEVICE_NAME);
|
|
IoDeleteSymbolicLink(&DosName);
|
|
|
|
FreeMemoryManagement();
|
|
GlobalDataInitialized = FALSE;
|
|
}
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeGlobalData: Exiting.\n")));
|
|
|
|
} // FreeGlobalData
|
|
|
|
|
|
BOOLEAN
|
|
InitializeDeviceData(
|
|
PDEVICE_OBJECT DeviceObject
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine initializes all the parts specific for each device.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - pointer to device object to be initialized.
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, else FALSE
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
LARGE_INTEGER Time;
|
|
LONG Priority;
|
|
HEADLESS_CMD_ENABLE_TERMINAL Command;
|
|
PSAC_DEVICE_CONTEXT DeviceContext;
|
|
|
|
PAGED_CODE();
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Entering.\n")));
|
|
|
|
DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension;
|
|
|
|
if (!DeviceContext->InitializedAndReady) {
|
|
|
|
DeviceObject->StackSize = DEFAULT_IRP_STACK_SIZE;
|
|
DeviceObject->Flags |= DO_DIRECT_IO;
|
|
|
|
DeviceContext->DeviceObject = DeviceObject;
|
|
DeviceContext->PriorityBoost = DEFAULT_PRIORITY_BOOST;
|
|
DeviceContext->AdminSecurityDescriptor = NULL;
|
|
DeviceContext->UnloadDeferred = FALSE;
|
|
DeviceContext->Processing = FALSE;
|
|
|
|
KeInitializeTimer(&(DeviceContext->Timer));
|
|
|
|
KeInitializeDpc(&(DeviceContext->Dpc), &TimerDpcRoutine, DeviceContext);
|
|
|
|
KeInitializeSpinLock(&(DeviceContext->SpinLock));
|
|
|
|
KeInitializeEvent(&(DeviceContext->ProcessEvent), SynchronizationEvent, FALSE);
|
|
|
|
//
|
|
// Enable the terminal
|
|
//
|
|
Command.Enable = TRUE;
|
|
Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
|
|
&Command,
|
|
sizeof(HEADLESS_CMD_ENABLE_TERMINAL),
|
|
NULL,
|
|
NULL
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Exiting (1) with status FALSE\n")));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Remember a pointer to the system process. We'll use this pointer
|
|
// for KeAttachProcess() calls so that we can open handles in the
|
|
// context of the system process.
|
|
//
|
|
DeviceContext->SystemProcess = (PKPROCESS)IoGetCurrentProcess();
|
|
|
|
//
|
|
// Create the security descriptor used for raw access checks.
|
|
//
|
|
Status = CreateAdminSecurityDescriptor(DeviceContext);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Exiting (2) with status FALSE\n")));
|
|
Command.Enable = FALSE;
|
|
HeadlessDispatch(HeadlessCmdEnableTerminal,
|
|
&Command,
|
|
sizeof(HEADLESS_CMD_ENABLE_TERMINAL),
|
|
NULL,
|
|
NULL
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Start a thread to handle requests
|
|
//
|
|
Status = PsCreateSystemThread(&(DeviceContext->ThreadHandle),
|
|
PROCESS_ALL_ACCESS,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
WorkerThreadStartUp,
|
|
DeviceContext
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Exiting (3) with status FALSE\n")));
|
|
Command.Enable = FALSE;
|
|
HeadlessDispatch(HeadlessCmdEnableTerminal,
|
|
&Command,
|
|
sizeof(HEADLESS_CMD_ENABLE_TERMINAL),
|
|
NULL,
|
|
NULL
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Set this thread to the real-time highest priority so that it will be
|
|
// responsive.
|
|
//
|
|
Priority = HIGH_PRIORITY;
|
|
Status = NtSetInformationThread(DeviceContext->ThreadHandle,
|
|
ThreadPriority,
|
|
&Priority,
|
|
sizeof(Priority)
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Exiting (6) with status FALSE\n")));
|
|
|
|
//
|
|
// Tell thread to exit.
|
|
//
|
|
DeviceContext->UnloadDeferred = TRUE;
|
|
KeInitializeEvent(&(DeviceContext->UnloadEvent), SynchronizationEvent, FALSE);
|
|
KeSetEvent(&(DeviceContext->ProcessEvent), DeviceContext->PriorityBoost, FALSE);
|
|
Status = KeWaitForSingleObject((PVOID)&(DeviceContext->UnloadEvent), Executive, KernelMode, FALSE, NULL);
|
|
ASSERT(Status == STATUS_SUCCESS);
|
|
|
|
Command.Enable = FALSE;
|
|
HeadlessDispatch(HeadlessCmdEnableTerminal,
|
|
&Command,
|
|
sizeof(HEADLESS_CMD_ENABLE_TERMINAL),
|
|
NULL,
|
|
NULL
|
|
);
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Start our timer
|
|
//
|
|
Time.QuadPart = Int32x32To64((LONG)100, -1000); // 100ms from now.
|
|
KeSetTimerEx(&(DeviceContext->Timer), Time, (LONG)100, &(DeviceContext->Dpc)); // every 100ms
|
|
|
|
//
|
|
// Display the prompt
|
|
//
|
|
SacPutSimpleMessage( SAC_ENTER );
|
|
SacPutSimpleMessage( SAC_INITIALIZED );
|
|
SacPutSimpleMessage( SAC_ENTER );
|
|
SacPutSimpleMessage( SAC_PROMPT );
|
|
|
|
DeviceContext->InitializedAndReady = TRUE;
|
|
|
|
|
|
}
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC InitializeDeviceData: Exiting with status TRUE\n")));
|
|
|
|
return TRUE;
|
|
} // InitializeDeviceData
|
|
|
|
|
|
VOID
|
|
FreeDeviceData(
|
|
PDEVICE_OBJECT DeviceObject
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine frees all components specific to a device..
|
|
|
|
Arguments:
|
|
|
|
DeviceContext - The device to work on.
|
|
|
|
Return Value:
|
|
|
|
It will stop and wait, if necessary, for any processing to complete.
|
|
|
|
--*/
|
|
|
|
{
|
|
KIRQL OldIrql;
|
|
NTSTATUS Status;
|
|
PVOID MemToFree;
|
|
PSAC_DEVICE_CONTEXT DeviceContext;
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeDeviceData: Entering.\n")));
|
|
|
|
DeviceContext = (PSAC_DEVICE_CONTEXT)DeviceObject->DeviceExtension;
|
|
|
|
if (!GlobalDataInitialized || !DeviceContext->InitializedAndReady) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeDeviceData: Exiting.\n")));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Wait for all processing to complete
|
|
//
|
|
KeAcquireSpinLock(&(DeviceContext->SpinLock), &OldIrql);
|
|
|
|
DeviceContext->UnloadDeferred = TRUE;
|
|
|
|
while (DeviceContext->Processing) {
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeDeviceData: Waiting....\n")));
|
|
|
|
KeInitializeEvent(&(DeviceContext->UnloadEvent), SynchronizationEvent, FALSE);
|
|
|
|
KeReleaseSpinLock(&(DeviceContext->SpinLock), OldIrql);
|
|
|
|
Status = KeWaitForSingleObject((PVOID)&(DeviceContext->UnloadEvent), Executive, KernelMode, FALSE, NULL);
|
|
|
|
ASSERT(Status == STATUS_SUCCESS);
|
|
|
|
KeAcquireSpinLock(&(DeviceContext->SpinLock), &OldIrql);
|
|
|
|
}
|
|
|
|
DeviceContext->Processing = TRUE;
|
|
|
|
KeReleaseSpinLock(&(DeviceContext->SpinLock), OldIrql);
|
|
|
|
KeCancelTimer(&(DeviceContext->Timer));
|
|
|
|
KeAcquireSpinLock(&(DeviceContext->SpinLock), &OldIrql);
|
|
|
|
DeviceContext->Processing = FALSE;
|
|
|
|
MemToFree = (PVOID)DeviceContext->AdminSecurityDescriptor;
|
|
DeviceContext->AdminSecurityDescriptor = NULL;
|
|
|
|
|
|
//
|
|
// Signal the thread to exit
|
|
//
|
|
KeInitializeEvent(&(DeviceContext->UnloadEvent), SynchronizationEvent, FALSE);
|
|
KeReleaseSpinLock(&(DeviceContext->SpinLock), OldIrql);
|
|
KeSetEvent(&(DeviceContext->ProcessEvent), DeviceContext->PriorityBoost, FALSE);
|
|
|
|
Status = KeWaitForSingleObject((PVOID)&(DeviceContext->UnloadEvent), Executive, KernelMode, FALSE, NULL);
|
|
ASSERT(Status == STATUS_SUCCESS);
|
|
|
|
//
|
|
// Finish up cleaning up.
|
|
//
|
|
IoUnregisterShutdownNotification(DeviceObject);
|
|
|
|
KeAcquireSpinLock(&(DeviceContext->SpinLock), &OldIrql);
|
|
|
|
DeviceContext->InitializedAndReady = FALSE;
|
|
DeviceContext->UnloadDeferred = FALSE;
|
|
|
|
KeReleaseSpinLock(&(DeviceContext->SpinLock), OldIrql);
|
|
|
|
if (MemToFree != NULL) {
|
|
ExFreePool(MemToFree);
|
|
}
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC FreeDeviceData: Exiting.\n")));
|
|
} // FreeDeviceData
|
|
|
|
|
|
NTSTATUS
|
|
BuildDeviceAcl(
|
|
OUT PACL *DeviceAcl
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine builds an ACL which gives Administrators and LocalSystem
|
|
principals full access. All other principals have no access.
|
|
|
|
Arguments:
|
|
|
|
DeviceAcl - Output pointer to the new ACL.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS or an appropriate error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
PGENERIC_MAPPING GenericMapping;
|
|
PSID AdminsSid;
|
|
PSID SystemSid;
|
|
ULONG AclLength;
|
|
NTSTATUS Status;
|
|
ACCESS_MASK AccessMask = GENERIC_ALL;
|
|
PACL NewAcl;
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE, KdPrint(("SAC BuildDeviceAcl: Entering.\n")));
|
|
|
|
//
|
|
// Enable access to all the globally defined SIDs
|
|
//
|
|
|
|
GenericMapping = IoGetFileObjectGenericMapping();
|
|
|
|
RtlMapGenericMask(&AccessMask, GenericMapping);
|
|
|
|
//SeEnableAccessToExports();
|
|
|
|
AdminsSid = SeExports->SeAliasAdminsSid;
|
|
SystemSid = SeExports->SeLocalSystemSid;
|
|
|
|
AclLength = sizeof(ACL) + (2 * sizeof(ACCESS_ALLOWED_ACE)) +
|
|
RtlLengthSid(AdminsSid) + RtlLengthSid(SystemSid) -
|
|
(2 * sizeof(ULONG));
|
|
|
|
NewAcl = ALLOCATE_POOL(AclLength, SECURITY_POOL_TAG);
|
|
|
|
if (NewAcl == NULL) {
|
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|
}
|
|
|
|
Status = RtlCreateAcl(NewAcl, AclLength, ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
FREE_POOL(&NewAcl);
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC BuildDeviceAcl: Exiting with status 0x%x\n", Status)));
|
|
return(Status);
|
|
}
|
|
|
|
Status = RtlAddAccessAllowedAce(NewAcl,
|
|
ACL_REVISION2,
|
|
AccessMask,
|
|
AdminsSid
|
|
);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
Status = RtlAddAccessAllowedAce(NewAcl,
|
|
ACL_REVISION2,
|
|
AccessMask,
|
|
SystemSid
|
|
);
|
|
|
|
ASSERT(NT_SUCCESS(Status));
|
|
|
|
*DeviceAcl = NewAcl;
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC BuildDeviceAcl: Exiting with status 0x%x\n", STATUS_SUCCESS)));
|
|
return(STATUS_SUCCESS);
|
|
|
|
} // BuildDeviceAcl
|
|
|
|
|
|
NTSTATUS
|
|
CreateAdminSecurityDescriptor(
|
|
PSAC_DEVICE_CONTEXT DeviceContext
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine creates a security descriptor which gives access
|
|
only to Administrtors and LocalSystem. This descriptor is used
|
|
to access check raw endpoint opens and exclisive access to transport
|
|
addresses.
|
|
|
|
Arguments:
|
|
|
|
DeviceContext - A pointer to the device to work on.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS or an appropriate error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
PACL RawAcl = NULL;
|
|
NTSTATUS Status;
|
|
BOOLEAN MemoryAllocated = FALSE;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
|
ULONG SecurityDescriptorLength;
|
|
CHAR Buffer[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
|
PSECURITY_DESCRIPTOR LocalSecurityDescriptor = (PSECURITY_DESCRIPTOR) &Buffer;
|
|
PSECURITY_DESCRIPTOR LocalAdminSecurityDescriptor;
|
|
SECURITY_INFORMATION SecurityInformation = DACL_SECURITY_INFORMATION;
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC CreateAdminSecDesc: Entering.\n")));
|
|
|
|
//
|
|
// Get a pointer to the security descriptor from the device object.
|
|
//
|
|
Status = ObGetObjectSecurity(DeviceContext->DeviceObject,
|
|
&SecurityDescriptor,
|
|
&MemoryAllocated
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(("SAC: Unable to get security descriptor, error: %x\n", Status)));
|
|
ASSERT(MemoryAllocated == FALSE);
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC CreateAdminSecDesc: Exiting with status 0x%x\n", Status)));
|
|
return(Status);
|
|
}
|
|
|
|
//
|
|
// Build a local security descriptor with an ACL giving only
|
|
// administrators and system access.
|
|
//
|
|
Status = BuildDeviceAcl(&RawAcl);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(("SAC CreateAdminSecDesc: Unable to create Raw ACL, error: %x\n", Status)));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
(VOID)RtlCreateSecurityDescriptor(LocalSecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION
|
|
);
|
|
|
|
(VOID)RtlSetDaclSecurityDescriptor(LocalSecurityDescriptor,
|
|
TRUE,
|
|
RawAcl,
|
|
FALSE
|
|
);
|
|
|
|
//
|
|
// Make a copy of the security descriptor. This copy will be the raw descriptor.
|
|
//
|
|
SecurityDescriptorLength = RtlLengthSecurityDescriptor(SecurityDescriptor);
|
|
|
|
LocalAdminSecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
|
|
SecurityDescriptorLength,
|
|
SECURITY_POOL_TAG
|
|
);
|
|
|
|
if (LocalAdminSecurityDescriptor == NULL) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(("SAC CreateAdminSecDesc: couldn't allocate security descriptor\n")));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
RtlMoveMemory(LocalAdminSecurityDescriptor,
|
|
SecurityDescriptor,
|
|
SecurityDescriptorLength
|
|
);
|
|
|
|
DeviceContext->AdminSecurityDescriptor = LocalAdminSecurityDescriptor;
|
|
|
|
//
|
|
// Now apply the local descriptor to the raw descriptor.
|
|
//
|
|
Status = SeSetSecurityDescriptorInfo(NULL,
|
|
&SecurityInformation,
|
|
LocalSecurityDescriptor,
|
|
&(DeviceContext->AdminSecurityDescriptor),
|
|
NonPagedPool,
|
|
IoGetFileObjectGenericMapping()
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
IF_SAC_DEBUG(SAC_DEBUG_FAILS,
|
|
KdPrint(("SAC CreateAdminSecDesc: SeSetSecurity failed, %lx\n", Status)));
|
|
ASSERT(DeviceContext->AdminSecurityDescriptor == LocalAdminSecurityDescriptor);
|
|
ExFreePool(DeviceContext->AdminSecurityDescriptor);
|
|
DeviceContext->AdminSecurityDescriptor = NULL;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (DeviceContext->AdminSecurityDescriptor != LocalAdminSecurityDescriptor) {
|
|
ExFreePool(LocalAdminSecurityDescriptor);
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
ErrorExit:
|
|
|
|
ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
|
|
|
|
if (RawAcl != NULL) {
|
|
FREE_POOL(&RawAcl);
|
|
}
|
|
|
|
IF_SAC_DEBUG(SAC_DEBUG_FUNC_TRACE,
|
|
KdPrint(("SAC CreateAdminSecDesc: Exiting with status 0x%x\n", Status)));
|
|
|
|
return(Status);
|
|
}
|
|
|
|
VOID
|
|
WorkerThreadStartUp(
|
|
IN PVOID StartContext
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the start up routine for the worker thread. It justn
|
|
sends the worker thread to the processing routine.
|
|
|
|
Arguments:
|
|
|
|
StartContext - A pointer to the device to work on.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
WorkerProcessEvents((PSAC_DEVICE_CONTEXT)StartContext);
|
|
}
|
|
|