sys: IRP_MJ_SET_SECURITY

This commit is contained in:
Bill Zissimopoulos 2016-02-18 17:21:39 -08:00
parent d4f1c13542
commit 12bbddfb19
4 changed files with 89 additions and 3 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}