mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Fix IopSecurityFile: Do not use BuildFsd, create IRP manually for sync/async, support assigning SD to device instead of file, and signal unimplemented set sd to device, simplify code for file object setting and remove duplication, wait on right event and return the matching status. moved static io security function to se subsystem and renamed it from default to world to better match what it's doing
svn path=/trunk/; revision=15177
This commit is contained in:
parent
db63a3b1ad
commit
834acf81da
2 changed files with 217 additions and 165 deletions
|
@ -21,6 +21,12 @@
|
||||||
|
|
||||||
extern GENERIC_MAPPING IopFileMapping;
|
extern GENERIC_MAPPING IopFileMapping;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
PULONG BufferLength);
|
||||||
|
|
||||||
/* INTERNAL FUNCTIONS ********************************************************/
|
/* INTERNAL FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -226,7 +232,7 @@ IopDeleteFile(PVOID ObjectBody)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
}
|
}
|
||||||
IoFreeIrp(Irp);
|
IoFreeIrp(Irp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,76 +251,6 @@ IopDeleteFile(PVOID ObjectBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
NTSTATUS
|
|
||||||
IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
||||||
PULONG BufferLength)
|
|
||||||
{
|
|
||||||
ULONG_PTR Current;
|
|
||||||
ULONG SidSize;
|
|
||||||
ULONG SdSize;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
DPRINT("IopSetDefaultSecurityDescriptor() called\n");
|
|
||||||
|
|
||||||
if (SecurityInformation == 0)
|
|
||||||
{
|
|
||||||
return STATUS_ACCESS_DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
SidSize = RtlLengthSid(SeWorldSid);
|
|
||||||
SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
|
|
||||||
|
|
||||||
if (*BufferLength < SdSize)
|
|
||||||
{
|
|
||||||
*BufferLength = SdSize;
|
|
||||||
return STATUS_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*BufferLength = SdSize;
|
|
||||||
|
|
||||||
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
|
|
||||||
SECURITY_DESCRIPTOR_REVISION);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityDescriptor->Control |= SE_SELF_RELATIVE;
|
|
||||||
Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
|
|
||||||
|
|
||||||
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
|
||||||
{
|
|
||||||
RtlCopyMemory((PVOID)Current,
|
|
||||||
SeWorldSid,
|
|
||||||
SidSize);
|
|
||||||
SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
|
||||||
Current += SidSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
|
||||||
{
|
|
||||||
RtlCopyMemory((PVOID)Current,
|
|
||||||
SeWorldSid,
|
|
||||||
SidSize);
|
|
||||||
SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
|
||||||
Current += SidSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
|
||||||
{
|
|
||||||
SecurityDescriptor->Control |= SE_DACL_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
|
||||||
{
|
|
||||||
SecurityDescriptor->Control |= SE_SACL_PRESENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
IopSecurityFile(PVOID ObjectBody,
|
IopSecurityFile(PVOID ObjectBody,
|
||||||
|
@ -323,105 +259,151 @@ IopSecurityFile(PVOID ObjectBody,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
PULONG BufferLength)
|
PULONG BufferLength)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIRP Irp;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
NTSTATUS Status;
|
ULONG MajorFunction;
|
||||||
|
PIRP Irp;
|
||||||
|
BOOLEAN LocalEvent = FALSE;
|
||||||
|
KEVENT Event;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("IopSecurityFile() called\n");
|
DPRINT("IopSecurityFile() called\n");
|
||||||
|
|
||||||
FileObject = (PFILE_OBJECT)ObjectBody;
|
FileObject = (PFILE_OBJECT)ObjectBody;
|
||||||
|
|
||||||
switch (OperationCode)
|
if (OperationCode == QuerySecurityDescriptor)
|
||||||
{
|
{
|
||||||
case SetSecurityDescriptor:
|
MajorFunction = IRP_MJ_QUERY_SECURITY;
|
||||||
DPRINT("Set security descriptor\n");
|
DPRINT("Query security descriptor\n");
|
||||||
KeResetEvent(&FileObject->Event);
|
}
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_SECURITY,
|
else if (OperationCode == DeleteSecurityDescriptor)
|
||||||
FileObject->DeviceObject,
|
{
|
||||||
NULL,
|
DPRINT("Delete\n");
|
||||||
0,
|
return STATUS_SUCCESS;
|
||||||
NULL,
|
}
|
||||||
&FileObject->Event,
|
else if (OperationCode == AssignSecurityDescriptor)
|
||||||
&IoStatusBlock);
|
{
|
||||||
|
/* If this is a direct open, we can assign it */
|
||||||
|
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
|
||||||
|
{
|
||||||
|
/* Get the Device Object */
|
||||||
|
DPRINT1("here\n");
|
||||||
|
DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
|
||||||
|
|
||||||
|
/* Assign the Security Descriptor */
|
||||||
|
DeviceObject->SecurityDescriptor = SecurityDescriptor;
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MajorFunction = IRP_MJ_SET_SECURITY;
|
||||||
|
DPRINT("Set security descriptor\n");
|
||||||
|
|
||||||
|
/* If this is a direct open, we can set it */
|
||||||
|
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
|
||||||
|
{
|
||||||
|
DPRINT1("Set SD unimplemented for Devices\n");
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Device Object */
|
||||||
|
DPRINT1("FileObject: %p\n", FileObject);
|
||||||
|
DeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* Check if we should use Sync IO or not */
|
||||||
|
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
|
||||||
|
{
|
||||||
|
/* Use File Object event */
|
||||||
|
KeClearEvent(&FileObject->Event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use local event */
|
||||||
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
LocalEvent = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate the IRP */
|
||||||
|
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
||||||
|
|
||||||
|
/* Set the IRP */
|
||||||
|
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||||
|
Irp->RequestorMode = ExGetPreviousMode();
|
||||||
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
|
Irp->UserEvent = (LocalEvent) ? &Event : NULL;
|
||||||
|
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
|
||||||
|
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
||||||
|
|
||||||
|
/* Set Stack Parameters */
|
||||||
|
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||||
|
StackPtr->FileObject = FileObject;
|
||||||
|
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
/* Set Parameters */
|
||||||
StackPtr->FileObject = FileObject;
|
if (OperationCode == QuerySecurityDescriptor)
|
||||||
|
{
|
||||||
StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
|
StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
|
||||||
StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
|
StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
|
||||||
|
Irp->UserBuffer = SecurityDescriptor;
|
||||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
}
|
||||||
if (Status == STATUS_PENDING)
|
else
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&FileObject->Event,
|
StackPtr->Parameters.SetSecurity.SecurityInformation = SecurityInformation;
|
||||||
Executive,
|
StackPtr->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
|
||||||
KernelMode,
|
}
|
||||||
FALSE,
|
|
||||||
NULL);
|
/* Call the Driver */
|
||||||
Status = IoStatusBlock.Status;
|
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||||
}
|
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
if (Status == STATUS_INVALID_DEVICE_REQUEST)
|
{
|
||||||
{
|
if (LocalEvent)
|
||||||
Status = STATUS_SUCCESS;
|
{
|
||||||
}
|
KeWaitForSingleObject(&Event,
|
||||||
return Status;
|
Executive,
|
||||||
|
KernelMode,
|
||||||
case QuerySecurityDescriptor:
|
FileObject->Flags & FO_ALERTABLE_IO,
|
||||||
DPRINT("Query security descriptor\n");
|
NULL);
|
||||||
KeResetEvent(&FileObject->Event);
|
Status = IoStatusBlock.Status;
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_SECURITY,
|
}
|
||||||
FileObject->DeviceObject,
|
else
|
||||||
NULL,
|
{
|
||||||
0,
|
KeWaitForSingleObject(&FileObject->Event,
|
||||||
NULL,
|
Executive,
|
||||||
&FileObject->Event,
|
KernelMode,
|
||||||
&IoStatusBlock);
|
FileObject->Flags & FO_ALERTABLE_IO,
|
||||||
|
NULL);
|
||||||
Irp->UserBuffer = SecurityDescriptor;
|
Status = FileObject->FinalStatus;
|
||||||
|
}
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
}
|
||||||
StackPtr->FileObject = FileObject;
|
|
||||||
|
/* This Driver doesn't implement Security, so try to give it a default */
|
||||||
StackPtr->Parameters.QuerySecurity.SecurityInformation = SecurityInformation;
|
if (Status == STATUS_INVALID_DEVICE_REQUEST)
|
||||||
StackPtr->Parameters.QuerySecurity.Length = *BufferLength;
|
{
|
||||||
|
if (OperationCode == QuerySecurityDescriptor)
|
||||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
{
|
||||||
if (Status == STATUS_PENDING)
|
/* Set a World Security Descriptor */
|
||||||
{
|
Status = SeSetWorldSecurityDescriptor(SecurityInformation,
|
||||||
KeWaitForSingleObject(&FileObject->Event,
|
SecurityDescriptor,
|
||||||
Executive,
|
BufferLength);
|
||||||
KernelMode,
|
}
|
||||||
FALSE,
|
else
|
||||||
NULL);
|
{
|
||||||
Status = IoStatusBlock.Status;
|
/* It wasn't a query, so just fake success */
|
||||||
}
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
if (Status == STATUS_INVALID_DEVICE_REQUEST)
|
}
|
||||||
{
|
else if (OperationCode == QuerySecurityDescriptor)
|
||||||
Status = IopSetDefaultSecurityDescriptor(SecurityInformation,
|
{
|
||||||
SecurityDescriptor,
|
/* Return length */
|
||||||
BufferLength);
|
*BufferLength = IoStatusBlock.Information;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME: Is this correct?? */
|
|
||||||
*BufferLength = IoStatusBlock.Information;
|
|
||||||
}
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
case DeleteSecurityDescriptor:
|
|
||||||
DPRINT("Delete security descriptor\n");
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
case AssignSecurityDescriptor:
|
|
||||||
DPRINT("Assign security descriptor\n");
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
/* Return Status */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -2664,8 +2646,8 @@ NtSetInformationFile(HANDLE FileHandle,
|
||||||
ASSERT(IoStatusBlock != NULL);
|
ASSERT(IoStatusBlock != NULL);
|
||||||
ASSERT(FileInformation != NULL);
|
ASSERT(FileInformation != NULL);
|
||||||
|
|
||||||
DPRINT1("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
|
DPRINT("NtSetInformationFile(Handle %x StatBlk %x FileInfo %x Length %d "
|
||||||
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
|
"Class %d)\n", FileHandle, IoStatusBlock, FileInformation,
|
||||||
Length, FileInformationClass);
|
Length, FileInformationClass);
|
||||||
|
|
||||||
/* Get the file object from the file handle */
|
/* Get the file object from the file handle */
|
||||||
|
|
|
@ -108,6 +108,76 @@ SepInitSDs(VOID)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
PULONG BufferLength)
|
||||||
|
{
|
||||||
|
ULONG_PTR Current;
|
||||||
|
ULONG SidSize;
|
||||||
|
ULONG SdSize;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("SeSetWorldSecurityDescriptor() called\n");
|
||||||
|
|
||||||
|
if (SecurityInformation == 0)
|
||||||
|
{
|
||||||
|
return STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
SidSize = RtlLengthSid(SeWorldSid);
|
||||||
|
SdSize = sizeof(SECURITY_DESCRIPTOR) + (2 * SidSize);
|
||||||
|
|
||||||
|
if (*BufferLength < SdSize)
|
||||||
|
{
|
||||||
|
*BufferLength = SdSize;
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*BufferLength = SdSize;
|
||||||
|
|
||||||
|
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
|
||||||
|
SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityDescriptor->Control |= SE_SELF_RELATIVE;
|
||||||
|
Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR);
|
||||||
|
|
||||||
|
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
||||||
|
{
|
||||||
|
RtlCopyMemory((PVOID)Current,
|
||||||
|
SeWorldSid,
|
||||||
|
SidSize);
|
||||||
|
SecurityDescriptor->Owner = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
||||||
|
Current += SidSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
||||||
|
{
|
||||||
|
RtlCopyMemory((PVOID)Current,
|
||||||
|
SeWorldSid,
|
||||||
|
SidSize);
|
||||||
|
SecurityDescriptor->Group = (PSID)((ULONG_PTR)Current - (ULONG_PTR)SecurityDescriptor);
|
||||||
|
Current += SidSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
||||||
|
{
|
||||||
|
SecurityDescriptor->Control |= SE_DACL_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
||||||
|
{
|
||||||
|
SecurityDescriptor->Control |= SE_SACL_PRESENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
|
|
Loading…
Reference in a new issue