mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
sys: IRP_MJ_SET_SECURITY
This commit is contained in:
parent
d4f1c13542
commit
12bbddfb19
@ -239,6 +239,7 @@ typedef struct
|
||||
{
|
||||
UINT64 UserContext;
|
||||
UINT64 UserContext2;
|
||||
UINT32 SecurityInformation;
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
|
||||
} SetSecurity;
|
||||
} Req;
|
||||
@ -298,6 +299,10 @@ typedef struct
|
||||
{
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor;
|
||||
} QuerySecurity;
|
||||
struct
|
||||
{
|
||||
FSP_FSCTL_TRANSACT_BUF SecurityDescriptor; /* Size==0 means no security descriptor returned */
|
||||
} SetSecurity;
|
||||
} Rsp;
|
||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||
} FSP_FSCTL_TRANSACT_RSP;
|
||||
|
@ -177,8 +177,11 @@ static NTSTATUS FspFsvolCreateNoLock(
|
||||
/* check security descriptor validity */
|
||||
if (0 != SecurityDescriptor)
|
||||
{
|
||||
#if 0
|
||||
/* captured security descriptor is always valid */
|
||||
if (!RtlValidSecurityDescriptor(SecurityDescriptor))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
#endif
|
||||
SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);
|
||||
}
|
||||
|
||||
|
@ -497,7 +497,8 @@ VOID FspFileNodeSetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size)
|
||||
FspFsvolDeviceExtension(FileNode->FsvolDeviceObject);
|
||||
|
||||
FspMetaCacheInvalidateItem(FsvolDeviceExtension->SecurityCache, FileNode->Security);
|
||||
FileNode->Security = FspMetaCacheAddItem(FsvolDeviceExtension->SecurityCache, Buffer, Size);
|
||||
FileNode->Security = 0 != Buffer ?
|
||||
FspMetaCacheAddItem(FsvolDeviceExtension->SecurityCache, Buffer, Size) : 0;
|
||||
}
|
||||
|
||||
BOOLEAN FspFileNodeTrySetSecurity(FSP_FILE_NODE *FileNode, PCVOID Buffer, ULONG Size,
|
||||
|
@ -114,7 +114,7 @@ NTSTATUS FspFsvolQuerySecurityComplete(
|
||||
{
|
||||
/* check that the security descriptor we got back is valid */
|
||||
if (Response->Buffer + Response->Rsp.QuerySecurity.SecurityDescriptor.Size >
|
||||
(PUINT8)Response + Response->Size ||
|
||||
(PUINT8)Response + Response->Size ||
|
||||
!RtlValidRelativeSecurityDescriptor((PVOID)Response->Buffer,
|
||||
Response->Rsp.QuerySecurity.SecurityDescriptor.Size, 0))
|
||||
{
|
||||
@ -163,7 +163,51 @@ static NTSTATUS FspFsvolSetSecurity(
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
/* is this a valid FileObject? */
|
||||
if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext))
|
||||
return STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
NTSTATUS Result;
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
FSP_FILE_DESC *FileDesc = FileObject->FsContext2;
|
||||
SECURITY_INFORMATION SecurityInformation = IrpSp->Parameters.SetSecurity.SecurityInformation;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor = IrpSp->Parameters.SetSecurity.SecurityDescriptor;
|
||||
ULONG SecurityDescriptorSize = 0;
|
||||
|
||||
ASSERT(FileNode == FileDesc->FileNode);
|
||||
|
||||
#if 0
|
||||
/* captured security descriptor is always valid */
|
||||
if (0 == SecurityDescriptor || !RtlValidSecurityDescriptor(SecurityDescriptor))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
#endif
|
||||
SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor);
|
||||
|
||||
FspFileNodeAcquireExclusive(FileNode, Full);
|
||||
|
||||
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||
|
||||
Result = FspIopCreateRequestEx(Irp, 0, SecurityDescriptorSize, FspFsvolSecurityRequestFini,
|
||||
&Request);
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileNodeRelease(FileNode, Full);
|
||||
return Result;
|
||||
}
|
||||
|
||||
Request->Kind = FspFsctlTransactSetSecurityKind;
|
||||
Request->Req.SetSecurity.UserContext = FileNode->UserContext;
|
||||
Request->Req.SetSecurity.UserContext2 = FileDesc->UserContext2;
|
||||
Request->Req.SetSecurity.SecurityInformation = SecurityInformation;
|
||||
Request->Req.SetSecurity.SecurityDescriptor.Offset = 0;
|
||||
Request->Req.SetSecurity.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize;
|
||||
RtlCopyMemory(Request->Buffer, SecurityDescriptor, SecurityDescriptorSize);
|
||||
|
||||
FspFileNodeSetOwner(FileNode, Full, Request);
|
||||
FspIopRequestContext(Request, RequestFileNode) = FileNode;
|
||||
|
||||
return FSP_STATUS_IOQ_POST;
|
||||
}
|
||||
|
||||
NTSTATUS FspFsvolSetSecurityComplete(
|
||||
@ -171,6 +215,39 @@ NTSTATUS FspFsvolSetSecurityComplete(
|
||||
{
|
||||
FSP_ENTER_IOC(PAGED_CODE());
|
||||
|
||||
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Result = Response->IoStatus.Status;
|
||||
FSP_RETURN();
|
||||
}
|
||||
|
||||
PFILE_OBJECT FileObject = IrpSp->FileObject;
|
||||
FSP_FILE_NODE *FileNode = FileObject->FsContext;
|
||||
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||
|
||||
/* if the security descriptor that we got back is valid */
|
||||
if (0 < Response->Rsp.SetSecurity.SecurityDescriptor.Size &&
|
||||
Response->Buffer + Response->Rsp.SetSecurity.SecurityDescriptor.Size <=
|
||||
(PUINT8)Response + Response->Size &&
|
||||
RtlValidRelativeSecurityDescriptor((PVOID)Response->Buffer,
|
||||
Response->Rsp.SetSecurity.SecurityDescriptor.Size, 0))
|
||||
{
|
||||
/* update the cached security */
|
||||
FspFileNodeSetSecurity(FileNode,
|
||||
Response->Buffer, Response->Rsp.SetSecurity.SecurityDescriptor.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* invalidate the cached security */
|
||||
FspFileNodeSetSecurity(FileNode, 0, 0);
|
||||
}
|
||||
|
||||
FspIopRequestContext(Request, RequestFileNode) = 0;
|
||||
FspFileNodeReleaseOwner(FileNode, Full, Request);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
FSP_LEAVE_IOC("FileObject=%p, SecurityInformation=%x",
|
||||
IrpSp->FileObject, IrpSp->Parameters.SetSecurity.SecurityInformation);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user